From 57f923674177789b9edf9b5405d88f9b02e33f66 Mon Sep 17 00:00:00 2001 From: Stefan Leichter Date: Wed, 10 Jun 2009 20:39:42 +0200 Subject: [PATCH] kernel32: Implement QueryFullProcessImageNameA. --- dlls/kernel32/kernel32.spec | 2 +- dlls/kernel32/process.c | 21 +++++++++++++ dlls/kernel32/tests/process.c | 56 +++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 17344600ab4..5182e71fc1a 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -865,7 +865,7 @@ @ stdcall QueryDepthSList(ptr) ntdll.RtlQueryDepthSList @ stdcall QueryDosDeviceA(str ptr long) @ stdcall QueryDosDeviceW(wstr ptr long) -@ stub QueryFullProcessImageNameA +@ stdcall QueryFullProcessImageNameA(ptr long ptr ptr) @ stdcall QueryFullProcessImageNameW(ptr long ptr ptr) @ stdcall QueryInformationJobObject(long long ptr long ptr) # @ stub QueryMemoryResourceNotification diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index f00d972ab96..31faf73244f 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -3133,6 +3133,27 @@ BOOL WINAPI GetProcessHandleCount(HANDLE hProcess, DWORD *cnt) return !status; } +/****************************************************************** + * QueryFullProcessImageNameA (KERNEL32.@) + */ +BOOL WINAPI QueryFullProcessImageNameA(HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD pdwSize) +{ + BOOL retval; + DWORD pdwSizeW = *pdwSize; + LPWSTR lpExeNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pdwSize * sizeof(WCHAR)); + + retval = QueryFullProcessImageNameW(hProcess, dwFlags, lpExeNameW, &pdwSizeW); + + if(retval) + retval = (0 != WideCharToMultiByte(CP_ACP, 0, lpExeNameW, -1, + lpExeName, *pdwSize, NULL, NULL)); + if(retval) + *pdwSize = strlen(lpExeName); + + HeapFree(GetProcessHeap(), 0, lpExeNameW); + return retval; +} + /****************************************************************** * QueryFullProcessImageNameW (KERNEL32.@) */ diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 05fab17cbe0..d8087a642c5 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -41,6 +41,12 @@ ok((expected) == value, "Expected " #actual " to be %d (" #expected ") is %d\n", \ (expected), value); \ } while (0) +#define expect_eq_s(expected, actual) \ + do { \ + LPCSTR value = (actual); \ + ok(lstrcmpA((expected), value) == 0, "Expected " #actual " to be L\"%s\" (" #expected ") is L\"%s\"\n", \ + expected, value); \ + } while (0) #define expect_eq_ws_i(expected, actual) \ do { \ LPCWSTR value = (actual); \ @@ -68,6 +74,7 @@ static const char *wine_dbgstr_w(LPCWSTR wstr) static HINSTANCE hkernel32; static LPVOID (WINAPI *pVirtualAllocEx)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD); static BOOL (WINAPI *pVirtualFreeEx)(HANDLE, LPVOID, SIZE_T, DWORD); +static BOOL (WINAPI *pQueryFullProcessImageNameA)(HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD lpdwSize); static BOOL (WINAPI *pQueryFullProcessImageNameW)(HANDLE hProcess, DWORD dwFlags, LPWSTR lpExeName, PDWORD lpdwSize); /* ############################### */ @@ -206,6 +213,7 @@ static int init(void) hkernel32 = GetModuleHandleA("kernel32"); pVirtualAllocEx = (void *) GetProcAddress(hkernel32, "VirtualAllocEx"); pVirtualFreeEx = (void *) GetProcAddress(hkernel32, "VirtualFreeEx"); + pQueryFullProcessImageNameA = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameA"); pQueryFullProcessImageNameW = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameW"); return 1; } @@ -1618,6 +1626,53 @@ static void test_GetProcessVersion(void) CloseHandle(pi.hThread); } +static void test_ProcessNameA(void) +{ +#define INIT_STR "Just some words" + DWORD length, size; + CHAR buf[1024]; + + if (!pQueryFullProcessImageNameA) + { + win_skip("QueryFullProcessImageNameA unavailable (added in Windows Vista)\n"); + return; + } + /* get the buffer length without \0 terminator */ + length = 1024; + expect_eq_d(TRUE, pQueryFullProcessImageNameA(GetCurrentProcess(), 0, buf, &length)); + expect_eq_d(length, lstrlenA(buf)); + + /* when the buffer is too small + * - function fail with error ERROR_INSUFFICIENT_BUFFER + * - the size variable is not modified + * tested with the biggest too small size + */ + size = length; + sprintf(buf,INIT_STR); + expect_eq_d(FALSE, pQueryFullProcessImageNameA(GetCurrentProcess(), 0, buf, &size)); + expect_eq_d(ERROR_INSUFFICIENT_BUFFER, GetLastError()); + expect_eq_d(length, size); + expect_eq_s(INIT_STR, buf); + + /* retest with smaller buffer size + */ + size = 4; + sprintf(buf,INIT_STR); + expect_eq_d(FALSE, pQueryFullProcessImageNameA(GetCurrentProcess(), 0, buf, &size)); + expect_eq_d(ERROR_INSUFFICIENT_BUFFER, GetLastError()); + expect_eq_d(4, size); + expect_eq_s(INIT_STR, buf); + + /* this is a difference between the ascii and the unicode version + * the unicode version crashes when the size is big enough to hold the result + * ascii version throughs an error + */ + size = 1024; + expect_eq_d(FALSE, pQueryFullProcessImageNameA(GetCurrentProcess(), 0, NULL, &size)); + expect_eq_d(1024, size); + expect_eq_d(ERROR_INVALID_PARAMETER, GetLastError()); +} + static void test_ProcessName(void) { HANDLE hSelf; @@ -1741,6 +1796,7 @@ START_TEST(process) test_ExitCode(); test_OpenProcess(); test_GetProcessVersion(); + test_ProcessNameA(); test_ProcessName(); test_Handles(); /* things that can be tested: