Module: wine Branch: master Commit: a2af890483580c9acbd00555dd4daa9d447e83fa URL: http://source.winehq.org/git/wine.git/?a=commit;h=a2af890483580c9acbd00555dd...
Author: Francois Gouget fgouget@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);