From: Stefan Leichter Subject: wtsapi32: partial implementation of WTSEnumerateProcessesW Message-Id: <201308262225.12989.Stefan.Leichter@camline.com> Date: Mon, 26 Aug 2013 22:25:12 +0200 --- dlls/wtsapi32/wtsapi32.c | 63 +++++++++++++++++++++++++++++++++++++++++++--- include/wtsapi32.h | 2 ++ 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/dlls/wtsapi32/wtsapi32.c b/dlls/wtsapi32/wtsapi32.c index 898b95d..53c6325 100644 --- a/dlls/wtsapi32/wtsapi32.c +++ b/dlls/wtsapi32/wtsapi32.c @@ -18,9 +18,13 @@ #include "config.h" #include #include -#include "windef.h" -#include "winbase.h" +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "winternl.h" #include "wtsapi32.h" +#include "wine/library.h" +#include "wine/server.h" +#include "wine/unicode.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(wtsapi); @@ -84,14 +88,65 @@ 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 = 0x4000; + void *buf = NULL; + NTSTATUS status; + DWORD i,lcount = 0; + WTS_PROCESS_INFOW *linfo; if (!ppProcessInfo || !pCount) return FALSE; *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++; + spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset); + } while(spi->NextEntryOffset != 0); + + linfo = HeapAlloc(GetProcessHeap(), 0, lcount * sizeof(WTS_PROCESS_INFOW)); + if(!linfo) + return FALSE; + + for(i = 0, spi = buf; i < lcount; i++) + { + linfo[i].SessionId = 0; + linfo[i].ProcessId = HandleToUlong(spi->UniqueProcessId); + linfo[i].pProcessName = spi->ProcessName.Buffer; + linfo[i].pUserSid = NULL; + spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset); + } + *ppProcessInfo = linfo; + *pCount = lcount; + FIXME("pUserSid not filled\n"); + + HeapFree(GetProcessHeap(), 0, buf); return TRUE; } diff --git a/include/wtsapi32.h b/include/wtsapi32.h index f4bab56..0476478 100644 --- a/include/wtsapi32.h +++ b/include/wtsapi32.h @@ -135,6 +135,8 @@ typedef struct _WTS_SERVER_INFOW DECL_WINELIB_TYPE_AW(WTS_SERVER_INFO) DECL_WINELIB_TYPE_AW(PWTS_SERVER_INFO) +#define WTS_CURRENT_SERVER_HANDLE NULL + void WINAPI WTSCloseServer(HANDLE); BOOL WINAPI WTSConnectSessionA(ULONG, ULONG, PSTR, BOOL); BOOL WINAPI WTSConnectSessionW(ULONG, ULONG, PWSTR, BOOL);