[SHELL32] shellpath.c: it is _WIN32_WINNT, not WIN32_WINNT. We even need to use __REA...
[reactos.git] / dll / win32 / shell32 / wine / shellpath.c
index 4255e6a..02072e9 100644 (file)
@@ -39,6 +39,8 @@
 #include <wine/debug.h>
 #include <wine/unicode.h>
 
+#include <userenv.h>
+
 #include "pidl.h"
 #include "shell32_main.h"
 #include "shresdef.h"
@@ -47,6 +49,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
 static const BOOL is_win64 = sizeof(void *) > sizeof(int);
 
+typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+
+static LPFN_ISWOW64PROCESS fnIsWow64Process = NULL;
+
+BOOL IsWow64()
+{
+    BOOL bIsWow64 = FALSE;
+
+    if (!fnIsWow64Process)
+    {
+        fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
+            GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
+    }
+
+    if (!fnIsWow64Process)
+        return FALSE;
+
+    if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
+        return FALSE;
+
+    return bIsWow64;
+}
+
+
 /*
        ########## Combining and Constructing paths ##########
 */
@@ -63,16 +89,6 @@ BOOL WINAPI PathAppendAW(
        return PathAppendA(lpszPath1, lpszPath2);
 }
 
-/*************************************************************************
- * PathBuildRoot               [SHELL32.30]
- */
-LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive)
-{
-       if(SHELL_OsIsUnicode())
-         return PathBuildRootW(lpszPath, drive);
-       return PathBuildRootA(lpszPath, drive);
-}
-
 /*************************************************************************
  * PathGetExtensionA           [internal]
  *
@@ -102,7 +118,7 @@ static LPWSTR PathGetExtensionW(LPCWSTR lpszPath)
 /*************************************************************************
  * SHPathGetExtension        [SHELL32.158]
  */
-EXTERN_C LPVOID WINAPI SHPathGetExtensionW(LPCWSTR lpszPath, DWORD void1, DWORD void2)
+LPVOID WINAPI SHPathGetExtensionW(LPCWSTR lpszPath, DWORD void1, DWORD void2)
 {
     return PathGetExtensionW(lpszPath);
 }
@@ -233,16 +249,6 @@ BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath)
        return PathFileExistsA (lpszPath);
 }
 
-/*************************************************************************
- * PathIsSameRoot      [SHELL32.650]
- */
-BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2)
-{
-       if (SHELL_OsIsUnicode())
-         return PathIsSameRootW(lpszPath1, lpszPath2);
-       return PathIsSameRootA(lpszPath1, lpszPath2);
-}
-
 /*************************************************************************
  * IsLFNDriveA         [SHELL32.41]
  */
@@ -639,12 +645,15 @@ typedef enum _CSIDL_Type {
     CSIDL_Type_SystemX86Path,
 } CSIDL_Type;
 
+/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
+#ifndef __REACTOS__
 #define CSIDL_CONTACTS         0x0043
 #define CSIDL_DOWNLOADS        0x0047
 #define CSIDL_LINKS            0x004d
 #define CSIDL_APPDATA_LOCALLOW 0x004e
 #define CSIDL_SAVED_GAMES      0x0062
 #define CSIDL_SEARCHES         0x0063
+#endif
 
 typedef struct
 {
@@ -672,7 +681,7 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_Programs,
         CSIDL_Type_User,
         ProgramsW,
-        Start_Menu_ProgramsW
+        MAKEINTRESOURCEW(IDS_PROGRAMS)
     },
     { /* 0x03 - CSIDL_CONTROLS (.CPL files) */
         &FOLDERID_ControlPanelFolder,
@@ -696,25 +705,25 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_Favorites,
         CSIDL_Type_User,
         FavoritesW,
-        FavoritesW
+        MAKEINTRESOURCEW(IDS_FAVORITES)
     },
     { /* 0x07 - CSIDL_STARTUP */
         &FOLDERID_Startup,
         CSIDL_Type_User,
         StartUpW,
-        Start_Menu_StartupW
+        MAKEINTRESOURCEW(IDS_STARTUP)
     },
     { /* 0x08 - CSIDL_RECENT */
         &FOLDERID_Recent,
         CSIDL_Type_User,
         RecentW,
-        RecentW
+        MAKEINTRESOURCEW(IDS_RECENT)
     },
     { /* 0x09 - CSIDL_SENDTO */
         &FOLDERID_SendTo,
         CSIDL_Type_User,
         SendToW,
-        SendToW
+        MAKEINTRESOURCEW(IDS_SENDTO)
     },
     { /* 0x0a - CSIDL_BITBUCKET - Recycle Bin */
         &FOLDERID_RecycleBinFolder,
@@ -726,7 +735,7 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_StartMenu,
         CSIDL_Type_User,
         Start_MenuW,
-        Start_MenuW
+        MAKEINTRESOURCEW(IDS_STARTMENU)
     },
     { /* 0x0c - CSIDL_MYDOCUMENTS */
         &GUID_NULL,
@@ -774,7 +783,7 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_NetHood,
         CSIDL_Type_User,
         NetHoodW,
-        NetHoodW
+        MAKEINTRESOURCEW(IDS_NETHOOD)
     },
     { /* 0x14 - CSIDL_FONTS */
         &FOLDERID_Fonts,
@@ -786,25 +795,25 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_Templates,
         CSIDL_Type_User,
         TemplatesW,
-        TemplatesW
+        MAKEINTRESOURCEW(IDS_TEMPLATES)
     },
     { /* 0x16 - CSIDL_COMMON_STARTMENU */
         &FOLDERID_CommonStartMenu,
         CSIDL_Type_AllUsers,
         Common_Start_MenuW,
-        Start_MenuW
+        MAKEINTRESOURCEW(IDS_STARTMENU)
     },
     { /* 0x17 - CSIDL_COMMON_PROGRAMS */
         &FOLDERID_CommonPrograms,
         CSIDL_Type_AllUsers,
         Common_ProgramsW,
-        Start_Menu_ProgramsW
+        MAKEINTRESOURCEW(IDS_PROGRAMS)
     },
     { /* 0x18 - CSIDL_COMMON_STARTUP */
         &FOLDERID_CommonStartup,
         CSIDL_Type_AllUsers,
         Common_StartUpW,
-        Start_Menu_StartupW
+        MAKEINTRESOURCEW(IDS_STARTUP)
     },
     { /* 0x19 - CSIDL_COMMON_DESKTOPDIRECTORY */
         &FOLDERID_PublicDesktop,
@@ -816,19 +825,19 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_RoamingAppData,
         CSIDL_Type_User,
         AppDataW,
-        Application_DataW
+        MAKEINTRESOURCEW(IDS_APPDATA)
     },
     { /* 0x1b - CSIDL_PRINTHOOD */
         &FOLDERID_PrintHood,
         CSIDL_Type_User,
         PrintHoodW,
-        PrintHoodW
+        MAKEINTRESOURCEW(IDS_PRINTHOOD)
     },
     { /* 0x1c - CSIDL_LOCAL_APPDATA */
         &FOLDERID_LocalAppData,
         CSIDL_Type_User,
         Local_AppDataW,
-        Local_Settings_Application_DataW
+        MAKEINTRESOURCEW(IDS_LOCAL_APPDATA)
     },
     { /* 0x1d - CSIDL_ALTSTARTUP */
         &GUID_NULL,
@@ -846,31 +855,31 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_Favorites,
         CSIDL_Type_AllUsers,
         Common_FavoritesW,
-        FavoritesW
+        MAKEINTRESOURCEW(IDS_FAVORITES)
     },
     { /* 0x20 - CSIDL_INTERNET_CACHE */
         &FOLDERID_InternetCache,
         CSIDL_Type_User,
         CacheW,
-        Local_Settings_Temporary_Internet_FilesW
+        MAKEINTRESOURCEW(IDS_INTERNET_CACHE)
     },
     { /* 0x21 - CSIDL_COOKIES */
         &FOLDERID_Cookies,
         CSIDL_Type_User,
         CookiesW,
-        CookiesW
+        MAKEINTRESOURCEW(IDS_COOKIES)
     },
     { /* 0x22 - CSIDL_HISTORY */
         &FOLDERID_History,
         CSIDL_Type_User,
         HistoryW,
-        Local_Settings_HistoryW
+        MAKEINTRESOURCEW(IDS_HISTORY)
     },
     { /* 0x23 - CSIDL_COMMON_APPDATA */
         &FOLDERID_ProgramData,
         CSIDL_Type_AllUsers,
         Common_AppDataW,
-        Application_DataW
+        MAKEINTRESOURCEW(IDS_APPDATA)
     },
     { /* 0x24 - CSIDL_WINDOWS */
         &FOLDERID_Windows,
@@ -888,7 +897,7 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_ProgramFiles,
         CSIDL_Type_CurrVer,
         ProgramFilesDirW,
-        Program_FilesW
+        MAKEINTRESOURCEW(IDS_PROGRAM_FILES)
     },
     { /* 0x27 - CSIDL_MYPICTURES */
         &FOLDERID_Pictures,
@@ -918,7 +927,7 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_ProgramFilesCommon,
         CSIDL_Type_CurrVer,
         CommonFilesDirW,
-        Program_Files_Common_FilesW
+        MAKEINTRESOURCEW(IDS_PROGRAM_FILES_COMMON)
     },
     { /* 0x2c - CSIDL_PROGRAM_FILES_COMMONX86 */
         &FOLDERID_ProgramFilesCommonX86,
@@ -930,25 +939,25 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_CommonTemplates,
         CSIDL_Type_AllUsers,
         Common_TemplatesW,
-        TemplatesW
+        MAKEINTRESOURCEW(IDS_TEMPLATES)
     },
     { /* 0x2e - CSIDL_COMMON_DOCUMENTS */
         &FOLDERID_PublicDocuments,
         CSIDL_Type_AllUsers,
         Common_DocumentsW,
-        DocumentsW
+        MAKEINTRESOURCEW(IDS_PERSONAL)
     },
     { /* 0x2f - CSIDL_COMMON_ADMINTOOLS */
         &FOLDERID_CommonAdminTools,
         CSIDL_Type_AllUsers,
         Common_Administrative_ToolsW,
-        Start_Menu_Admin_ToolsW
+        MAKEINTRESOURCEW(IDS_ADMINTOOLS)
     },
     { /* 0x30 - CSIDL_ADMINTOOLS */
         &FOLDERID_AdminTools,
         CSIDL_Type_User,
         Administrative_ToolsW,
-        Start_Menu_Admin_ToolsW
+        MAKEINTRESOURCEW(IDS_ADMINTOOLS)
     },
     { /* 0x31 - CSIDL_CONNECTIONS */
         &FOLDERID_ConnectionsFolder,
@@ -978,19 +987,19 @@ static const CSIDL_DATA CSIDL_Data[] =
         &FOLDERID_PublicMusic,
         CSIDL_Type_AllUsers,
         CommonMusicW,
-        MusicW
+        MAKEINTRESOURCEW(IDS_COMMON_MUSIC)
     },
     { /* 0x36 - CSIDL_COMMON_PICTURES */
         &FOLDERID_PublicPictures,
         CSIDL_Type_AllUsers,
         CommonPicturesW,
-        PicturesW
+        MAKEINTRESOURCEW(IDS_COMMON_PICTURES)
     },
     { /* 0x37 - CSIDL_COMMON_VIDEO */
         &FOLDERID_PublicVideos,
         CSIDL_Type_AllUsers,
         CommonVideoW,
-        VideosW
+        MAKEINTRESOURCEW(IDS_COMMON_VIDEO)
     },
     { /* 0x38 - CSIDL_RESOURCES */
         &FOLDERID_ResourceDir,
@@ -1034,6 +1043,8 @@ static const CSIDL_DATA CSIDL_Data[] =
         NULL,
         NULL
     },
