[glib: 2/3] GWin32Mount: Don't use SHGetFileInfoW() for mount displaynames
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 2/3] GWin32Mount: Don't use SHGetFileInfoW() for mount displaynames
- Date: Wed, 31 Mar 2021 13:49:36 +0000 (UTC)
commit cb994350c427b8c5e514ecb26fd036d889cfd839
Author: Руслан Ижбулатов <lrn1986 gmail com>
Date: Tue Mar 30 20:27:25 2021 +0000
GWin32Mount: Don't use SHGetFileInfoW() for mount displaynames
This function can create long delays when used on disconnected
or just weird volumes. Use IShellFolder::GetDisplayNameOf() instead.
Fixes #2096
gio/gwin32mount.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 42 insertions(+), 4 deletions(-)
---
diff --git a/gio/gwin32mount.c b/gio/gwin32mount.c
index 6388beb11..f5be8adfa 100644
--- a/gio/gwin32mount.c
+++ b/gio/gwin32mount.c
@@ -143,14 +143,52 @@ g_win32_mount_init (GWin32Mount *win32_mount)
{
}
+/* wdrive doesn't need to end with a path separator.
+ wdrive must use backslashes as path separators, not slashes.
+ IShellFolder::ParseDisplayName() takes non-const string as input,
+ so wdrive can't be a const string.
+ Returns the name on success (free with g_free),
+ NULL otherwise.
+ */
+static gchar *
+get_mount_display_name (gunichar2 *wdrive)
+{
+ IShellFolder *desktop;
+ PIDLIST_RELATIVE volume;
+ STRRET volume_name;
+ gchar *result = NULL;
+
+ /* Get the desktop folder object reference */
+ if (!SUCCEEDED (SHGetDesktopFolder (&desktop)))
+ return result;
+
+ if (SUCCEEDED (IShellFolder_ParseDisplayName (desktop, NULL, NULL, wdrive, NULL, &volume, NULL)))
+ {
+ volume_name.uType = STRRET_WSTR;
+
+ if (SUCCEEDED (IShellFolder_GetDisplayNameOf (desktop, volume, SHGDN_FORADDRESSBAR, &volume_name)))
+ {
+ wchar_t *volume_name_wchar;
+
+ if (SUCCEEDED (StrRetToStrW (&volume_name, volume, &volume_name_wchar)))
+ {
+ result = g_utf16_to_utf8 (volume_name_wchar, -1, NULL, NULL, NULL);
+ CoTaskMemFree (volume_name_wchar);
+ }
+ }
+ CoTaskMemFree (volume);
+ }
+
+ IShellFolder_Release (desktop);
+
+ return result;
+}
+
static gchar *
_win32_get_displayname (const char *drive)
{
gunichar2 *wdrive = g_utf8_to_utf16 (drive, -1, NULL, NULL, NULL);
- gchar *name = NULL;
- SHFILEINFOW sfi;
- if (SHGetFileInfoW(wdrive, 0, &sfi, sizeof(sfi), SHGFI_DISPLAYNAME))
- name = g_utf16_to_utf8 (sfi.szDisplayName, -1, NULL, NULL, NULL);
+ gchar *name = get_mount_display_name (wdrive);
g_free (wdrive);
return name ? name : g_strdup (drive);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]