mirror of
https://github.com/reactos/reactos.git
synced 2024-08-04 10:30:59 +00:00
198 lines
4.7 KiB
C
198 lines
4.7 KiB
C
![]() |
/*
|
||
|
* PROJECT: ReactOS kernel-mode tests
|
||
|
* LICENSE: GPLv2+ - See COPYING in the top level directory
|
||
|
* PURPOSE: Kernel-Mode Test Suite Loader Application
|
||
|
* PROGRAMMER: Thomas Faber <thfabba@gmx.de>
|
||
|
*/
|
||
|
|
||
|
#define UNICODE
|
||
|
#include <windows.h>
|
||
|
#include <strsafe.h>
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#include "kmtest.h"
|
||
|
#include <winioctl.h>
|
||
|
#include <kmt_public.h>
|
||
|
|
||
|
static void OutputError(FILE *fp, DWORD error);
|
||
|
static DWORD RunTest(char *testName);
|
||
|
static DWORD ListTests(PSTR *testList);
|
||
|
int __cdecl main(int argc, char **argv);
|
||
|
|
||
|
static void OutputError(FILE *fp, DWORD error)
|
||
|
{
|
||
|
char *message;
|
||
|
if (!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
||
|
NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&message, 0, NULL))
|
||
|
{
|
||
|
fprintf(fp, "Could not retrieve error message (error 0x%08lx). Original error: 0x%08lx\n", GetLastError(), error);
|
||
|
}
|
||
|
|
||
|
fprintf(fp, "%s\n", message);
|
||
|
|
||
|
LocalFree(message);
|
||
|
}
|
||
|
|
||
|
static DWORD RunTest(char *testName)
|
||
|
{
|
||
|
DWORD error = ERROR_SUCCESS;
|
||
|
HANDLE hDevice = INVALID_HANDLE_VALUE;
|
||
|
DWORD bytesRead;
|
||
|
char buffer[1024];
|
||
|
BOOL ret;
|
||
|
|
||
|
hDevice = CreateFile(KMTEST_DEVICE_PATH, GENERIC_READ | GENERIC_WRITE, 0,
|
||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||
|
|
||
|
if (hDevice == INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
error = GetLastError();
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
if (!DeviceIoControl(hDevice, IOCTL_KMTEST_RUN_TEST, testName, strlen(testName), NULL, 0, &bytesRead, NULL))
|
||
|
{
|
||
|
error = GetLastError();
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
while ((ret = ReadFile(hDevice, buffer, sizeof buffer - 1, &bytesRead, NULL)) != 0)
|
||
|
{
|
||
|
if (!bytesRead)
|
||
|
break;
|
||
|
|
||
|
assert(bytesRead < sizeof buffer);
|
||
|
buffer[bytesRead] = '\0';
|
||
|
|
||
|
fputs(buffer, stdout);
|
||
|
}
|
||
|
if (!ret)
|
||
|
{
|
||
|
error = GetLastError();
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
cleanup:
|
||
|
if (hDevice != INVALID_HANDLE_VALUE)
|
||
|
CloseHandle(hDevice);
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
static DWORD ListTests(PSTR *testList)
|
||
|
{
|
||
|
DWORD error = ERROR_SUCCESS;
|
||
|
HANDLE hDevice = INVALID_HANDLE_VALUE;
|
||
|
DWORD bytesRead;
|
||
|
PSTR buffer = NULL;
|
||
|
DWORD bufferSize;
|
||
|
|
||
|
if (!testList)
|
||
|
{
|
||
|
error = ERROR_INVALID_PARAMETER;
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
hDevice = CreateFile(KMTEST_DEVICE_PATH, GENERIC_READ | GENERIC_WRITE, 0,
|
||
|
NULL, OPEN_EXISTING, 0, NULL);
|
||
|
|
||
|
if (hDevice == INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
error = GetLastError();
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
bufferSize = 1024;
|
||
|
buffer = HeapAlloc(GetProcessHeap(), 0, bufferSize);
|
||
|
if (!buffer)
|
||
|
{
|
||
|
error = GetLastError();
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
if (!DeviceIoControl(hDevice, IOCTL_KMTEST_GET_TESTS, NULL, 0, buffer, bufferSize, &bytesRead, NULL))
|
||
|
{
|
||
|
error = GetLastError();
|
||
|
goto cleanup;
|
||
|
}
|
||
|
|
||
|
cleanup:
|
||
|
if (buffer && error)
|
||
|
{
|
||
|
HeapFree(GetProcessHeap(), 0, buffer);
|
||
|
buffer = NULL;
|
||
|
}
|
||
|
|
||
|
if (hDevice != INVALID_HANDLE_VALUE)
|
||
|
CloseHandle(hDevice);
|
||
|
|
||
|
if (testList)
|
||
|
*testList = buffer;
|
||
|
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
int __cdecl main(int argc, char **argv)
|
||
|
{
|
||
|
int status = EXIT_SUCCESS;
|
||
|
DWORD error;
|
||
|
|
||
|
if (argc <= 1)
|
||
|
{
|
||
|
/* no arguments: show usage and list tests */
|
||
|
char *programName = argc == 0 ? "kmtest" : argv[0];
|
||
|
char *testNames, *testName;
|
||
|
size_t len;
|
||
|
|
||
|
printf("Usage: %s test_name\n", programName);
|
||
|
puts("\nValid test names:");
|
||
|
puts(" Create");
|
||
|
puts(" Start");
|
||
|
puts(" Stop");
|
||
|
puts(" Delete");
|
||
|
|
||
|
error = ListTests(&testNames);
|
||
|
testName = testNames;
|
||
|
|
||
|
while ((len = strlen(testName)) != 0)
|
||
|
{
|
||
|
printf(" %s\n", testName);
|
||
|
testName += len + 1;
|
||
|
}
|
||
|
|
||
|
/* TODO: user-mode test parts */
|
||
|
|
||
|
if (error)
|
||
|
OutputError(stdout, error);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
char *testName = argv[1];
|
||
|
|
||
|
if (argc > 2)
|
||
|
fputs("Excess arguments ignored\n", stderr);
|
||
|
|
||
|
if (!lstrcmpiA(testName, "create"))
|
||
|
error = Service_Control(Service_Create);
|
||
|
else if (!lstrcmpiA(testName, "delete"))
|
||
|
error = Service_Control(Service_Delete);
|
||
|
else if (!lstrcmpiA(testName, "start"))
|
||
|
error = Service_Control(Service_Start);
|
||
|
else if (!lstrcmpiA(testName, "stop"))
|
||
|
error = Service_Control(Service_Stop);
|
||
|
else
|
||
|
/* TODO: user-mode test parts */
|
||
|
error = RunTest(testName);
|
||
|
|
||
|
OutputError(stdout, error);
|
||
|
}
|
||
|
|
||
|
if (error)
|
||
|
status = EXIT_FAILURE;
|
||
|
|
||
|
return status;
|
||
|
}
|