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