[PATCH] shell32: Disable WOW64 redirection when converting pidls to UNIX paths. (try 2, resend)

Octavian Voicu octavian.voicu at gmail.com
Thu Jul 28 18:29:39 CDT 2011


This should fix the comdlg32:filedlg failures on WOW64 [1].

The Open/Save dialogs convert the initial directory (system32) to a pidl.
On Wine, without this patch, the pidl points to the syswow64 directory,
causing the failure.

try 2: Load GetSystemWow64DirectoryW dynamically, skip test if not avaialble.

Octavian


[1] http://test.winehq.org/data/e0f1aa0b05b50f9dcc4ee7ea7428997fda168228/linux_ov-ku1104-wow64/comdlg32:filedlg.html

---
 dlls/shell32/shfldr_unixfs.c   |    5 ++++-
 dlls/shell32/tests/shlfolder.c |   27 +++++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c
index 8f52a80..9649df8 100644
--- a/dlls/shell32/shfldr_unixfs.c
+++ b/dlls/shell32/shfldr_unixfs.c
@@ -371,7 +371,8 @@ static BOOL UNIXFS_get_unix_path(LPCWSTR pszDosPath, char *pszCanonicalPath)
     char *pPathTail, *pElement, *pCanonicalTail, szPath[FILENAME_MAX], *pszUnixPath, has_failed = 0, mb_path[FILENAME_MAX];
     WCHAR wszDrive[] = { '?', ':', '\\', 0 }, dospath[PATH_MAX], *dospath_end;
     int cDriveSymlinkLen;
-    
+    void *redir;
+
     TRACE("(pszDosPath=%s, pszCanonicalPath=%p)\n", debugstr_w(pszDosPath), pszCanonicalPath);
 
     if (!pszDosPath || pszDosPath[1] != ':')
@@ -392,6 +393,7 @@ static BOOL UNIXFS_get_unix_path(LPCWSTR pszDosPath, char *pszCanonicalPath)
     dospath_end = dospath + lstrlenW(dospath);
     /* search for the most valid UNIX path possible, then append missing
      * path parts */
+    Wow64DisableWow64FsRedirection(&redir);
     while(!(pszUnixPath = wine_get_unix_file_name(dospath))){
         if(has_failed){
             *dospath_end = '/';
@@ -405,6 +407,7 @@ static BOOL UNIXFS_get_unix_path(LPCWSTR pszDosPath, char *pszCanonicalPath)
         }
         *dospath_end = '\0';
     }
+    Wow64RevertWow64FsRedirection(redir);
     if(dospath_end < dospath)
         return FALSE;
     strcat(szPath, pszUnixPath + cDriveSymlinkLen);
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index 681a28f..5e6bf89 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -70,6 +70,7 @@ static HRESULT (WINAPI *pSHGetItemFromDataObject)(IDataObject*,DATAOBJ_GET_ITEM_
 static HRESULT (WINAPI *pSHGetIDListFromObject)(IUnknown*, PIDLIST_ABSOLUTE*);
 static HRESULT (WINAPI *pSHGetItemFromObject)(IUnknown*,REFIID,void**);
 static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
+static UINT (WINAPI *pGetSystemWow64DirectoryW)(LPWSTR, UINT);
 
 static WCHAR *make_wstr(const char *str)
 {
@@ -165,7 +166,9 @@ static void init_function_pointers(void)
     hmod = GetModuleHandleA("shlwapi.dll");
     pStrRetToBufW = (void*)GetProcAddress(hmod, "StrRetToBufW");
 
-    pIsWow64Process = (void*)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
+    hmod = GetModuleHandleA("kernel32.dll");
+    pIsWow64Process = (void*)GetProcAddress(hmod, "IsWow64Process");
+    pGetSystemWow64DirectoryW = (void*)GetProcAddress(hmod, "GetSystemWow64DirectoryW");
 
     hr = SHGetMalloc(&ppM);
     ok(hr == S_OK, "SHGetMalloc failed %08x\n", hr);
@@ -3727,7 +3730,7 @@ static void test_SHParseDisplayName(void)
     WCHAR dirW[MAX_PATH];
     WCHAR nameW[10];
     HRESULT hr;
-    BOOL ret;
+    BOOL ret, is_wow64;
 
     if (!pSHParseDisplayName)
     {
@@ -3775,6 +3778,26 @@ if (0)
     pILFree(pidl1);
     pILFree(pidl2);
 
+    /* system32 is not redirected to syswow64 on WOW64 */
+    if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
+    if (is_wow64 && pGetSystemWow64DirectoryW)
+    {
+        *dirW = 0;
+        ok(GetSystemDirectoryW(dirW, MAX_PATH) > 0, "GetSystemDirectoryW failed: %u\n", GetLastError());
+        hr = pSHParseDisplayName(dirW, NULL, &pidl1, 0, NULL);
+        ok(hr == S_OK, "failed %08x\n", hr);
+        *dirW = 0;
+        ok(pGetSystemWow64DirectoryW(dirW, MAX_PATH) > 0, "GetSystemWow64DirectoryW failed: %u\n", GetLastError());
+        hr = pSHParseDisplayName(dirW, NULL, &pidl2, 0, NULL);
+        ok(hr == S_OK, "failed %08x\n", hr);
+        ret = pILIsEqual(pidl1, pidl2);
+        ok(ret == FALSE, "expected different idls\n");
+        pILFree(pidl1);
+        pILFree(pidl2);
+    }
+    else
+        win_skip("Not on WOW64, skipping test.\n");
+
     IShellFolder_Release(desktop);
 }
 
-- 
1.7.4.1




More information about the wine-patches mailing list