Francois Gouget : kernel32: Fix the NT path returned by QueryFullProcessImageName().

Alexandre Julliard julliard at winehq.org
Tue Oct 4 17:43:04 CDT 2011


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

Author: Francois Gouget <fgouget at codeweavers.com>
Date:   Mon Oct  3 23:56:12 2011 +0200

kernel32: Fix the NT path returned by QueryFullProcessImageName().

---

 dlls/kernel32/process.c       |   60 +++++++++++++++++++++++++++++-----------
 dlls/kernel32/tests/process.c |    8 +++---
 2 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 3c6ae63..c540f44 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -3429,14 +3429,12 @@ BOOL WINAPI QueryFullProcessImageNameW(HANDLE hProcess, DWORD dwFlags, LPWSTR lp
 {
     BYTE buffer[sizeof(UNICODE_STRING) + MAX_PATH*sizeof(WCHAR)];  /* this buffer should be enough */
     UNICODE_STRING *dynamic_buffer = NULL;
-    UNICODE_STRING nt_path;
     UNICODE_STRING *result = NULL;
     NTSTATUS status;
     DWORD needed;
 
-    RtlInitUnicodeStringEx(&nt_path, NULL);
-    /* FIXME: On Windows, ProcessImageFileName return an NT path. We rely that it being a DOS path,
-     * as this is on Wine. */
+    /* FIXME: On Windows, ProcessImageFileName return an NT path. In Wine it
+     * is a DOS path and we depend on this. */
     status = NtQueryInformationProcess(hProcess, ProcessImageFileName, buffer,
                                        sizeof(buffer) - sizeof(WCHAR), &needed);
     if (status == STATUS_INFO_LENGTH_MISMATCH)
@@ -3452,28 +3450,56 @@ BOOL WINAPI QueryFullProcessImageNameW(HANDLE hProcess, DWORD dwFlags, LPWSTR lp
 
     if (dwFlags & PROCESS_NAME_NATIVE)
     {
-        result->Buffer[result->Length / sizeof(WCHAR)] = 0;
-        if (!RtlDosPathNameToNtPathName_U(result->Buffer, &nt_path, NULL, NULL))
+        WCHAR drive[3];
+        WCHAR device[1024];
+        DWORD ntlen, devlen;
+
+        if (result->Buffer[1] != ':' || result->Buffer[0] < 'A' || result->Buffer[0] > 'Z')
         {
-            status = STATUS_OBJECT_PATH_NOT_FOUND;
+            /* We cannot convert it to an NT device path so fail */
+            status = STATUS_NO_SUCH_DEVICE;
             goto cleanup;
         }
-        result = &nt_path;
-    }
 
-    if (result->Length/sizeof(WCHAR) + 1 > *pdwSize)
-    {
-        status = STATUS_BUFFER_TOO_SMALL;
-        goto cleanup;
+        /* Find this drive's NT device path */
+        drive[0] = result->Buffer[0];
+        drive[1] = ':';
+        drive[2] = 0;
+        if (!QueryDosDeviceW(drive, device, sizeof(device)/sizeof(*device)))
+        {
+            status = STATUS_NO_SUCH_DEVICE;
+            goto cleanup;
+        }
+
+        devlen = lstrlenW(device);
+        ntlen = devlen + (result->Length/sizeof(WCHAR) - 2);
+        if (ntlen + 1 > *pdwSize)
+        {
+            SetLastError(ERROR_INSUFFICIENT_BUFFER);
+            return 0;
+        }
+        *pdwSize = ntlen;
+
+        memcpy(lpExeName, device, devlen * sizeof(*device));
+        memcpy(lpExeName + devlen, result->Buffer + 2, result->Length - 2 * sizeof(WCHAR));
+        lpExeName[*pdwSize] = 0;
+        TRACE("NT path: %s\n", debugstr_w(lpExeName));
     }
+    else
+    {
+        if (result->Length/sizeof(WCHAR) + 1 > *pdwSize)
+        {
+            status = STATUS_BUFFER_TOO_SMALL;
+            goto cleanup;
+        }
 
-    *pdwSize = result->Length/sizeof(WCHAR);
-    memcpy( lpExeName, result->Buffer, result->Length );
-    lpExeName[*pdwSize] = 0;
+        *pdwSize = result->Length/sizeof(WCHAR);
+        memcpy( lpExeName, result->Buffer, result->Length );
+        lpExeName[*pdwSize] = 0;
+    }
 
 cleanup:
     HeapFree(GetProcessHeap(), 0, dynamic_buffer);
-    RtlFreeUnicodeString(&nt_path);
     if (status) SetLastError( RtlNtStatusToDosError(status) );
     return !status;
 }
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 65c2836..ac387bf 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -1802,7 +1802,7 @@ static void test_QueryFullProcessImageNameW(void)
     expect_eq_d(TRUE, pQueryFullProcessImageNameW(hSelf, PROCESS_NAME_NATIVE, buf, &size));
     expect_eq_d(lstrlenW(buf), size);
     ok(buf[0] == '\\', "NT path should begin with '\\'\n");
-    todo_wine ok(memcmp(buf, deviceW, sizeof(WCHAR)*lstrlenW(deviceW)) == 0, "NT path should begin with \\Device\n");
+    ok(memcmp(buf, deviceW, sizeof(WCHAR)*lstrlenW(deviceW)) == 0, "NT path should begin with \\Device\n");
 
     module_name[2] = '\0';
     *device = '\0';
@@ -1817,10 +1817,10 @@ static void test_QueryFullProcessImageNameW(void)
     }
     else
     {
-        todo_wine ok(buf[len] == '\\', "expected '%c' to be a '\\' in %s\n", buf[len], wine_dbgstr_w(module_name));
+        ok(buf[len] == '\\', "expected '%c' to be a '\\' in %s\n", buf[len], wine_dbgstr_w(module_name));
         buf[len] = '\0';
-        todo_wine ok(lstrcmpiW(device, buf) == 0, "expected %s to match %s\n", wine_dbgstr_w(device), wine_dbgstr_w(buf));
-        todo_wine ok(lstrcmpiW(module_name+3, buf+len+1) == 0, "expected '%s' to match '%s'\n", wine_dbgstr_w(module_name+3), wine_dbgstr_w(buf+len+1));
+        ok(lstrcmpiW(device, buf) == 0, "expected %s to match %s\n", wine_dbgstr_w(device), wine_dbgstr_w(buf));
+        ok(lstrcmpiW(module_name+3, buf+len+1) == 0, "expected '%s' to match '%s'\n", wine_dbgstr_w(module_name+3), wine_dbgstr_w(buf+len+1));
     }
 
     CloseHandle(hSelf);




More information about the wine-cvs mailing list