Skip to content
Snippets Groups Projects
Commit c471ccfe authored by Pétur Runólfsson's avatar Pétur Runólfsson Committed by Alexandre Julliard
Browse files

wtsapi32: Handle WTSSessionInfo class in WTSQuerySessionInformationW().

parent ab28cf3b
No related branches found
No related tags found
No related merge requests found
......@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <windef.h>
#include <winbase.h>
#include <winuser.h>
#include <winternl.h>
#include <lmcons.h>
#include <wtsapi32.h>
......@@ -188,13 +189,27 @@ static void test_WTSEnumerateProcessesW(void)
pWTSFreeMemoryExW(WTSTypeProcessInfoLevel0, info, count);
}
static LONGLONG get_system_time_as_longlong(void)
{
LARGE_INTEGER li;
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
li.u.LowPart = ft.dwLowDateTime;
li.u.HighPart = ft.dwHighDateTime;
return li.QuadPart;
}
static void test_WTSQuerySessionInformation(void)
{
WCHAR *buf1, usernameW[UNLEN + 1], computernameW[MAX_COMPUTERNAME_LENGTH + 1];
char *buf2, username[UNLEN + 1], computername[MAX_COMPUTERNAME_LENGTH + 1];
DWORD count, tempsize, sessionId;
WTS_CONNECTSTATE_CLASS *state;
DWORD count, tempsize;
WTSINFOW *wtsinfoW;
WTSINFOA *wtsinfoA;
USHORT *protocol;
LONGLONG t1, t2;
BOOL ret;
count = 0;
......@@ -309,6 +324,66 @@ static void test_WTSQuerySessionInformation(void)
ok(protocol != NULL, "protocol not set\n");
ok(count == sizeof(*protocol), "got %lu\n", count);
WTSFreeMemory(protocol);
ProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
count = 0;
wtsinfoW = NULL;
t1 = get_system_time_as_longlong();
ret = WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSSessionInfo,
(WCHAR **)&wtsinfoW, &count);
ok(ret, "got %lu\n", GetLastError());
t2 = get_system_time_as_longlong();
ok(count == sizeof(*wtsinfoW), "got %lu\n", count);
ok(wtsinfoW->State == WTSActive, "got %d.\n", wtsinfoW->State);
ok(wtsinfoW->SessionId == sessionId, "expected %lu, got %lu\n", sessionId, wtsinfoW->SessionId);
ok(wtsinfoW->IncomingBytes == 0, "got %lu\n", wtsinfoW->IncomingBytes);
ok(wtsinfoW->OutgoingBytes == 0, "got %lu\n", wtsinfoW->OutgoingBytes);
ok(wtsinfoW->IncomingFrames == 0, "got %lu\n", wtsinfoW->IncomingFrames);
ok(wtsinfoW->OutgoingFrames == 0, "got %lu\n", wtsinfoW->OutgoingFrames);
ok(wtsinfoW->IncomingCompressedBytes == 0, "got %lu\n", wtsinfoW->IncomingCompressedBytes);
ok(wtsinfoW->OutgoingCompressedBytes == 0, "got %lu\n", wtsinfoW->OutgoingCompressedBytes);
ok(!wcscmp(wtsinfoW->WinStationName, L"Console"), "got %s\n", wine_dbgstr_w(wtsinfoW->WinStationName));
ok(!wcsicmp(wtsinfoW->Domain, computernameW),
"expected %s, got %s\n",
wine_dbgstr_w(computernameW), wine_dbgstr_w(wtsinfoW->Domain));
ok(!wcsicmp(wtsinfoW->UserName, usernameW),
"expected %s, got %s\n",
wine_dbgstr_w(usernameW), wine_dbgstr_w(wtsinfoW->UserName));
ok(t1 <= wtsinfoW->CurrentTime.QuadPart,
"out of order %s %s\n",
wine_dbgstr_longlong(t1), wine_dbgstr_longlong(wtsinfoW->CurrentTime.QuadPart));
ok(wtsinfoW->CurrentTime.QuadPart <= t2,
"out of order %s %s\n",
wine_dbgstr_longlong(wtsinfoW->CurrentTime.QuadPart), wine_dbgstr_longlong(t2));
WTSFreeMemory(wtsinfoW);
count = 0;
wtsinfoA = NULL;
t1 = get_system_time_as_longlong();
ret = WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSSessionInfo,
(char **)&wtsinfoA, &count);
ok(ret, "got %lu\n", GetLastError());
t2 = get_system_time_as_longlong();
ok(count == sizeof(*wtsinfoA), "got %lu\n", count);
ok(wtsinfoA->State == WTSActive, "got %d.\n", wtsinfoA->State);
ok(wtsinfoA->SessionId == sessionId, "expected %lu, got %lu\n", sessionId, wtsinfoA->SessionId);
ok(wtsinfoA->IncomingBytes == 0, "got %lu\n", wtsinfoA->IncomingBytes);
ok(wtsinfoA->OutgoingBytes == 0, "got %lu\n", wtsinfoA->OutgoingBytes);
ok(wtsinfoA->IncomingFrames == 0, "got %lu\n", wtsinfoA->IncomingFrames);
ok(wtsinfoA->OutgoingFrames == 0, "got %lu\n", wtsinfoA->OutgoingFrames);
ok(wtsinfoA->IncomingCompressedBytes == 0, "got %lu\n", wtsinfoA->IncomingCompressedBytes);
ok(wtsinfoA->OutgoingCompressedBytes == 0, "got %lu\n", wtsinfoA->OutgoingCompressedBytes);
ok(!strcmp(wtsinfoA->WinStationName, "Console"), "got %s\n", wtsinfoA->WinStationName);
ok(!stricmp(wtsinfoA->Domain, computername), "expected %s, got %s\n", computername, wtsinfoA->Domain);
ok(!stricmp(wtsinfoA->UserName, username), "expected %s, got %s\n", username, wtsinfoA->UserName);
ok(t1 <= wtsinfoA->CurrentTime.QuadPart,
"out of order %s %s\n",
wine_dbgstr_longlong(t1), wine_dbgstr_longlong(wtsinfoA->CurrentTime.QuadPart));
ok(wtsinfoA->CurrentTime.QuadPart <= t2,
"out of order %s %s\n",
wine_dbgstr_longlong(wtsinfoA->CurrentTime.QuadPart), wine_dbgstr_longlong(t2));
WTSFreeMemory(wtsinfoA);
}
static void test_WTSQueryUserToken(void)
......
......@@ -470,6 +470,51 @@ BOOL WINAPI WTSQuerySessionInformationA(HANDLE server, DWORD session_id, WTS_INF
if (class == WTSClientProtocolType || class == WTSConnectState)
return WTSQuerySessionInformationW(server, session_id, class, (WCHAR **)buffer, count);
if (class == WTSSessionInfo)
{
DWORD size;
WTSINFOA *info;
WTSINFOW *infoW;
if (!WTSQuerySessionInformationW(server, session_id, class, (WCHAR **)&infoW, &size))
return FALSE;
if (!(info = malloc(sizeof(*info))))
{
WTSFreeMemory(infoW);
return FALSE;
}
memset(info, 0, sizeof(*info));
info->State = infoW->State;
info->SessionId = infoW->SessionId;
size = sizeof(info->WinStationName);
if (!WideCharToMultiByte(CP_ACP, 0, infoW->WinStationName, -1, info->WinStationName, size, NULL, NULL))
{
WTSFreeMemory(infoW);
free(info);
return FALSE;
}
size = sizeof(info->Domain);
if (!WideCharToMultiByte(CP_ACP, 0, infoW->Domain, -1, info->Domain, size, NULL, NULL))
{
WTSFreeMemory(infoW);
free(info);
return FALSE;
}
size = sizeof(info->UserName);
if (!WideCharToMultiByte(CP_ACP, 0, infoW->UserName, -1, info->UserName, size, NULL, NULL))
{
WTSFreeMemory(infoW);
free(info);
return FALSE;
}
info->CurrentTime = infoW->CurrentTime;
WTSFreeMemory(infoW);
*buffer = (char *)info;
*count = sizeof(*info);
return TRUE;
}
if (!WTSQuerySessionInformationW(server, session_id, class, &bufferW, count))
return FALSE;
......@@ -559,6 +604,35 @@ BOOL WINAPI WTSQuerySessionInformationW(HANDLE server, DWORD session_id, WTS_INF
return TRUE;
}
if (class == WTSSessionInfo)
{
WTSINFOW *info;
FILETIME ft;
DWORD size;
if (!(info = malloc(sizeof(*info)))) return FALSE;
FIXME("returning partial WTSINFO\n");
memset(info, 0, sizeof(*info));
info->State = WTSActive;
if (!ProcessIdToSessionId(GetCurrentProcessId(), &info->SessionId))
{
free(info);
return FALSE;
}
wcscpy(info->WinStationName, L"Console");
size = sizeof(info->Domain) / sizeof(WCHAR);
GetComputerNameW(info->Domain, &size);
size = sizeof(info->UserName) / sizeof(WCHAR);
GetUserNameW(info->UserName, &size);
GetSystemTimeAsFileTime(&ft);
info->CurrentTime.LowPart = ft.dwLowDateTime;
info->CurrentTime.HighPart = ft.dwHighDateTime;
/* TODO: fill remaining timestamps with real data */
*buffer = (WCHAR *)info;
*count = sizeof(*info);
return TRUE;
}
FIXME("Unimplemented class %d\n", class);
*buffer = NULL;
......
......@@ -49,6 +49,19 @@ typedef enum tagWTS_INFO_CLASS
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType,
WTSIdleTime,
WTSLogonTime,
WTSIncomingBytes,
WTSOutgoingBytes,
WTSIncomingFrames,
WTSOutgoingFrames,
WTSClientInfo,
WTSSessionInfo,
WTSSessionInfoEx,
WTSConfigInfo,
WTSValidationInfo,
WTSSessionAddressV4,
WTSIsRemoteSession
} WTS_INFO_CLASS;
typedef enum _WTS_CONNECTSTATE_CLASS
......@@ -169,6 +182,51 @@ typedef struct _WTS_SERVER_INFOW
DECL_WINELIB_TYPE_AW(WTS_SERVER_INFO)
DECL_WINELIB_TYPE_AW(PWTS_SERVER_INFO)
#define WINSTATIONNAME_LENGTH 32
#define USERNAME_LENGTH 20
#define DOMAIN_LENGTH 17
typedef struct _WTSINFOA {
WTS_CONNECTSTATE_CLASS State;
DWORD SessionId;
DWORD IncomingBytes;
DWORD OutgoingBytes;
DWORD IncomingFrames;
DWORD OutgoingFrames;
DWORD IncomingCompressedBytes;
DWORD OutgoingCompressedBytes;
CHAR WinStationName[WINSTATIONNAME_LENGTH];
CHAR Domain[DOMAIN_LENGTH];
CHAR UserName[USERNAME_LENGTH + 1];
LARGE_INTEGER ConnectTime;
LARGE_INTEGER DisconnectTime;
LARGE_INTEGER LastInputTime;
LARGE_INTEGER LogonTime;
LARGE_INTEGER CurrentTime;
} WTSINFOA, *PWTSINFOA;
typedef struct _WTSINFOW {
WTS_CONNECTSTATE_CLASS State;
DWORD SessionId;
DWORD IncomingBytes;
DWORD OutgoingBytes;
DWORD IncomingFrames;
DWORD OutgoingFrames;
DWORD IncomingCompressedBytes;
DWORD OutgoingCompressedBytes;
WCHAR WinStationName[WINSTATIONNAME_LENGTH];
WCHAR Domain[DOMAIN_LENGTH];
WCHAR UserName[USERNAME_LENGTH + 1];
LARGE_INTEGER ConnectTime;
LARGE_INTEGER DisconnectTime;
LARGE_INTEGER LastInputTime;
LARGE_INTEGER LogonTime;
LARGE_INTEGER CurrentTime;
} WTSINFOW, *PWTSINFOW;
DECL_WINELIB_TYPE_AW(WTSINFO)
DECL_WINELIB_TYPE_AW(PWTSINFO)
#define WTS_CURRENT_SERVER_HANDLE ((HANDLE)NULL)
#define WTS_CURRENT_SESSION (~0u)
#define WTS_ANY_SESSION ((DWORD)-2)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment