From: Stefan Leichter Subject: wtsapi32: Partial implementation of WTSEnumerateProcessesW (try 4) Message-Id: <201403272334.03001.Stefan.Leichter@camline.com> Date: Thu, 27 Mar 2014 23:34:02 +0100 fixes bug #29903 --- dlls/wtsapi32/tests/wtsapi.c | 1 - dlls/wtsapi32/wtsapi32.c | 65 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/dlls/wtsapi32/tests/wtsapi.c b/dlls/wtsapi32/tests/wtsapi.c index e8dced7..a317e5f 100644 --- a/dlls/wtsapi32/tests/wtsapi.c +++ b/dlls/wtsapi32/tests/wtsapi.c @@ -85,7 +85,6 @@ static void test_WTSEnumerateProcessesW(void) { found = found || !lstrcmpW(pname, info[i].pProcessName); } - todo_wine ok(found || broken(!ret), "process name %s not found\n", wine_dbgstr_w(pname)); if (info) WTSFreeMemory(info); } diff --git a/dlls/wtsapi32/wtsapi32.c b/dlls/wtsapi32/wtsapi32.c index 79d5a7f..9066f95 100644 --- a/dlls/wtsapi32/wtsapi32.c +++ b/dlls/wtsapi32/wtsapi32.c @@ -18,8 +18,11 @@ #include "config.h" #include #include +#include "ntstatus.h" +#define WIN32_NO_STATUS #include "windef.h" #include "winbase.h" +#include "winternl.h" #include "wtsapi32.h" #include "wine/debug.h" @@ -84,8 +87,13 @@ BOOL WINAPI WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version BOOL WINAPI WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOW* ppProcessInfo, DWORD* pCount) { - FIXME("Stub %p 0x%08x 0x%08x %p %p\n", hServer, Reserved, Version, - ppProcessInfo, pCount); + SYSTEM_PROCESS_INFORMATION *spi; + ULONG size = 100 * sizeof(SYSTEM_PROCESS_INFORMATION); + void *buf = NULL; + NTSTATUS status; + DWORD i,lcount = 0, strsize = 0; + WCHAR *name; + WTS_PROCESS_INFOW *linfo; if (!ppProcessInfo || !pCount || Reserved != 0 || Version != 1) { @@ -96,6 +104,59 @@ BOOL WINAPI WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version *pCount = 0; *ppProcessInfo = NULL; + if (hServer != WTS_CURRENT_SERVER_HANDLE) + { + FIXME("Only WTS_CURRENT_SERVER_HANDLE is impemented\n"); + return FALSE; + } + + do { + size *= 2; + HeapFree(GetProcessHeap(), 0, buf); + buf = HeapAlloc(GetProcessHeap(), 0, size); + if (!buf) + return FALSE; + + status = NtQuerySystemInformation(SystemProcessInformation, buf, size, NULL); + } while(status == STATUS_INFO_LENGTH_MISMATCH); + + if (status != STATUS_SUCCESS) + { + HeapFree(GetProcessHeap(), 0, buf); + SetLastError(RtlNtStatusToDosError(status)); + return FALSE; + } + + spi = buf; + + do { + lcount++; + strsize += spi->ProcessName.MaximumLength; + spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset); + } while(spi->NextEntryOffset != 0); + + linfo = HeapAlloc(GetProcessHeap(), 0, lcount * sizeof(WTS_PROCESS_INFOW) + strsize * sizeof(WCHAR)); + if (!linfo) + return FALSE; + + name = (WCHAR*) &linfo[lcount]; + + for (i = 0, spi = buf; i < lcount; i++) + { + linfo[i].SessionId = 0; + linfo[i].ProcessId = HandleToUlong(spi->UniqueProcessId); + linfo[i].pProcessName = name; + linfo[i].pUserSid = NULL; + memcpy( name, spi->ProcessName.Buffer, spi->ProcessName.MaximumLength ); + + name += spi->ProcessName.MaximumLength; + spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset); + } + *ppProcessInfo = linfo; + *pCount = lcount; + FIXME("pUserSid not filled\n"); + + HeapFree(GetProcessHeap(), 0, buf); return TRUE; }