+/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
+#ifndef __REACTOS__
     { /* 0x3f */
         &FOLDERID_AddNewPrograms,
         CSIDL_Type_Disallowed,
@@ -1346,6 +1357,7 @@ static const CSIDL_DATA CSIDL_Data[] =
         NULL,
         NULL
     }
+#endif
 };
 
 static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest);
@@ -1429,6 +1441,27 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix,
     return hr;
 }
 
+BOOL _SHGetUserProfileDirectoryW(HANDLE hToken, LPWSTR szPath, LPDWORD lpcchPath)
+{
+    BOOL result;
+    if (!hToken)
+    {
+        OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
+        result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
+        CloseHandle(hToken);
+    }
+    else if ((INT) hToken == -1)
+    {
+        result = GetDefaultUserProfileDirectoryW(szPath, lpcchPath);
+    }
+    else
+    {
+        result = GetUserProfileDirectoryW(hToken, szPath, lpcchPath);
+    }
+    DbgPrint("_SHGetUserProfileDirectoryW returning %S\n", szPath);
+    return result;
+}
+
 /* Gets a 'semi-expanded' default value of the CSIDL with index folder into
  * pszPath, based on the entries in CSIDL_Data.  By semi-expanded, I mean:
  * - The entry's szDefaultPath may be either a string value or an integer
@@ -1443,13 +1476,11 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix,
  *   CSIDL_Type_CurrVer:  %SystemDrive%
  *   (Others might make sense too, but as yet are unneeded.)
  */
