#include <wine/debug.h>
#include <wine/unicode.h>
+#include <userenv.h>
+
#include "pidl.h"
#include "shell32_main.h"
#include "shresdef.h"
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 ##########
*/
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]
*
/*************************************************************************
* 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);
}
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]
*/
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
{
&FOLDERID_Programs,
CSIDL_Type_User,
ProgramsW,
- Start_Menu_ProgramsW
+ MAKEINTRESOURCEW(IDS_PROGRAMS)
},
{ /* 0x03 - CSIDL_CONTROLS (.CPL files) */
&FOLDERID_ControlPanelFolder,
&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,
&FOLDERID_StartMenu,
CSIDL_Type_User,
Start_MenuW,
- Start_MenuW
+ MAKEINTRESOURCEW(IDS_STARTMENU)
},
{ /* 0x0c - CSIDL_MYDOCUMENTS */
&GUID_NULL,
&FOLDERID_NetHood,
CSIDL_Type_User,
NetHoodW,
- NetHoodW
+ MAKEINTRESOURCEW(IDS_NETHOOD)
},
{ /* 0x14 - CSIDL_FONTS */
&FOLDERID_Fonts,
&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,
&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,
&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,
&FOLDERID_ProgramFiles,
CSIDL_Type_CurrVer,
ProgramFilesDirW,
- Program_FilesW
+ MAKEINTRESOURCEW(IDS_PROGRAM_FILES)
},
{ /* 0x27 - CSIDL_MYPICTURES */
&FOLDERID_Pictures,
&FOLDERID_ProgramFilesCommon,
CSIDL_Type_CurrVer,
CommonFilesDirW,
- Program_Files_Common_FilesW
+ MAKEINTRESOURCEW(IDS_PROGRAM_FILES_COMMON)
},
{ /* 0x2c - CSIDL_PROGRAM_FILES_COMMONX86 */
&FOLDERID_ProgramFilesCommonX86,
&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,
&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,
NULL,
NULL
},
+/* Cannot use #if _WIN32_WINNT >= 0x0600 because _WIN32_WINNT == 0x0600 here. */
+#ifndef __REACTOS__
{ /* 0x3f */
&FOLDERID_AddNewPrograms,
CSIDL_Type_Disallowed,
NULL,
NULL
}
+#endif
};
static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest);
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
* 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);
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);
return E_INVALIDARG;
if (dwFlags & SHGFP_TYPE_DEFAULT)
- hr = _SHGetDefaultValue(folder, pszPath);
+ hr = _SHGetDefaultValue(NULL, folder, pszPath);
else
{
HKEY hKey;
&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)
{
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
{
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);
}
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;
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;