/* * PROJECT: ReactOS Tests * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) * PURPOSE: Tests some aspects of the Window Station API. * COPYRIGHT: Copyright 2018 Hermes Belusca-Maito */ #include #include #include #include #include #include "resource.h" /* * Logging facilities */ typedef struct _LOG_FILE { HANDLE hLogFile; PWCHAR pBuffer; size_t cbBufferSize; } LOG_FILE, *PLOG_FILE; BOOL InitLog( OUT PLOG_FILE LogFile, IN LPCWSTR LogFileName, IN PWCHAR pBuffer, IN size_t cbBufferSize) { HANDLE hLogFile; ZeroMemory(LogFile, sizeof(*LogFile)); hLogFile = CreateFileW(LogFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hLogFile == INVALID_HANDLE_VALUE) return FALSE; LogFile->hLogFile = hLogFile; LogFile->pBuffer = pBuffer; LogFile->cbBufferSize = cbBufferSize; return TRUE; } VOID CloseLog( IN PLOG_FILE LogFile) { CloseHandle(LogFile->hLogFile); ZeroMemory(LogFile, sizeof(*LogFile)); } BOOL WriteToLog( IN PLOG_FILE LogFile, IN LPCVOID Buffer, IN DWORD dwBufferSize) { return WriteFile(LogFile->hLogFile, Buffer, dwBufferSize, &dwBufferSize, NULL); } BOOL WriteToLogPuts( IN PLOG_FILE LogFile, IN LPCWSTR String) { return WriteToLog(LogFile, String, wcslen(String) * sizeof(WCHAR)); } BOOL WriteToLogPrintfV( IN PLOG_FILE LogFile, IN LPCWSTR Format, IN va_list args) { StringCbVPrintfW(LogFile->pBuffer, LogFile->cbBufferSize, Format, args); return WriteToLog(LogFile, LogFile->pBuffer, wcslen(LogFile->pBuffer) * sizeof(WCHAR)); } BOOL WriteToLogPrintf( IN PLOG_FILE LogFile, IN LPCWSTR Format, ...) { BOOL bRet; va_list args; va_start(args, Format); bRet = WriteToLogPrintfV(LogFile, Format, args); va_end(args); return bRet; } /* * Window Station tests */ BOOL CALLBACK EnumDesktopProc( IN LPWSTR lpszDesktop, IN LPARAM lParam) { PLOG_FILE LogFile = (PLOG_FILE)lParam; WriteToLogPrintf(LogFile, L" :: Found desktop '%s'\r\n", lpszDesktop); /* Continue the enumeration */ return TRUE; } /* * This test inspects the same window station aspects that are used in the * Cygwin fhandler_console.cc!fhandler_console::create_invisible_console() * function, see: * https://github.com/cygwin/cygwin/blob/7b9bfb4136f23655e243bab89fb62b04bdbacc7f/winsup/cygwin/fhandler_console.cc#L2494 */ VOID DoTest(HWND hWnd) { HWINSTA hWinSta; LPCWSTR lpszWinSta = L"Test-WinSta"; BOOL bIsItOk; LOG_FILE LogFile; WCHAR szBuffer[2048]; bIsItOk = InitLog(&LogFile, L"test_winsta.log", szBuffer, sizeof(szBuffer)); if (!bIsItOk) { MessageBoxW(hWnd, L"Could not create the log file, stopping test now...", L"Error", MB_ICONERROR | MB_OK); return; } /* Switch output to UTF-16 (little endian) */ WriteToLog(&LogFile, "\xFF\xFE", 2); WriteToLogPrintf(&LogFile, L"Creating Window Station '%s'\r\n", lpszWinSta); hWinSta = CreateWindowStationW(lpszWinSta, 0, WINSTA_ALL_ACCESS, NULL); WriteToLogPrintf(&LogFile, L"--> Returned handle 0x%p ; last error: %lu\r\n", hWinSta, GetLastError()); if (!hWinSta) { WriteToLogPuts(&LogFile, L"\r\nHandle is NULL, cannot proceed further, stopping the test!\r\n\r\n"); return; } WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (before process attach)\r\n", lpszWinSta, hWinSta); bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Setting current process to Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta); bIsItOk = SetProcessWindowStation(hWinSta); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (after process attach, before allocating console)\r\n", lpszWinSta, hWinSta); bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Allocating a new console on Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta); bIsItOk = AllocConsole(); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (after allocating console)\r\n", lpszWinSta, hWinSta); bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); WriteToLogPrintf(&LogFile, L"Now closing Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta); bIsItOk = CloseWindowStation(hWinSta); WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n\r\n", (bIsItOk ? L"success" : L"failure"), GetLastError()); CloseLog(&LogFile); } INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: DoTest(hDlg); EndDialog(hDlg, LOWORD(wParam)); break; case IDCANCEL: default: EndDialog(hDlg, LOWORD(wParam)); break; } return (INT_PTR)TRUE; } return (INT_PTR)FALSE; } int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); return DialogBoxW(hInstance, MAKEINTRESOURCEW(IDD_ABOUTBOX), NULL, About); }