-static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath)
+static HRESULT _SHGetDefaultValue(HANDLE hToken, BYTE folder, LPWSTR pszPath)
 {
-    DWORD dwSize;
+    DWORD cchSize;
     HRESULT hr;
-    HKEY hKey;
     WCHAR resourcePath[MAX_PATH];
-    LPCWSTR pDefaultPath = NULL;
 
     TRACE("0x%02x,%p\n", folder, pszPath);
 
@@ -1458,80 +1489,57 @@ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath)
     if (!pszPath)
         return E_INVALIDARG;
 
-    if (!is_win64)
+    switch (folder)
     {
-        BOOL is_wow64;
-
-        switch (folder)
-        {
-        case CSIDL_PROGRAM_FILES:
-        case CSIDL_PROGRAM_FILESX86:
-            IsWow64Process( GetCurrentProcess(), &is_wow64 );
-            folder = is_wow64 ? CSIDL_PROGRAM_FILESX86 : CSIDL_PROGRAM_FILES;
-            break;
-        case CSIDL_PROGRAM_FILES_COMMON:
-        case CSIDL_PROGRAM_FILES_COMMONX86:
-            IsWow64Process( GetCurrentProcess(), &is_wow64 );
-            folder = is_wow64 ? CSIDL_PROGRAM_FILES_COMMONX86 : CSIDL_PROGRAM_FILES_COMMON;
-            break;
-        }
+    case CSIDL_PROGRAM_FILES:
+        if (IsWow64())
+            folder = CSIDL_PROGRAM_FILESX86;
+        break;
+    case CSIDL_PROGRAM_FILES_COMMON:
+        if (IsWow64())
+            folder = CSIDL_PROGRAM_FILESX86;
+        break;
     }
 
-#ifdef __REACTOS__ /* FIXME: Inspect */
-    if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+    switch (CSIDL_Data[folder].type)
     {
-        /* FIXME assume MAX_PATH size */
-        dwSize = MAX_PATH * sizeof(WCHAR);
-        if (RegQueryValueExW(hKey, CSIDL_Data[folder].szValueName, NULL, NULL, (LPBYTE)pszPath, &dwSize) == ERROR_SUCCESS)
-        {
-            RegCloseKey(hKey);
-            return S_OK;
-        }
-        RegCloseKey(hKey);
+    case CSIDL_Type_User:
+        cchSize = MAX_PATH;
+        if (!_SHGetUserProfileDirectoryW(hToken, pszPath, &cchSize))
+            return HRESULT_FROM_WIN32(GetLastError());
+        break;
+    case CSIDL_Type_AllUsers:
+        cchSize = MAX_PATH;
+        if (!GetAllUsersProfileDirectoryW(pszPath, &cchSize))
+            return HRESULT_FROM_WIN32(GetLastError());
+        break;
+    case CSIDL_Type_CurrVer:
+        strcpyW(pszPath, SystemDriveW);
+        break;
+    default:
+        ; /* no corresponding env. var, do nothing */
     }
-#endif
 
