[SHELL32] Partially synchronize wine/shellpath.c with Wine.
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 22 Sep 2018 20:19:14 +0000 (22:19 +0200)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 22 Sep 2018 22:16:02 +0000 (00:16 +0200)
- Adjust the code with respect to:
  "shell32: Re-add support for expanding ALLUSERSPROFILE for backward compatibility."
  4a6855a575c02aa1569aab8b2e96720fc02f3f26 (Alexandre Julliard)

- "shell32: Avoid infinite loop in _SHExpandEnvironmentStrings."
  ceea5bda14ecf4c8ce262fc7ab88df49e500bc38 (Alexandre Julliard)

- "shell32: Assume that system directory always contains a drive letter."
  54530bc4933ae1014c3697c95e22b8ca5a275bc4 (Alexandre Julliard)

- "shell32: Use ARRAY_SIZE macro."
  612a1941331485725952d34f3dcd5866fc318dc2 (Nikolay Sivov)

- "shell32: Fix a trace message."
  bb09bb5750d617047aa23635731519a2f9486159 (Nikolay Sivov)

- "shell32: Fix SHGetFolderPathAndSubDir() trace message."
  f75d5625966933562b974540a3f29dfcd720ad50 (Nikolay Sivov)

- "shell32: Pass correct buffer length to RegQueryValueExW()."
  0bfb97dcba29552b51d8609fcc6e7bbc04bb8320 (Nikolay Sivov)

- "shell32: Remove unused string (Clang)."
  8d50a8a246960749afba21eac117b4fcbbf2c79d (André Hentschel)

- "shell32: Use E_NOT_SUFFICIENT_BUFFER definition."
  730e744e3bd6b706612fe0f90a7efb2e600f114f (Nikolay Sivov)

dll/win32/shell32/wine/shell32_main.h
dll/win32/shell32/wine/shellpath.c

index 170d844..1653697 100644 (file)
@@ -26,6 +26,8 @@
 extern "C" {
 #endif
 
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+
 /*******************************************
 *  global SHELL32.DLL variables
 */
index d1a3ada..6396641 100644 (file)
@@ -578,7 +578,6 @@ static const WCHAR MusicW[] = {'M','u','s','i','c','\0'};
 static const WCHAR Music_PlaylistsW[] = {'M','u','s','i','c','\\','P','l','a','y','l','i','s','t','s','\0'};
 static const WCHAR Music_Sample_MusicW[] = {'M','u','s','i','c','\\','S','a','m','p','l','e',' ','M','u','s','i','c','\0'};
 static const WCHAR Music_Sample_PlaylistsW[] = {'M','u','s','i','c','\\','S','a','m','p','l','e',' ','P','l','a','y','l','i','s','t','s','\0'};
-static const WCHAR My_DocumentsW[] = {'M','y',' ','D','o','c','u','m','e','n','t','s','\0'};
 #endif
 static const WCHAR My_MusicW[] = {'M','y',' ','M','u','s','i','c','\0'};
 static const WCHAR My_PicturesW[] = {'M','y',' ','P','i','c','t','u','r','e','s','\0'};
@@ -601,6 +600,9 @@ static const WCHAR Program_Files_x86_Common_FilesW[] = {'P','r','o','g','r','a',
 static const WCHAR ProgramFilesDirW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r','\0'};
 static const WCHAR ProgramFilesDirX86W[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',' ','(','x','8','6',')','\0'};
 static const WCHAR ProgramsW[] = {'P','r','o','g','r','a','m','s','\0'};
+#ifndef __REACTOS__
+static const WCHAR PublicW[] = {'P','u','b','l','i','c',0};
+#endif
 static const WCHAR RecentW[] = {'R','e','c','e','n','t','\0'};
 static const WCHAR ResourcesW[] = {'R','e','s','o','u','r','c','e','s','\0'};
 #ifndef __REACTOS__
@@ -624,6 +626,9 @@ static const WCHAR Videos_Sample_VideosW[] = {'V','i','d','e','o','s','\\','S','
 #endif
 static const WCHAR DefaultW[] = {'.','D','e','f','a','u','l','t','\0'};
 static const WCHAR AllUsersProfileW[] = {'%','A','L','L','U','S','E','R','S','P','R','O','F','I','L','E','%','\0'};
+#ifndef __REACTOS__
+static const WCHAR PublicProfileW[] = {'%','P','U','B','L','I','C','%',0};
+#endif
 static const WCHAR UserProfileW[] = {'%','U','S','E','R','P','R','O','F','I','L','E','%','\0'};
 static const WCHAR SystemDriveW[] = {'%','S','y','s','t','e','m','D','r','i','v','e','%','\0'};
 #ifndef __REACTOS__
@@ -1425,8 +1430,8 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, HANDLE hToken, LPCWSTR us
     HRESULT hr;
     WCHAR shellFolderPath[MAX_PATH], userShellFolderPath[MAX_PATH];
     LPCWSTR pShellFolderPath, pUserShellFolderPath;
-    DWORD dwType, dwPathLen = MAX_PATH;
     HKEY userShellFolderKey, shellFolderKey;
+    DWORD dwType, dwPathLen;
 
     TRACE("%p,%s,%s,%p\n",rootKey, debugstr_w(userPrefix), debugstr_w(value),
      path);
@@ -1461,6 +1466,7 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, HANDLE hToken, LPCWSTR us
         return E_FAIL;
     }
 
+    dwPathLen = MAX_PATH * sizeof(WCHAR);
     if (!RegQueryValueExW(userShellFolderKey, value, NULL, &dwType,
      (LPBYTE)path, &dwPathLen) && (dwType == REG_EXPAND_SZ || dwType == REG_SZ))
     {
@@ -1539,8 +1545,9 @@ static HRESULT _SHGetDefaultValue(HANDLE hToken, BYTE folder, LPWSTR pszPath)
 
     TRACE("0x%02x,%p\n", folder, pszPath);
 
-    if (folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0]))
+    if (folder >= ARRAY_SIZE(CSIDL_Data))
         return E_INVALIDARG;
+
     if (!pszPath)
         return E_INVALIDARG;
 
@@ -1576,7 +1583,11 @@ static HRESULT _SHGetDefaultValue(HANDLE hToken, BYTE folder, LPWSTR pszPath)
             strcpyW(pszPath, UserProfileW);
             break;
         case CSIDL_Type_AllUsers:
+#ifndef __REACTOS__
+            strcpyW(pszPath, PublicProfileW);
+#else
             strcpyW(pszPath, AllUsersProfileW);
+#endif
             break;
         case CSIDL_Type_CurrVer:
             strcpyW(pszPath, SystemDriveW);
@@ -1624,7 +1635,7 @@ static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder,
 
     TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
 
-    if (folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0]))
+    if (folder >= ARRAY_SIZE(CSIDL_Data))
         return E_INVALIDARG;
     if (CSIDL_Data[folder].type != CSIDL_Type_CurrVer)
         return E_INVALIDARG;
