* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include <config.h>
+#include "config.h"
#include <stdarg.h>
-//#include <stdlib.h>
-#include <windef.h>
-#include <winbase.h>
-#include <wtsapi32.h>
-#include <wine/debug.h>
+#include <stdlib.h>
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winbase.h"
+#include "wine/winternl.h"
+#include "wtsapi32.h"
+#include "wine/debug.h"
+#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(wtsapi);
+#ifdef __REACTOS__ /* FIXME: Inspect */
+#define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3)
+#endif
/************************************************************
* WTSCloseServer (WTSAPI32.@)
return TRUE;
}
+/************************************************************
+ * WTSEnableChildSessions (WTSAPI32.@)
+ */
+BOOL WINAPI WTSEnableChildSessions(BOOL enable)
+{
+ FIXME("Stub %d\n", enable);
+ return TRUE;
+}
+
/************************************************************
* WTSEnumerateProcessesA (WTSAPI32.@)
*/
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);
+ WTS_PROCESS_INFOW *processInfo;
+ SYSTEM_PROCESS_INFORMATION *spi;
+ ULONG size = 0x4000;
+ void *buf = NULL;
+ NTSTATUS status;
+ DWORD count;
+ WCHAR *name;
if (!ppProcessInfo || !pCount || Reserved != 0 || Version != 1)
{
return FALSE;
}
- *pCount = 0;
- *ppProcessInfo = NULL;
+ if (hServer != WTS_CURRENT_SERVER_HANDLE)
+ {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+ }
+ do
+ {
+ size *= 2;
+ HeapFree(GetProcessHeap(), 0, buf);
+ buf = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!buf)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ 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;
+ count = size = 0;
+ for (;;)
+ {
+ size += sizeof(WTS_PROCESS_INFOW) + spi->ProcessName.Length + sizeof(WCHAR);
+ count++;
+ if (spi->NextEntryOffset == 0) break;
+ spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset);
+ }
+
+ processInfo = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!processInfo)
+ {
+ HeapFree(GetProcessHeap(), 0, buf);
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+ name = (WCHAR *)&processInfo[count];
+
+ *ppProcessInfo = processInfo;
+ *pCount = count;
+
+ spi = buf;
+ while (count--)
+ {
+ processInfo->SessionId = 0;
+ processInfo->ProcessId = HandleToUlong(spi->UniqueProcessId);
+ processInfo->pProcessName = name;
+ processInfo->pUserSid = NULL;
+ memcpy( name, spi->ProcessName.Buffer, spi->ProcessName.Length );
+ name[ spi->ProcessName.Length/sizeof(WCHAR) ] = 0;
+
+ processInfo++;
+ name += (spi->ProcessName.Length + sizeof(WCHAR))/sizeof(WCHAR);
+ spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset);
+ }
+
+ HeapFree(GetProcessHeap(), 0, buf);
return TRUE;
}
*/
void WINAPI WTSFreeMemory(PVOID pMemory)
{
- static int once;
-
- if (!once++) FIXME("Stub %p\n", pMemory);
+ heap_free(pMemory);
}
/************************************************************
LPSTR* Buffer,
DWORD* BytesReturned)
{
+#ifdef __REACTOS__
+ const size_t wcsErrorCode = -1;
+ LPWSTR buffer = NULL;
+ LPSTR ansiBuffer = NULL;
+ DWORD bytesReturned = 0;
+ BOOL result = FALSE;
+ size_t len;
+
+ if (!BytesReturned || !Buffer)
+ {
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ return FALSE;
+ }
+
+ if (!WTSQuerySessionInformationW(hServer, SessionId, WTSInfoClass, &buffer, &bytesReturned))
+ {
+ ansiBuffer = (LPSTR)buffer;
+ *Buffer = ansiBuffer;
+ *BytesReturned = bytesReturned;
+ return FALSE;
+ }
+
+ switch (WTSInfoClass)
+ {
+ case WTSInitialProgram:
+ case WTSApplicationName:
+ case WTSWorkingDirectory:
+ case WTSOEMId:
+ case WTSUserName:
+ case WTSWinStationName:
+ case WTSDomainName:
+ case WTSClientName:
+ case WTSClientDirectory:
+ {
+ len = wcstombs(NULL, buffer, 0);
+ if (len != wcsErrorCode)
+ {
+ len++;
+ ansiBuffer = heap_alloc_zero(len);
+ if (ansiBuffer && (wcstombs(ansiBuffer, buffer, len) != wcsErrorCode))
+ {
+ result = TRUE;
+ bytesReturned = len;
+ }
+ }
+ WTSFreeMemory(buffer);
+ break;
+ }
+
+ default:
+ {
+ result = TRUE;
+ ansiBuffer = (LPSTR)buffer;
+ break;
+ }
+ }
+
+ *Buffer = ansiBuffer;
+ *BytesReturned = bytesReturned;
+
+ return result;
+#else
/* FIXME: Forward request to winsta.dll::WinStationQueryInformationA */
FIXME("Stub %p 0x%08x %d %p %p\n", hServer, SessionId, WTSInfoClass,
Buffer, BytesReturned);
return FALSE;
+#endif
}
/************************************************************
LPWSTR* Buffer,
DWORD* BytesReturned)
{
+#ifdef __REACTOS__
+ if (!BytesReturned || !Buffer)
+ {
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ return FALSE;
+ }
+
+#if (NTDDI_VERSION >= NTDDI_WS08)
+ if (WTSInfoClass > WTSIsRemoteSession)
+#else
+ if (WTSInfoClass > WTSClientProtocolType)
+#endif
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ switch (WTSInfoClass)
+ {
+ case WTSSessionId:
+ {
+ const DWORD size = sizeof(ULONG);
+ ULONG* output = heap_alloc_zero(size);
+ if (!output)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ *output = NtCurrentTeb()->Peb->SessionId;
+ *Buffer = (LPWSTR)output;
+ *BytesReturned = size;
+ return TRUE;
+ }
+
+ case WTSUserName:
+ {
+ WCHAR* username;
+ DWORD count = 0;
+
+ GetUserNameW(NULL, &count);
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ return FALSE;
+ username = heap_alloc(count * sizeof(WCHAR));
+ if (!username)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ GetUserNameW(username, &count);
+ *Buffer = username;
+ *BytesReturned = count * sizeof(WCHAR);
+ return TRUE;
+ }
+
+ case WTSConnectState:
+ {
+ const DWORD size = sizeof(DWORD);
+ WCHAR* output = heap_alloc_zero(size);
+ if (!output)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ *Buffer = output;
+ *BytesReturned = size;
+ return TRUE;
+ }
+
+ case WTSClientProtocolType:
+ {
+ const DWORD size = sizeof(WORD);
+ WCHAR* output = heap_alloc_zero(size);
+ if (!output)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ *Buffer = output;
+ *BytesReturned = size;
+ return TRUE;
+ }
+
+#if (NTDDI_VERSION >= NTDDI_WS08)
+ case WTSIdleTime:
+ case WTSLogonTime:
+ case WTSIncomingBytes:
+ case WTSOutgoingBytes:
+ case WTSIncomingFrames:
+ case WTSOutgoingFrames:
+ {
+ SetLastError(ERROR_NOT_SUPPORTED);
+ return FALSE;
+ }
+#endif /* (NTDDI_VERSION >= NTDDI_WS08) */
+
+ default:
+ {
+ if (BytesReturned)
+ *BytesReturned = 0;
+
+ break;
+ }
+ }
+
/* FIXME: Forward request to winsta.dll::WinStationQueryInformationW */
FIXME("Stub %p 0x%08x %d %p %p\n", hServer, SessionId, WTSInfoClass,
Buffer, BytesReturned);
return FALSE;
+#else
+ /* FIXME: Forward request to winsta.dll::WinStationQueryInformationW */
+ FIXME("Stub %p 0x%08x %d %p %p\n", hServer, SessionId, WTSInfoClass,
+ Buffer, BytesReturned);
+
+ if (WTSInfoClass == WTSUserName)
+ {
+ WCHAR *username;
+ DWORD count = 0;
+
+ GetUserNameW(NULL, &count);
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE;
+ if (!(username = heap_alloc(count * sizeof(WCHAR)))) return FALSE;
+ GetUserNameW(username, &count);
+ *Buffer = username;
+ *BytesReturned = count * sizeof(WCHAR);
+ return TRUE;
+ }
+ return FALSE;
+#endif
}
/************************************************************
BOOL WINAPI WTSQueryUserToken(ULONG session_id, PHANDLE token)
{
FIXME("%u %p\n", session_id, token);
- return FALSE;
+
+ if (!token)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return DuplicateHandle(GetCurrentProcess(), GetCurrentProcessToken(),
+ GetCurrentProcess(), token,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
}
/************************************************************
}
/************************************************************
- * WTSRegisterSessionNotification (WTSAPI32.@)
+ * WTSRegisterSessionNotificationEx (WTSAPI32.@)
*/
BOOL WINAPI WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags)
{