reactos/modules/rostests/win32/user32/winstation/winstation.c

240 lines
6.6 KiB
C

/*
* 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 <windef.h>
#include <winbase.h>
#include <wincon.h>
#include <winuser.h>
#include <strsafe.h>
#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);
}