@@ -1736,7 +1747,7 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder,
 
     TRACE("%p,0x%08x,0x%02x,%p\n", hToken, dwFlags, folder, pszPath);
 
-    if (folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0]))
+    if (folder >= ARRAY_SIZE(CSIDL_Data))
         return E_INVALIDARG;
     if (CSIDL_Data[folder].type != CSIDL_Type_User)
         return E_INVALIDARG;
@@ -1815,7 +1826,7 @@ static HRESULT _SHGetAllUsersProfilePath(DWORD dwFlags, BYTE folder,
 
     TRACE("0x%08x,0x%02x,%p\n", dwFlags, folder, pszPath);
 
-    if (folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0]))
+    if (folder >= ARRAY_SIZE(CSIDL_Data))
         return E_INVALIDARG;
     if (CSIDL_Data[folder].type != CSIDL_Type_AllUsers)
         return E_INVALIDARG;
@@ -1946,8 +1957,7 @@ static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR
 
         /* get the system drive */
         GetSystemDirectoryW(def_val, MAX_PATH);
-        if (def_val[1] == ':') strcpyW( def_val + 3, szDefaultProfileDirW );
-        else FIXME("non-drive system paths unsupported\n");
+        strcpyW( def_val + 3, szDefaultProfileDirW );
 
         hr = _SHGetProfilesValue(key, ProfilesDirectoryW, szProfilesPrefix, def_val );
     }
@@ -1966,7 +1976,7 @@ static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR
 
             strcpyW(szDest, szProfilesPrefix);
             hr = _SHGetProfilesValue(key, AllUsersProfileValueW,
-             szAllUsers, AllUsersW);
+                                     szAllUsers, AllUsersW);
             PathAppendW(szDest, szAllUsers);
 #else
             DWORD cchSize = cchDest;
@@ -1975,6 +1985,19 @@ static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR
 #endif
             PathAppendW(szDest, szTemp + strlenW(AllUsersProfileW));
         }
