From: Michael Müller Subject: shell32: Create profile directories available in Vista and above Message-Id: <53D80AA7.8020703@fds-team.de> Date: Tue, 29 Jul 2014 22:57:11 +0200 This patch fixes the bugs #22896 and #28312 by creating the necessary profile directories and adding the according registry keys. The key names match the implementation on Windows Server 2012. --- dlls/shell32/shellpath.c | 58 ++++++++++++++++++++++++++++++++-------------- include/shlobj.h | 9 +++++++ 2 files changed, 50 insertions(+), 17 deletions(-) From 92dc11a14302d63443d61d5d2a2e0c1da130aa3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Mon, 28 Jul 2014 01:21:04 +0200 Subject: shell32: Create profile directories available in Vista and above. --- dlls/shell32/shellpath.c | 58 ++++++++++++++++++++++++++++++++-------------- include/shlobj.h | 9 +++++++ 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index 158b1d1..e7548d1 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -1280,10 +1280,10 @@ static const CSIDL_DATA CSIDL_Data[] = NULL, NULL }, - { /* 0x43 */ + { /* 0x43 - CSIDL_WINE_CONTACTS */ &FOLDERID_Contacts, CSIDL_Type_User, - ContactsW, + NULL, ContactsW }, { /* 0x44 */ @@ -1304,7 +1304,7 @@ static const CSIDL_DATA CSIDL_Data[] = NULL, NULL }, - { /* 0x47 */ + { /* 0x47 - CSIDL_WINE_DOWNLOADS */ &FOLDERID_Downloads, CSIDL_Type_User, NULL, @@ -1340,13 +1340,13 @@ static const CSIDL_DATA CSIDL_Data[] = NULL, NULL }, - { /* 0x4d */ + { /* 0x4d - CSIDL_WINE_LINKS */ &FOLDERID_Links, CSIDL_Type_User, NULL, LinksW }, - { /* 0x4e */ + { /* 0x4e - CSIDL_WINE_APPDATA_LOCALLOW */ &FOLDERID_LocalAppDataLow, CSIDL_Type_User, NULL, @@ -1466,13 +1466,13 @@ static const CSIDL_DATA CSIDL_Data[] = NULL, Videos_Sample_VideosW }, - { /* 0x62 */ + { /* 0x62 - CSIDL_WINE_SAVED_GAMES */ &FOLDERID_SavedGames, CSIDL_Type_User, NULL, Saved_GamesW }, - { /* 0x63 */ + { /* 0x63 - CSIDL_WINE_SEARCHES */ &FOLDERID_SavedSearches, CSIDL_Type_User, NULL, @@ -1855,6 +1855,8 @@ static LPWSTR _GetUserSidStringFromToken(HANDLE Token) static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder, LPWSTR pszPath) { + const WCHAR *szValueName; + WCHAR buffer[40]; HRESULT hr; TRACE("%p,0x%08x,0x%02x,%p\n", hToken, dwFlags, folder, pszPath); @@ -1897,11 +1899,18 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder, goto error; } } - hr = _SHGetUserShellFolderPath(hRootKey, userPrefix, - CSIDL_Data[folder].szValueName, pszPath); + + /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */ + szValueName = CSIDL_Data[folder].szValueName; + if (!szValueName) + { + StringFromGUID2( CSIDL_Data[folder].id, buffer, 39 ); + szValueName = &buffer[0]; + } + + hr = _SHGetUserShellFolderPath(hRootKey, userPrefix, szValueName, pszPath); if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE) - hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL, - CSIDL_Data[folder].szValueName, pszPath); + hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL, szValueName, pszPath); if (FAILED(hr)) hr = _SHGetDefaultValue(folder, pszPath); if (userPrefix != NULL && userPrefix != DefaultW) @@ -2361,6 +2370,8 @@ static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken, LPCWSTR szUserShellFolderPath, LPCWSTR szShellFolderPath, const UINT folders[], UINT foldersLen) { + const WCHAR *szValueName; + WCHAR buffer[40]; UINT i; WCHAR path[MAX_PATH]; HRESULT hr = S_OK; @@ -2383,7 +2394,16 @@ static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken, for (i = 0; SUCCEEDED(hr) && i < foldersLen; i++) { dwPathLen = MAX_PATH * sizeof(WCHAR); - if (RegQueryValueExW(hUserKey, CSIDL_Data[folders[i]].szValueName, NULL, + + /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */ + szValueName = CSIDL_Data[folders[i]].szValueName; + if (!szValueName && CSIDL_Data[folders[i]].type == CSIDL_Type_User) + { + StringFromGUID2( CSIDL_Data[folders[i]].id, buffer, 39 ); + szValueName = &buffer[0]; + } + + if (RegQueryValueExW(hUserKey, szValueName, NULL, &dwType, (LPBYTE)path, &dwPathLen) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ)) { @@ -2407,8 +2427,7 @@ static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken, hr = E_FAIL; if (*path) { - ret = RegSetValueExW(hUserKey, - CSIDL_Data[folders[i]].szValueName, 0, REG_EXPAND_SZ, + ret = RegSetValueExW(hUserKey, szValueName, 0, REG_EXPAND_SZ, (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR)); if (ret) hr = HRESULT_FROM_WIN32(ret); @@ -2416,8 +2435,7 @@ static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken, { hr = SHGetFolderPathW(NULL, folders[i] | CSIDL_FLAG_CREATE, hToken, SHGFP_TYPE_DEFAULT, path); - ret = RegSetValueExW(hKey, - CSIDL_Data[folders[i]].szValueName, 0, REG_SZ, + ret = RegSetValueExW(hKey, szValueName, 0, REG_SZ, (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR)); if (ret) hr = HRESULT_FROM_WIN32(ret); @@ -2457,7 +2475,13 @@ static HRESULT _SHRegisterUserShellFolders(BOOL bDefault) CSIDL_HISTORY, CSIDL_MYPICTURES, CSIDL_FONTS, - CSIDL_ADMINTOOLS + CSIDL_ADMINTOOLS, + CSIDL_WINE_CONTACTS, + CSIDL_WINE_DOWNLOADS, + CSIDL_WINE_LINKS, + CSIDL_WINE_APPDATA_LOCALLOW, + CSIDL_WINE_SAVED_GAMES, + CSIDL_WINE_SEARCHES }; WCHAR userShellFolderPath[MAX_PATH], shellFolderPath[MAX_PATH]; LPCWSTR pUserShellFolderPath, pShellFolderPath; diff --git a/include/shlobj.h b/include/shlobj.h index 9025a73..dcea14e 100644 --- a/include/shlobj.h +++ b/include/shlobj.h @@ -1529,6 +1529,15 @@ HRESULT WINAPI SHGetFolderPathW(HWND hwnd, int nFolder, HANDLE hToken, DWORD dwF #define CSIDL_CDBURN_AREA 0x003b #define CSIDL_COMPUTERSNEARME 0x003d #define CSIDL_PROFILES 0x003e + +/* Wine internal CSIDLs */ +#define CSIDL_WINE_CONTACTS 0x0043 +#define CSIDL_WINE_DOWNLOADS 0x0047 +#define CSIDL_WINE_LINKS 0x004d +#define CSIDL_WINE_APPDATA_LOCALLOW 0x004e +#define CSIDL_WINE_SAVED_GAMES 0x0062 +#define CSIDL_WINE_SEARCHES 0x0063 + #define CSIDL_FOLDER_MASK 0x00ff #define CSIDL_FLAG_PER_USER_INIT 0x0800 #define CSIDL_FLAG_NO_ALIAS 0x1000 -- 1.7.9.5