From 77d9da4571579004511b4328a34cdf575daf2139 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 30 May 2015 23:31:34 +0200
Subject: [PATCH] shell32: Do not use unixfs for devices without mountpoint.

---
 dlls/shell32/shfldr_desktop.c  | 17 ++++++++++++++++-
 dlls/shell32/tests/shlfolder.c | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/dlls/shell32/shfldr_desktop.c b/dlls/shell32/shfldr_desktop.c
index 880291c..fba7dd6 100644
--- a/dlls/shell32/shfldr_desktop.c
+++ b/dlls/shell32/shfldr_desktop.c
@@ -186,11 +186,26 @@ static HRESULT WINAPI ISF_Desktop_fnParseDisplayName (IShellFolder2 * iface,
     }
     else if (PathGetDriveNumberW (lpszDisplayName) >= 0)
     {
+        /*
+         * UNIXFS can't handle drives without a mount point yet. We fall back
+         * to use the MyComputer interface if we can't get the file attributes
+         * on the device.
+         */
+        char drivePath[] = "A:\\";
+        drivePath[0] = 'A' + PathGetDriveNumberW(lpszDisplayName);
+
         /* it's a filesystem path with a drive. Let MyComputer/UnixDosFolder parse it */
-        if (UNIXFS_is_rooted_at_desktop()) 
+        if (UNIXFS_is_rooted_at_desktop() &&
+            GetFileAttributesA(drivePath) != INVALID_FILE_ATTRIBUTES)
+        {
             pidlTemp = _ILCreateGuid(PT_GUID, &CLSID_UnixDosFolder);
+            TRACE("Using unixfs for %s\n", debugstr_w(lpszDisplayName));
+        }
         else
+        {
             pidlTemp = _ILCreateMyComputer ();
+            TRACE("Using MyComputer for %s\n", debugstr_w(lpszDisplayName));
+        }
         szNext = lpszDisplayName;
     }
     else if (PathIsUNCW(lpszDisplayName))
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index bd4bba2..5eb47e4 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -4215,12 +4215,34 @@ static void test_ShellItemArrayGetAttributes(void)
     Cleanup();
 }
 
+static WCHAR *get_empty_cddrive(void)
+{
+    static WCHAR cdrom_drive[] = {'A',':','\\',0};
+    DWORD drives = GetLogicalDrives();
+
+    cdrom_drive[0] = 'A';
+    while (drives)
+    {
+        if ((drives & 1) &&
+            GetDriveTypeW(cdrom_drive) == DRIVE_CDROM &&
+            GetFileAttributesW(cdrom_drive) == INVALID_FILE_ATTRIBUTES)
+        {
+            return cdrom_drive;
+        }
+
+        drives = drives >> 1;
+        cdrom_drive[0]++;
+    }
+    return NULL;
+}
+
 static void test_SHParseDisplayName(void)
 {
     LPITEMIDLIST pidl1, pidl2;
     IShellFolder *desktop;
     WCHAR dirW[MAX_PATH];
     WCHAR nameW[10];
+    WCHAR *cdrom;
     HRESULT hr;
     BOOL ret, is_wow64;
 
@@ -4286,6 +4308,16 @@ if (0)
     }
 
     IShellFolder_Release(desktop);
+
+    cdrom = get_empty_cddrive();
+    if (!cdrom)
+        skip("No empty cdrom drive found, skipping test\n");
+    else
+    {
+        hr = SHParseDisplayName(cdrom, NULL, &pidl1, 0, NULL);
+        ok(hr == S_OK, "failed %08x\n", hr);
+        if (SUCCEEDED(hr)) ILFree(pidl1);
+    }
 }
 
 static void test_desktop_IPersist(void)
-- 
1.9.1

