[PATCH 2/4] shell32/shfldr_mycomp: Handle drive letters properly when parsing

Gabriel Ivăncescu gabrielopcode at gmail.com
Wed Aug 21 06:32:40 CDT 2019


Besides PathGetDriveNumber being dangerous and having a completely messed
up result with \\?\ prefix, a backslash is not required anymore on newer
Windows versions. So e.g. C: should succeed to be parsed.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---

Testcase at end of series.

 dlls/shell32/shfldr_mycomp.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/dlls/shell32/shfldr_mycomp.c b/dlls/shell32/shfldr_mycomp.c
index 1b987a7..97d259a 100644
--- a/dlls/shell32/shfldr_mycomp.c
+++ b/dlls/shell32/shfldr_mycomp.c
@@ -193,7 +193,7 @@ static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface,
     IMyComputerFolderImpl *This = impl_from_IShellFolder2(iface);
     HRESULT hr = E_INVALIDARG;
     LPCWSTR szNext = NULL;
-    WCHAR szElement[MAX_PATH];
+    WCHAR c, szElement[MAX_PATH];
     LPITEMIDLIST pidlTemp = NULL;
     CLSID clsid;
 
@@ -213,13 +213,18 @@ static HRESULT WINAPI ISF_MyComputer_fnParseDisplayName (IShellFolder2 *iface,
         SHCLSIDFromStringW (szElement + 2, &clsid);
         pidlTemp = _ILCreateGuid (PT_GUID, &clsid);
     }
-    /* do we have an absolute path name ? */
-    else if (PathGetDriveNumberW (lpszDisplayName) >= 0 &&
-              lpszDisplayName[2] == (WCHAR) '\\')
+    /* do we have an absolute path name?  note that we can't use
+       PathGetDriveNumberW because we can't have the \\?\ prefix */
+    else if ((c = toupperW(lpszDisplayName[0])) >= 'A' && c <= 'Z' &&
+             lpszDisplayName[1] == ':' &&
+             (lpszDisplayName[2] == '\\' || lpszDisplayName[2] == '\0'))
     {
-        szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
-        /* make drive letter uppercase to enable PIDL comparison */
-        szElement[0] = toupper(szElement[0]);
+        /* drive letter has to be uppercase to enable PIDL comparison */
+        szElement[0] = c;
+        szElement[1] = ':';
+        szElement[2] = '\\';  /* make sure it has a backslash here */
+        szElement[3] = '\0';
+        szNext = &lpszDisplayName[2] + (lpszDisplayName[2] == '\\');
         pidlTemp = _ILCreateDrive (szElement);
     }
 
-- 
2.21.0




More information about the wine-devel mailing list