Module: wine Branch: master Commit: c15b376a159e174f4fe5a0069a40a2f6ca91ff79 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c15b376a159e174f4fe5a0069a...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Sep 21 13:36:17 2010 +0200
shell32: Map the x86 version of the folder to the appropriate path depending on Wow64 mode.
---
dlls/shell32/shellpath.c | 39 ++++++++++++++++- dlls/shell32/tests/shlfolder.c | 91 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index e0228ee..54d7efa 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -54,6 +54,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(shell);
+static const BOOL is_win64 = sizeof(void *) > sizeof(int); + /* ########## Combining and Constructing paths ########## */ @@ -1634,6 +1636,25 @@ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath) if (!pszPath) return E_INVALIDARG;
+ if (!is_win64) + { + 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; + } + } + if (CSIDL_Data[folder].szDefaultPath && IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath)) { @@ -1719,8 +1740,22 @@ static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder, { hr = _SHGetDefaultValue(folder, pszPath); dwType = REG_EXPAND_SZ; - RegSetValueExW(hKey, CSIDL_Data[folder].szValueName, 0, dwType, - (LPBYTE)pszPath, (strlenW(pszPath)+1)*sizeof(WCHAR)); + switch (folder) + { + case CSIDL_PROGRAM_FILESX86: + case CSIDL_PROGRAM_FILES_COMMONX86: + /* these two should never be set on 32-bit setups */ + if (!is_win64) + { + BOOL is_wow64; + IsWow64Process( GetCurrentProcess(), &is_wow64 ); + if (!is_wow64) break; + } + /* fall through */ + default: + RegSetValueExW(hKey, CSIDL_Data[folder].szValueName, 0, dwType, + (LPBYTE)pszPath, (strlenW(pszPath)+1)*sizeof(WCHAR)); + } } else { diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c index e766adf..639b092 100644 --- a/dlls/shell32/tests/shlfolder.c +++ b/dlls/shell32/tests/shlfolder.c @@ -68,6 +68,7 @@ static HRESULT (WINAPI *pSHGetNameFromIDList)(PCIDLIST_ABSOLUTE,SIGDN,PWSTR*); static HRESULT (WINAPI *pSHGetItemFromDataObject)(IDataObject*,DATAOBJ_GET_ITEM_FLAGS,REFIID,void**); static HRESULT (WINAPI *pSHGetIDListFromObject)(IUnknown*, PIDLIST_ABSOLUTE*); static HRESULT (WINAPI *pSHGetItemFromObject)(IUnknown*,REFIID,void**); +static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static int strcmp_wa(LPCWSTR strw, const char *stra) { @@ -143,6 +144,8 @@ static void init_function_pointers(void) hmod = GetModuleHandleA("shlwapi.dll"); pStrRetToBufW = (void*)GetProcAddress(hmod, "StrRetToBufW");
+ pIsWow64Process = (void*)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); + hr = SHGetMalloc(&ppM); ok(hr == S_OK, "SHGetMalloc failed %08x\n", hr); } @@ -1658,6 +1661,93 @@ static void test_ITEMIDLIST_format(void) { IShellFolder_Release(psfPersonal); }
+static void test_SHGetFolderPathA(void) +{ + static const BOOL is_win64 = sizeof(void *) > sizeof(int); + BOOL is_wow64; + char path[MAX_PATH]; + char path_x86[MAX_PATH]; + char path_key[MAX_PATH]; + HRESULT hr; + HKEY key; + + if (!pSHGetFolderPathA) + { + win_skip("SHGetFolderPathA not present\n"); + return; + } + if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE; + + hr = pSHGetFolderPathA( 0, CSIDL_PROGRAM_FILES, 0, SHGFP_TYPE_CURRENT, path ); + ok( !hr, "SHGetFolderPathA failed %x\n", hr ); + hr = pSHGetFolderPathA( 0, CSIDL_PROGRAM_FILESX86, 0, SHGFP_TYPE_CURRENT, path_x86 ); + if (hr == E_FAIL) + { + win_skip( "Program Files (x86) not supported\n" ); + return; + } + ok( !hr, "SHGetFolderPathA failed %x\n", hr ); + if (is_win64) + { + ok( lstrcmpiA( path, path_x86 ), "paths are identical '%s'\n", path ); + ok( strstr( path, "x86" ) == NULL, "64-bit path '%s' contains x86\n", path ); + ok( strstr( path_x86, "x86" ) != NULL, "32-bit path '%s' doesn't contain x86\n", path_x86 ); + } + else + { + ok( !lstrcmpiA( path, path_x86 ), "paths differ '%s' != '%s'\n", path, path_x86 ); + if (is_wow64) + ok( strstr( path, "x86" ) != NULL, "32-bit path '%s' doesn't contain x86\n", path ); + else + ok( strstr( path, "x86" ) == NULL, "32-bit path '%s' contains x86\n", path ); + } + if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows\CurrentVersion", &key )) + { + DWORD type, count = sizeof(path_x86); + if (!RegQueryValueExA( key, "ProgramFilesDir (x86)", NULL, &type, (BYTE *)path_key, &count )) + { + ok( is_win64 || is_wow64, "ProgramFilesDir (x86) exists on 32-bit setup\n" ); + ok( !lstrcmpiA( path_key, path_x86 ), "paths differ '%s' != '%s'\n", path_key, path_x86 ); + } + else ok( !is_win64 && !is_wow64, "ProgramFilesDir (x86) should exist on 64-bit setup\n" ); + RegCloseKey( key ); + } + + hr = pSHGetFolderPathA( 0, CSIDL_PROGRAM_FILES_COMMON, 0, SHGFP_TYPE_CURRENT, path ); + ok( !hr, "SHGetFolderPathA failed %x\n", hr ); + hr = pSHGetFolderPathA( 0, CSIDL_PROGRAM_FILES_COMMONX86, 0, SHGFP_TYPE_CURRENT, path_x86 ); + if (hr == E_FAIL) + { + win_skip( "Common Files (x86) not supported\n" ); + return; + } + ok( !hr, "SHGetFolderPathA failed %x\n", hr ); + if (is_win64) + { + ok( lstrcmpiA( path, path_x86 ), "paths are identical '%s'\n", path ); + ok( strstr( path, "x86" ) == NULL, "64-bit path '%s' contains x86\n", path ); + ok( strstr( path_x86, "x86" ) != NULL, "32-bit path '%s' doesn't contain x86\n", path_x86 ); + } + else + { + ok( !lstrcmpiA( path, path_x86 ), "paths differ '%s' != '%s'\n", path, path_x86 ); + if (is_wow64) + ok( strstr( path, "x86" ) != NULL, "32-bit path '%s' doesn't contain x86\n", path ); + else + ok( strstr( path, "x86" ) == NULL, "32-bit path '%s' contains x86\n", path ); + } + if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows\CurrentVersion", &key )) + { + DWORD type, count = sizeof(path_x86); + if (!RegQueryValueExA( key, "CommonFilesDir (x86)", NULL, &type, (BYTE *)path_key, &count )) + { + ok( is_win64 || is_wow64, "CommonFilesDir (x86) exists on 32-bit setup\n" ); + ok( !lstrcmpiA( path_key, path_x86 ), "paths differ '%s' != '%s'\n", path_key, path_x86 ); + } + else ok( !is_win64 && !is_wow64, "CommonFilesDir (x86) should exist on 64-bit setup\n" ); + } +} + static void test_SHGetFolderPathAndSubDirA(void) { HRESULT ret; @@ -4062,6 +4152,7 @@ START_TEST(shlfolder) test_CallForAttributes(); test_FolderShortcut(); test_ITEMIDLIST_format(); + test_SHGetFolderPathA(); test_SHGetFolderPathAndSubDirA(); test_LocalizedNames(); test_SHCreateShellItem();