-    if (CSIDL_Data[folder].szDefaultPath &&
-     IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath))
+    hr = S_OK;
+    if (CSIDL_Data[folder].szDefaultPath)
     {
-        if (LoadStringW(shell32_hInstance,
-         LOWORD(CSIDL_Data[folder].szDefaultPath), resourcePath, MAX_PATH))
+        if (IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath))
         {
-            hr = S_OK;
-            pDefaultPath = resourcePath;
+            if (LoadStringW(shell32_hInstance,
+                LOWORD(CSIDL_Data[folder].szDefaultPath), resourcePath, MAX_PATH))
+            {
+                PathAppendW(pszPath, resourcePath);
+            }
+            else
+            {
+                ERR("(%d,%s), LoadString failed, missing translation?\n", folder,
+                      debugstr_w(pszPath));
+                hr = E_FAIL;
+            }
         }
         else
         {
-            FIXME("(%d,%s), LoadString failed, missing translation?\n", folder,
-             debugstr_w(pszPath));
-            hr = E_FAIL;
-        }
-    }
-    else
-    {
-        hr = S_OK;
-        pDefaultPath = CSIDL_Data[folder].szDefaultPath;
-    }
-    if (SUCCEEDED(hr))
-    {
-        switch (CSIDL_Data[folder].type)
-        {
-            case CSIDL_Type_User:
-                strcpyW(pszPath, UserProfileW);
-                break;
-            case CSIDL_Type_AllUsers:
-                strcpyW(pszPath, AllUsersProfileW);
-                break;
-            case CSIDL_Type_CurrVer:
-                strcpyW(pszPath, SystemDriveW);
-                break;
-            default:
-                ; /* no corresponding env. var, do nothing */
-        }
-        if (pDefaultPath)
-        {
-            PathAddBackslashW(pszPath);
-            strcatW(pszPath, pDefaultPath);
+            PathAppendW(pszPath, CSIDL_Data[folder].szDefaultPath);
         }
     }
     TRACE("returning 0x%08x\n", hr);
@@ -1559,7 +1567,7 @@ static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder,
         return E_INVALIDARG;
 
     if (dwFlags & SHGFP_TYPE_DEFAULT)
-        hr = _SHGetDefaultValue(folder, pszPath);
+        hr = _SHGetDefaultValue(NULL, folder, pszPath);
     else
     {
         HKEY hKey;
@@ -1574,7 +1582,7 @@ static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder,
              &dwType, (LPBYTE)pszPath, &dwPathLen) ||
              (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
             {
-                hr = _SHGetDefaultValue(folder, pszPath);
+                hr = _SHGetDefaultValue(NULL, folder, pszPath);
                 dwType = REG_EXPAND_SZ;
                 switch (folder)
                 {
@@ -1664,12 +1672,7 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder,
 
     if (dwFlags & SHGFP_TYPE_DEFAULT)
     {
-        if (hToken != NULL && hToken != (HANDLE)-1)
-        {
-            FIXME("unsupported for user other than current or default\n");
-            return E_FAIL;
-        }
-        hr = _SHGetDefaultValue(folder, pszPath);
+        hr = _SHGetDefaultValue(hToken, folder, pszPath);
     }
     else
     {
@@ -1706,7 +1709,7 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder,
         if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
             hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL, szValueName, pszPath);
         if (FAILED(hr))
-            hr = _SHGetDefaultValue(folder, pszPath);
+            hr = _SHGetDefaultValue(hToken, folder, pszPath);
         if (userPrefix != NULL && userPrefix != DefaultW)
             LocalFree((HLOCAL) userPrefix);
     }
@@ -1735,13 +1738,13 @@ static HRESULT _SHGetAllUsersProfilePath(DWORD dwFlags, BYTE folder,
         return E_INVALIDARG;
 
     if (dwFlags & SHGFP_TYPE_DEFAULT)
-        hr = _SHGetDefaultValue(folder, pszPath);
+        hr = _SHGetDefaultValue(NULL, folder, pszPath);
     else
     {
         hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL,
          CSIDL_Data[folder].szValueName, pszPath);
         if (FAILED(hr))
-            hr = _SHGetDefaultValue(folder, pszPath);
+            hr = _SHGetDefaultValue(NULL, folder, pszPath);
     }
     TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
     return hr;
@@ -2270,12 +2273,15 @@ static HRESULT _SHRegisterUserShellFolders(BOOL bDefault)
      CSIDL_MYPICTURES,
      CSIDL_FONTS,
      CSIDL_ADMINTOOLS,
+/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
+#ifndef __REACTOS__
      CSIDL_CONTACTS,
      CSIDL_DOWNLOADS,
      CSIDL_LINKS,
      CSIDL_APPDATA_LOCALLOW,
      CSIDL_SAVED_GAMES,
      CSIDL_SEARCHES
+#endif
     };
     WCHAR userShellFolderPath[MAX_PATH], shellFolderPath[MAX_PATH];
     LPCWSTR pUserShellFolderPath, pShellFolderPath;