mirror of
https://github.com/reactos/reactos.git
synced 2024-11-01 20:32:36 +00:00
240 lines
6.6 KiB
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);
|
||
|
}
|