+#ifndef __REACTOS__
+        else if (!strncmpiW(szTemp, PublicProfileW, strlenW(PublicProfileW)))
+        {
+            WCHAR szAllUsers[MAX_PATH], def_val[MAX_PATH];
+
+            GetSystemDirectoryW(def_val, MAX_PATH);
+            strcpyW( def_val + 3, UsersPublicW );
+
+            hr = _SHGetProfilesValue(key, PublicW, szAllUsers, def_val);
+            PathAppendW(szDest, szAllUsers);
+            PathAppendW(szDest, szTemp + strlenW(PublicProfileW));
+        }
+#endif
         else if (!strncmpiW(szTemp, UserProfileW, strlenW(UserProfileW)))
         {
 #ifndef __REACTOS__
@@ -1999,21 +2022,12 @@ static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR
             if (!GetSystemDirectoryW(szDest, cchDest))
                 return HRESULT_FROM_WIN32(GetLastError());
 #endif
-            if (szDest[1] != ':')
-            {
-                FIXME("non-drive system paths unsupported\n");
-                hr = E_FAIL;
-            }
-            else
-            {
-                strcpyW(szDest + 3, szTemp + strlenW(SystemDriveW) + 1);
-                hr = S_OK;
-            }
+            strcpyW(szDest + 3, szTemp + strlenW(SystemDriveW) + 1);
         }
         else
         {
 #ifndef __REACTOS__
-            DWORD ret = ExpandEnvironmentStringsW(szSrc, szDest, MAX_PATH);
+            DWORD ret = ExpandEnvironmentStringsW(szTemp, szDest, MAX_PATH);
 #else
             DWORD ret = SHExpandEnvironmentStringsForUserW(hToken, szSrc, szDest, cchDest);
 #endif
@@ -2023,19 +2037,12 @@ static HRESULT _SHExpandEnvironmentStrings(HANDLE hToken, LPCWSTR szSrc, LPWSTR
 #else
             if (ret > cchDest)
 #endif
-                hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+                hr = E_NOT_SUFFICIENT_BUFFER;
             else if (ret == 0)
                 hr = HRESULT_FROM_WIN32(GetLastError());
-            else
-                hr = S_OK;
-        }
-        if (SUCCEEDED(hr) && szDest[0] == '%')
-            strcpyW(szTemp, szDest);
-        else
-        {
-            /* terminate loop */
-            szTemp[0] = '\0';
+            else if (!strcmpW( szTemp, szDest )) break;  /* nothing expanded */
         }
+        if (SUCCEEDED(hr)) strcpyW(szTemp, szDest);
     }
 end:
 #ifndef __REACTOS__
@@ -2092,7 +2099,8 @@ HRESULT WINAPI SHGetFolderPathAndSubDirA(
     HRESULT hr = S_OK;
     LPWSTR pszSubPathW = NULL;
     LPWSTR pszPathW = NULL;
-    TRACE("%08x,%08x,%s\n",nFolder, dwFlags, debugstr_w(pszSubPathW));
+
+    TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_a(pszSubPath), pszPath);
 
     if(pszPath) {
         pszPathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
@@ -2145,7 +2153,7 @@ HRESULT WINAPI SHGetFolderPathAndSubDirW(
     CSIDL_Type type;
     int        ret;
     
-    TRACE("%p,%p,nFolder=0x%04x,%s\n", hwndOwner,pszPath,nFolder,debugstr_w(pszSubPath));
+    TRACE("%p,%#x,%p,%#x,%s,%p\n", hwndOwner, nFolder, hToken, dwFlags, debugstr_w(pszSubPath), pszPath);
 
     /* Windows always NULL-terminates the resulting path regardless of success
      * or failure, so do so first
@@ -2153,7 +2161,7 @@ HRESULT WINAPI SHGetFolderPathAndSubDirW(
     if (pszPath)
         *pszPath = '\0';
 
-    if (folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0]))
+    if (folder >= ARRAY_SIZE(CSIDL_Data))
         return E_INVALIDARG;
     if ((SHGFP_TYPE_CURRENT != dwFlags) && (SHGFP_TYPE_DEFAULT != dwFlags))
         return E_INVALIDARG;
@@ -2317,7 +2325,7 @@ HRESULT WINAPI SHGetFolderPathA(
     WCHAR szTemp[MAX_PATH];
     HRESULT hr;
 
-    TRACE("%p,%p,nFolder=0x%04x\n",hwndOwner,pszPath,nFolder);
+    TRACE("%p,%d,%p,%#x,%p\n", hwndOwner, nFolder, hToken, dwFlags, pszPath);
 
     if (pszPath)
         *pszPath = '\0';
@@ -2486,7 +2494,7 @@ static HRESULT _SHRegisterUserShellFolders(BOOL bDefault)
     }
 
     hr = _SHRegisterFolders(hRootKey, hToken, pUserShellFolderPath,
-     pShellFolderPath, folders, sizeof(folders) / sizeof(folders[0]));
+     pShellFolderPath, folders, ARRAY_SIZE(folders));
     TRACE("returning 0x%08x\n", hr);
     return hr;
 }
@@ -2511,7 +2519,7 @@ static HRESULT _SHRegisterCommonShellFolders(void)
 
     TRACE("\n");
     hr = _SHRegisterFolders(HKEY_LOCAL_MACHINE, NULL, szSHUserFolders,
-     szSHFolders, folders, sizeof(folders) / sizeof(folders[0]));
+     szSHFolders, folders, ARRAY_SIZE(folders));
     TRACE("returning 0x%08x\n", hr);
     return hr;
 }