summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr/wtsapi/test
diff options
context:
space:
mode:
Diffstat (limited to 'winpr/libwinpr/wtsapi/test')
-rw-r--r--winpr/libwinpr/wtsapi/test/CMakeLists.txt74
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiEnumerateProcesses.c49
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiEnumerateSessions.c50
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiExtraDisconnectSession.c22
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiExtraDynamicVirtualChannel.c53
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiExtraLogoffSession.c22
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiExtraSendMessage.c30
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiExtraStartRemoteSessionEx.c31
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiExtraVirtualChannel.c53
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiQuerySessionInformation.c225
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiSessionNotification.c62
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiShutdownSystem.c35
-rw-r--r--winpr/libwinpr/wtsapi/test/TestWtsApiWaitSystemEvent.c39
13 files changed, 745 insertions, 0 deletions
diff --git a/winpr/libwinpr/wtsapi/test/CMakeLists.txt b/winpr/libwinpr/wtsapi/test/CMakeLists.txt
new file mode 100644
index 0000000..d5bf76c
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/CMakeLists.txt
@@ -0,0 +1,74 @@
+
+set(MODULE_NAME "TestWtsApi")
+set(MODULE_PREFIX "TEST_WTSAPI")
+
+set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
+
+set(UNIX_ONLY
+ TestWtsApiShutdownSystem.c
+ TestWtsApiWaitSystemEvent.c
+ )
+
+set(${MODULE_PREFIX}_TESTS
+ TestWtsApiEnumerateProcesses.c
+ TestWtsApiEnumerateSessions.c
+ TestWtsApiQuerySessionInformation.c
+ TestWtsApiSessionNotification.c
+ )
+
+if(NOT WIN32)
+ set(${MODULE_PREFIX}_TESTS ${${MODULE_PREFIX}_TESTS} ${UNIX_ONLY})
+endif()
+
+create_test_sourcelist(${MODULE_PREFIX}_SRCS
+ ${${MODULE_PREFIX}_DRIVER}
+ ${${MODULE_PREFIX}_TESTS})
+
+add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
+
+
+target_link_libraries(${MODULE_NAME} winpr)
+
+set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
+
+foreach(test ${${MODULE_PREFIX}_TESTS})
+ get_filename_component(TestName ${test} NAME_WE)
+ add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
+endforeach()
+
+set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
+
+if(TESTS_WTSAPI_EXTRA)
+
+set(MODULE_NAME "TestWtsApiExtra")
+set(MODULE_PREFIX "TEST_WTSAPI_EXTRA")
+
+set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
+
+set(${MODULE_PREFIX}_TESTS
+ TestWtsApiExtraDisconnectSession.c
+ TestWtsApiExtraDynamicVirtualChannel.c
+ TestWtsApiExtraLogoffSession.c
+ TestWtsApiExtraSendMessage.c
+ TestWtsApiExtraVirtualChannel.c
+ TestWtsApiExtraStartRemoteSessionEx.c
+ )
+
+create_test_sourcelist(${MODULE_PREFIX}_SRCS
+ ${${MODULE_PREFIX}_DRIVER}
+ ${${MODULE_PREFIX}_TESTS})
+
+add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
+
+target_link_libraries(${MODULE_NAME} winpr)
+
+set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
+
+foreach(test ${${MODULE_PREFIX}_TESTS})
+ get_filename_component(TestName ${test} NAME_WE)
+ add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
+ set_tests_properties(${TestName} PROPERTIES LABELS "WTSAPI_EXTRA")
+endforeach()
+
+set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
+endif()
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiEnumerateProcesses.c b/winpr/libwinpr/wtsapi/test/TestWtsApiEnumerateProcesses.c
new file mode 100644
index 0000000..f26646c
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiEnumerateProcesses.c
@@ -0,0 +1,49 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+#include <winpr/environment.h>
+
+int TestWtsApiEnumerateProcesses(int argc, char* argv[])
+{
+ DWORD count = 0;
+ BOOL bSuccess = 0;
+ HANDLE hServer = NULL;
+ PWTS_PROCESS_INFOA pProcessInfo = NULL;
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+#ifndef _WIN32
+ if (!GetEnvironmentVariableA("WTSAPI_LIBRARY", NULL, 0))
+ {
+ printf("%s: No RDS environment detected, skipping test\n", __func__);
+ return 0;
+ }
+#endif
+
+ hServer = WTS_CURRENT_SERVER_HANDLE;
+
+ count = 0;
+ pProcessInfo = NULL;
+
+ bSuccess = WTSEnumerateProcessesA(hServer, 0, 1, &pProcessInfo, &count);
+
+ if (!bSuccess)
+ {
+ printf("WTSEnumerateProcesses failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+
+#if 0
+ {
+ printf("WTSEnumerateProcesses enumerated %"PRIu32" processs:\n", count);
+ for (DWORD i = 0; i < count; i++)
+ printf("\t[%"PRIu32"]: %s (%"PRIu32")\n", i, pProcessInfo[i].pProcessName, pProcessInfo[i].ProcessId);
+ }
+#endif
+
+ WTSFreeMemory(pProcessInfo);
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiEnumerateSessions.c b/winpr/libwinpr/wtsapi/test/TestWtsApiEnumerateSessions.c
new file mode 100644
index 0000000..afe48a9
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiEnumerateSessions.c
@@ -0,0 +1,50 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+#include <winpr/environment.h>
+
+int TestWtsApiEnumerateSessions(int argc, char* argv[])
+{
+ DWORD count = 0;
+ BOOL bSuccess = 0;
+ HANDLE hServer = NULL;
+ PWTS_SESSION_INFOA pSessionInfo = NULL;
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+#ifndef _WIN32
+ if (!GetEnvironmentVariableA("WTSAPI_LIBRARY", NULL, 0))
+ {
+ printf("%s: No RDS environment detected, skipping test\n", __func__);
+ return 0;
+ }
+#endif
+
+ hServer = WTS_CURRENT_SERVER_HANDLE;
+
+ count = 0;
+ pSessionInfo = NULL;
+
+ bSuccess = WTSEnumerateSessionsA(hServer, 0, 1, &pSessionInfo, &count);
+
+ if (!bSuccess)
+ {
+ printf("WTSEnumerateSessions failed: %" PRIu32 "\n", GetLastError());
+ return 0;
+ }
+
+ printf("WTSEnumerateSessions count: %" PRIu32 "\n", count);
+
+ for (DWORD index = 0; index < count; index++)
+ {
+ printf("[%" PRIu32 "] SessionId: %" PRIu32 " WinstationName: '%s' State: %s (%u)\n", index,
+ pSessionInfo[index].SessionId, pSessionInfo[index].pWinStationName,
+ WTSSessionStateToString(pSessionInfo[index].State), pSessionInfo[index].State);
+ }
+
+ WTSFreeMemory(pSessionInfo);
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiExtraDisconnectSession.c b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraDisconnectSession.c
new file mode 100644
index 0000000..4d04e59
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraDisconnectSession.c
@@ -0,0 +1,22 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+
+int TestWtsApiExtraDisconnectSession(int argc, char* argv[])
+{
+ BOOL bSuccess;
+ HANDLE hServer;
+
+ hServer = WTS_CURRENT_SERVER_HANDLE;
+
+ bSuccess = WTSDisconnectSession(hServer, WTS_CURRENT_SESSION, FALSE);
+
+ if (!bSuccess)
+ {
+ printf("WTSDisconnectSession failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiExtraDynamicVirtualChannel.c b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraDynamicVirtualChannel.c
new file mode 100644
index 0000000..d0bd87e
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraDynamicVirtualChannel.c
@@ -0,0 +1,53 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+
+int TestWtsApiExtraDynamicVirtualChannel(int argc, char* argv[])
+{
+ BOOL bSuccess;
+ ULONG length;
+ ULONG bytesRead;
+ ULONG bytesWritten;
+ BYTE buffer[1024];
+ HANDLE hVirtualChannel;
+
+ length = sizeof(buffer);
+
+ hVirtualChannel =
+ WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, "ECHO", WTS_CHANNEL_OPTION_DYNAMIC);
+
+ if (hVirtualChannel == INVALID_HANDLE_VALUE)
+ {
+ printf("WTSVirtualChannelOpen failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+ printf("WTSVirtualChannelOpen opend");
+ bytesWritten = 0;
+ bSuccess = WTSVirtualChannelWrite(hVirtualChannel, (PCHAR)buffer, length, &bytesWritten);
+
+ if (!bSuccess)
+ {
+ printf("WTSVirtualChannelWrite failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+ printf("WTSVirtualChannelWrite written");
+
+ bytesRead = 0;
+ bSuccess = WTSVirtualChannelRead(hVirtualChannel, 5000, (PCHAR)buffer, length, &bytesRead);
+
+ if (!bSuccess)
+ {
+ printf("WTSVirtualChannelRead failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+ printf("WTSVirtualChannelRead read");
+
+ if (!WTSVirtualChannelClose(hVirtualChannel))
+ {
+ printf("WTSVirtualChannelClose failed\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiExtraLogoffSession.c b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraLogoffSession.c
new file mode 100644
index 0000000..2af5002
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraLogoffSession.c
@@ -0,0 +1,22 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+
+int TestWtsApiExtraLogoffSession(int argc, char* argv[])
+{
+ BOOL bSuccess;
+ HANDLE hServer;
+
+ hServer = WTS_CURRENT_SERVER_HANDLE;
+
+ bSuccess = WTSLogoffSession(hServer, WTS_CURRENT_SESSION, FALSE);
+
+ if (!bSuccess)
+ {
+ printf("WTSLogoffSession failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiExtraSendMessage.c b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraSendMessage.c
new file mode 100644
index 0000000..f311af8
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraSendMessage.c
@@ -0,0 +1,30 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+#include <winpr/user.h>
+
+#define TITLE "thats the title"
+#define MESSAGE "thats the message"
+
+int TestWtsApiExtraSendMessage(int argc, char* argv[])
+{
+ BOOL bSuccess;
+ HANDLE hServer;
+ DWORD result;
+
+ hServer = WTS_CURRENT_SERVER_HANDLE;
+
+ bSuccess = WTSSendMessageA(hServer, WTS_CURRENT_SESSION, TITLE, strlen(TITLE) + 1, MESSAGE,
+ strlen(MESSAGE) + 1, MB_CANCELTRYCONTINUE, 3, &result, TRUE);
+
+ if (!bSuccess)
+ {
+ printf("WTSSendMessage failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+
+ printf("WTSSendMessage got result: %" PRIu32 "\n", result);
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiExtraStartRemoteSessionEx.c b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraStartRemoteSessionEx.c
new file mode 100644
index 0000000..179d33b
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraStartRemoteSessionEx.c
@@ -0,0 +1,31 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+#include <winpr/input.h>
+#include <winpr/environment.h>
+
+int TestWtsApiExtraStartRemoteSessionEx(int argc, char* argv[])
+{
+ BOOL bSuccess;
+ ULONG logonId = 0;
+ char logonIdStr[10];
+
+ bSuccess = GetEnvironmentVariableA("TEST_SESSION_LOGON_ID", logonIdStr, 10);
+ if (bSuccess)
+ {
+ sscanf(logonIdStr, "%u\n", &logonId);
+ }
+
+ bSuccess = WTSStartRemoteControlSessionEx(
+ NULL, logonId, VK_F10, REMOTECONTROL_KBDSHIFT_HOTKEY | REMOTECONTROL_KBDCTRL_HOTKEY,
+ REMOTECONTROL_FLAG_DISABLE_INPUT);
+
+ if (!bSuccess)
+ {
+ printf("WTSStartRemoteControlSessionEx failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiExtraVirtualChannel.c b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraVirtualChannel.c
new file mode 100644
index 0000000..c528e51
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiExtraVirtualChannel.c
@@ -0,0 +1,53 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+
+int TestWtsApiExtraVirtualChannel(int argc, char* argv[])
+{
+ BOOL bSuccess;
+ ULONG length;
+ ULONG bytesRead;
+ ULONG bytesWritten;
+ BYTE buffer[1024];
+ HANDLE hVirtualChannel;
+
+ length = sizeof(buffer);
+
+ hVirtualChannel =
+ WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, "sample");
+
+ if (hVirtualChannel == INVALID_HANDLE_VALUE)
+ {
+ printf("WTSVirtualChannelOpen failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+ printf("WTSVirtualChannelOpen opend");
+ bytesWritten = 0;
+ bSuccess = WTSVirtualChannelWrite(hVirtualChannel, (PCHAR)buffer, length, &bytesWritten);
+
+ if (!bSuccess)
+ {
+ printf("WTSVirtualChannelWrite failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+ printf("WTSVirtualChannelWrite written");
+
+ bytesRead = 0;
+ bSuccess = WTSVirtualChannelRead(hVirtualChannel, 5000, (PCHAR)buffer, length, &bytesRead);
+
+ if (!bSuccess)
+ {
+ printf("WTSVirtualChannelRead failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+ printf("WTSVirtualChannelRead read");
+
+ if (!WTSVirtualChannelClose(hVirtualChannel))
+ {
+ printf("WTSVirtualChannelClose failed\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiQuerySessionInformation.c b/winpr/libwinpr/wtsapi/test/TestWtsApiQuerySessionInformation.c
new file mode 100644
index 0000000..bc232f0
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiQuerySessionInformation.c
@@ -0,0 +1,225 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+#include <winpr/environment.h>
+
+int TestWtsApiQuerySessionInformation(int argc, char* argv[])
+{
+ DWORD count = 0;
+ BOOL bSuccess = 0;
+ HANDLE hServer = NULL;
+ LPSTR pBuffer = NULL;
+ DWORD sessionId = 0;
+ DWORD bytesReturned = 0;
+ PWTS_SESSION_INFOA pSessionInfo = NULL;
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+#ifndef _WIN32
+ if (!GetEnvironmentVariableA("WTSAPI_LIBRARY", NULL, 0))
+ {
+ printf("%s: No RDS environment detected, skipping test\n", __func__);
+ return 0;
+ }
+#endif
+
+ hServer = WTS_CURRENT_SERVER_HANDLE;
+
+ count = 0;
+ pSessionInfo = NULL;
+
+ bSuccess = WTSEnumerateSessionsA(hServer, 0, 1, &pSessionInfo, &count);
+
+ if (!bSuccess)
+ {
+ printf("WTSEnumerateSessions failed: %" PRIu32 "\n", GetLastError());
+ return 0;
+ }
+
+ printf("WTSEnumerateSessions count: %" PRIu32 "\n", count);
+
+ for (DWORD index = 0; index < count; index++)
+ {
+ char* Username = NULL;
+ char* Domain = NULL;
+ char* ClientName = NULL;
+ ULONG ClientBuildNumber = 0;
+ USHORT ClientProductId = 0;
+ ULONG ClientHardwareId = 0;
+ USHORT ClientProtocolType = 0;
+ PWTS_CLIENT_DISPLAY ClientDisplay = NULL;
+ PWTS_CLIENT_ADDRESS ClientAddress = NULL;
+ WTS_CONNECTSTATE_CLASS ConnectState = WTSInit;
+
+ pBuffer = NULL;
+ bytesReturned = 0;
+
+ sessionId = pSessionInfo[index].SessionId;
+
+ printf("[%" PRIu32 "] SessionId: %" PRIu32 " State: %s (%u) WinstationName: '%s'\n", index,
+ pSessionInfo[index].SessionId, WTSSessionStateToString(pSessionInfo[index].State),
+ pSessionInfo[index].State, pSessionInfo[index].pWinStationName);
+
+ /* WTSUserName */
+
+ bSuccess =
+ WTSQuerySessionInformationA(hServer, sessionId, WTSUserName, &pBuffer, &bytesReturned);
+
+ if (!bSuccess)
+ {
+ printf("WTSQuerySessionInformation WTSUserName failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+
+ Username = (char*)pBuffer;
+ printf("\tWTSUserName: '%s'\n", Username);
+
+ /* WTSDomainName */
+
+ bSuccess = WTSQuerySessionInformationA(hServer, sessionId, WTSDomainName, &pBuffer,
+ &bytesReturned);
+
+ if (!bSuccess)
+ {
+ printf("WTSQuerySessionInformation WTSDomainName failed: %" PRIu32 "\n",
+ GetLastError());
+ return -1;
+ }
+
+ Domain = (char*)pBuffer;
+ printf("\tWTSDomainName: '%s'\n", Domain);
+
+ /* WTSConnectState */
+
+ bSuccess = WTSQuerySessionInformationA(hServer, sessionId, WTSConnectState, &pBuffer,
+ &bytesReturned);
+
+ if (!bSuccess)
+ {
+ printf("WTSQuerySessionInformation WTSConnectState failed: %" PRIu32 "\n",
+ GetLastError());
+ return -1;
+ }
+
+ ConnectState = *((WTS_CONNECTSTATE_CLASS*)pBuffer);
+ printf("\tWTSConnectState: %u (%s)\n", ConnectState, WTSSessionStateToString(ConnectState));
+
+ /* WTSClientBuildNumber */
+
+ bSuccess = WTSQuerySessionInformationA(hServer, sessionId, WTSClientBuildNumber, &pBuffer,
+ &bytesReturned);
+
+ if (!bSuccess)
+ {
+ printf("WTSQuerySessionInformation WTSClientBuildNumber failed: %" PRIu32 "\n",
+ GetLastError());
+ return -1;
+ }
+
+ ClientBuildNumber = *((ULONG*)pBuffer);
+ printf("\tWTSClientBuildNumber: %" PRIu32 "\n", ClientBuildNumber);
+
+ /* WTSClientName */
+
+ bSuccess = WTSQuerySessionInformationA(hServer, sessionId, WTSClientName, &pBuffer,
+ &bytesReturned);
+
+ if (!bSuccess)
+ {
+ printf("WTSQuerySessionInformation WTSClientName failed: %" PRIu32 "\n",
+ GetLastError());
+ return -1;
+ }
+
+ ClientName = (char*)pBuffer;
+ printf("\tWTSClientName: '%s'\n", ClientName);
+
+ /* WTSClientProductId */
+
+ bSuccess = WTSQuerySessionInformationA(hServer, sessionId, WTSClientProductId, &pBuffer,
+ &bytesReturned);
+
+ if (!bSuccess)
+ {
+ printf("WTSQuerySessionInformation WTSClientProductId failed: %" PRIu32 "\n",
+ GetLastError());
+ return -1;
+ }
+
+ ClientProductId = *((USHORT*)pBuffer);
+ printf("\tWTSClientProductId: %" PRIu16 "\n", ClientProductId);
+
+ /* WTSClientHardwareId */
+
+ bSuccess = WTSQuerySessionInformationA(hServer, sessionId, WTSClientHardwareId, &pBuffer,
+ &bytesReturned);
+
+ if (!bSuccess)
+ {
+ printf("WTSQuerySessionInformation WTSClientHardwareId failed: %" PRIu32 "\n",
+ GetLastError());
+ return -1;
+ }
+
+ ClientHardwareId = *((ULONG*)pBuffer);
+ printf("\tWTSClientHardwareId: %" PRIu32 "\n", ClientHardwareId);
+
+ /* WTSClientAddress */
+
+ bSuccess = WTSQuerySessionInformationA(hServer, sessionId, WTSClientAddress, &pBuffer,
+ &bytesReturned);
+
+ if (!bSuccess)
+ {
+ printf("WTSQuerySessionInformation WTSClientAddress failed: %" PRIu32 "\n",
+ GetLastError());
+ return -1;
+ }
+
+ ClientAddress = (PWTS_CLIENT_ADDRESS)pBuffer;
+ printf("\tWTSClientAddress: AddressFamily: %" PRIu32 " Address: ",
+ ClientAddress->AddressFamily);
+ for (DWORD i = 0; i < sizeof(ClientAddress->Address); i++)
+ printf("%02" PRIX8 "", ClientAddress->Address[i]);
+ printf("\n");
+
+ /* WTSClientDisplay */
+
+ bSuccess = WTSQuerySessionInformationA(hServer, sessionId, WTSClientDisplay, &pBuffer,
+ &bytesReturned);
+
+ if (!bSuccess)
+ {
+ printf("WTSQuerySessionInformation WTSClientDisplay failed: %" PRIu32 "\n",
+ GetLastError());
+ return -1;
+ }
+
+ ClientDisplay = (PWTS_CLIENT_DISPLAY)pBuffer;
+ printf("\tWTSClientDisplay: HorizontalResolution: %" PRIu32 " VerticalResolution: %" PRIu32
+ " ColorDepth: %" PRIu32 "\n",
+ ClientDisplay->HorizontalResolution, ClientDisplay->VerticalResolution,
+ ClientDisplay->ColorDepth);
+
+ /* WTSClientProtocolType */
+
+ bSuccess = WTSQuerySessionInformationA(hServer, sessionId, WTSClientProtocolType, &pBuffer,
+ &bytesReturned);
+
+ if (!bSuccess)
+ {
+ printf("WTSQuerySessionInformation WTSClientProtocolType failed: %" PRIu32 "\n",
+ GetLastError());
+ return -1;
+ }
+
+ ClientProtocolType = *((USHORT*)pBuffer);
+ printf("\tWTSClientProtocolType: %" PRIu16 "\n", ClientProtocolType);
+ }
+
+ WTSFreeMemory(pSessionInfo);
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiSessionNotification.c b/winpr/libwinpr/wtsapi/test/TestWtsApiSessionNotification.c
new file mode 100644
index 0000000..e83c27b
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiSessionNotification.c
@@ -0,0 +1,62 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+#include <winpr/environment.h>
+
+int TestWtsApiSessionNotification(int argc, char* argv[])
+{
+ HWND hWnd = NULL;
+ BOOL bSuccess = 0;
+ DWORD dwFlags = 0;
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+#ifndef _WIN32
+ if (!GetEnvironmentVariableA("WTSAPI_LIBRARY", NULL, 0))
+ {
+ printf("%s: No RDS environment detected, skipping test\n", __func__);
+ return 0;
+ }
+#else
+ /* We create a message-only window and use the predefined class name "STATIC" for simplicity */
+ hWnd = CreateWindowA("STATIC", "TestWtsApiSessionNotification", 0, 0, 0, 0, 0, HWND_MESSAGE,
+ NULL, NULL, NULL);
+ if (!hWnd)
+ {
+ printf("%s: error creating message-only window: %" PRIu32 "\n", __func__, GetLastError());
+ return -1;
+ }
+#endif
+
+ dwFlags = NOTIFY_FOR_ALL_SESSIONS;
+
+ bSuccess = WTSRegisterSessionNotification(hWnd, dwFlags);
+
+ if (!bSuccess)
+ {
+ printf("%s: WTSRegisterSessionNotification failed: %" PRIu32 "\n", __func__,
+ GetLastError());
+ return -1;
+ }
+
+ bSuccess = WTSUnRegisterSessionNotification(hWnd);
+
+#ifdef _WIN32
+ if (hWnd)
+ {
+ DestroyWindow(hWnd);
+ hWnd = NULL;
+ }
+#endif
+
+ if (!bSuccess)
+ {
+ printf("%s: WTSUnRegisterSessionNotification failed: %" PRIu32 "\n", __func__,
+ GetLastError());
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiShutdownSystem.c b/winpr/libwinpr/wtsapi/test/TestWtsApiShutdownSystem.c
new file mode 100644
index 0000000..431424b
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiShutdownSystem.c
@@ -0,0 +1,35 @@
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+#include <winpr/environment.h>
+
+int TestWtsApiShutdownSystem(int argc, char* argv[])
+{
+ BOOL bSuccess = 0;
+ HANDLE hServer = NULL;
+ DWORD ShutdownFlag = 0;
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+#ifndef _WIN32
+ if (!GetEnvironmentVariableA("WTSAPI_LIBRARY", NULL, 0))
+ {
+ printf("%s: No RDS environment detected, skipping test\n", __func__);
+ return 0;
+ }
+#endif
+
+ hServer = WTS_CURRENT_SERVER_HANDLE;
+ ShutdownFlag = WTS_WSD_SHUTDOWN;
+
+ bSuccess = WTSShutdownSystem(hServer, ShutdownFlag);
+
+ if (!bSuccess)
+ {
+ printf("WTSShutdownSystem failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/winpr/libwinpr/wtsapi/test/TestWtsApiWaitSystemEvent.c b/winpr/libwinpr/wtsapi/test/TestWtsApiWaitSystemEvent.c
new file mode 100644
index 0000000..389c0be
--- /dev/null
+++ b/winpr/libwinpr/wtsapi/test/TestWtsApiWaitSystemEvent.c
@@ -0,0 +1,39 @@
+
+#include <winpr/crt.h>
+#include <winpr/error.h>
+#include <winpr/wtsapi.h>
+#include <winpr/environment.h>
+
+int TestWtsApiWaitSystemEvent(int argc, char* argv[])
+{
+ BOOL bSuccess = 0;
+ HANDLE hServer = NULL;
+ DWORD eventMask = 0;
+ DWORD eventFlags = 0;
+
+ WINPR_UNUSED(argc);
+ WINPR_UNUSED(argv);
+
+#ifndef _WIN32
+ if (!GetEnvironmentVariableA("WTSAPI_LIBRARY", NULL, 0))
+ {
+ printf("%s: No RDS environment detected, skipping test\n", __func__);
+ return 0;
+ }
+#endif
+
+ hServer = WTS_CURRENT_SERVER_HANDLE;
+
+ eventMask = WTS_EVENT_ALL;
+ eventFlags = 0;
+
+ bSuccess = WTSWaitSystemEvent(hServer, eventMask, &eventFlags);
+
+ if (!bSuccess)
+ {
+ printf("WTSWaitSystemEvent failed: %" PRIu32 "\n", GetLastError());
+ return -1;
+ }
+
+ return 0;
+}