Alexandre Julliard : shell32: Map the x86 version of the folder to the appropriate path depending on Wow64 mode .

Alexandre Julliard julliard at winehq.org
Tue Sep 21 13:59:26 CDT 2010


Module: wine
Branch: master
Commit: c15b376a159e174f4fe5a0069a40a2f6ca91ff79
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c15b376a159e174f4fe5a0069a40a2f6ca91ff79

Author: Alexandre Julliard <julliard at 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();




More information about the wine-cvs mailing list