mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
[KMTESTS]
- prepare the device object for being opened multiple times (required for communication with special-purpose drivers) - more verbose DPRINTs - implement utility functions for app<->driver communication - misc fixes svn path=/branches/GSoC_2011/KMTestSuite/; revision=52541
This commit is contained in:
parent
459f4ac630
commit
bf054095df
4 changed files with 93 additions and 42 deletions
|
@ -38,7 +38,14 @@ typedef struct
|
|||
CHAR LogBuffer[ANYSIZE_ARRAY];
|
||||
} KMT_RESULTBUFFER, *PKMT_RESULTBUFFER;
|
||||
|
||||
#if defined KMT_USER_MODE
|
||||
#ifdef KMT_KERNEL_MODE
|
||||
/* Device Extension layout */
|
||||
typedef struct
|
||||
{
|
||||
PKMT_RESULTBUFFER ResultBuffer;
|
||||
PMDL Mdl;
|
||||
} KMT_DEVICE_EXTENSION, *PKMT_DEVICE_EXTENSION;
|
||||
#elif defined KMT_USER_MODE
|
||||
VOID KmtLoadDriver(IN PCWSTR ServiceName, IN BOOLEAN RestartIfRunning);
|
||||
VOID KmtUnloadDriver(VOID);
|
||||
VOID KmtOpenDriver(VOID);
|
||||
|
@ -46,7 +53,7 @@ VOID KmtCloseDriver(VOID);
|
|||
|
||||
DWORD KmtSendToDriver(IN DWORD ControlCode);
|
||||
DWORD KmtSendStringToDriver(IN DWORD ControlCode, IN PCSTR String);
|
||||
DWORD KmtSendBufferToDriver(IN DWORD ControlCode, IN OUT PVOID Buffer, IN DWORD Length);
|
||||
DWORD KmtSendBufferToDriver(IN DWORD ControlCode, IN OUT PVOID Buffer, IN OUT PDWORD Length);
|
||||
#endif /* defined KMT_USER_MODE */
|
||||
|
||||
extern PKMT_RESULTBUFFER ResultBuffer;
|
||||
|
@ -95,6 +102,11 @@ BOOLEAN KmtSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, ...)
|
|||
#define ok_eq_str(value, expected) ok(!strcmp(value, expected), #value " = \"%s\", expected \"%s\"\n", value, expected)
|
||||
#define ok_eq_wstr(value, expected) ok(!wcscmp(value, expected), #value " = \"%ls\", expected \"%ls\"\n", value, expected)
|
||||
|
||||
#define KMT_MAKE_CODE(ControlCode) CTL_CODE(FILE_DEVICE_UNKNOWN, \
|
||||
0xA00 + (ControlCode), \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_ANY_ACCESS)
|
||||
|
||||
#if defined KMT_DEFINE_TEST_FUNCTIONS
|
||||
PKMT_RESULTBUFFER ResultBuffer = NULL;
|
||||
|
||||
|
@ -123,6 +135,9 @@ static VOID KmtAddToLogBuffer(PKMT_RESULTBUFFER Buffer, PCSTR String, SIZE_T Len
|
|||
LONG OldLength;
|
||||
LONG NewLength;
|
||||
|
||||
if (!Buffer)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
OldLength = Buffer->LogBufferLength;
|
||||
|
@ -199,6 +214,9 @@ VOID KmtFinishTest(PCSTR TestName)
|
|||
CHAR MessageBuffer[512];
|
||||
SIZE_T MessageLength;
|
||||
|
||||
if (!ResultBuffer)
|
||||
return;
|
||||
|
||||
MessageLength = KmtXSNPrintF(MessageBuffer, sizeof MessageBuffer, NULL, NULL,
|
||||
"%s: %ld tests executed (0 marked as todo, %ld failures), %ld skipped.\n",
|
||||
TestName,
|
||||
|
@ -213,6 +231,9 @@ VOID KmtVOk(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments)
|
|||
CHAR MessageBuffer[512];
|
||||
SIZE_T MessageLength;
|
||||
|
||||
if (!ResultBuffer)
|
||||
return;
|
||||
|
||||
if (Condition)
|
||||
{
|
||||
InterlockedIncrement(&ResultBuffer->Successes);
|
||||
|
@ -261,6 +282,9 @@ BOOLEAN KmtVSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Argumen
|
|||
CHAR MessageBuffer[512];
|
||||
SIZE_T MessageLength;
|
||||
|
||||
if (!ResultBuffer)
|
||||
return !Condition;
|
||||
|
||||
if (!Condition)
|
||||
{
|
||||
InterlockedIncrement(&ResultBuffer->Skipped);
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <strsafe.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kmtest.h"
|
||||
#include <winioctl.h>
|
||||
#include <kmt_public.h>
|
||||
#define KMT_DEFINE_TEST_FUNCTIONS
|
||||
#include <kmt_test.h>
|
||||
|
@ -187,7 +187,7 @@ OutputResult(
|
|||
KmtFinishTest(TestName);
|
||||
|
||||
if (!WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), ResultBuffer->LogBuffer, ResultBuffer->LogBufferLength, &BytesWritten, NULL))
|
||||
Error = GetLastError();
|
||||
error(Error);
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
@ -229,6 +229,7 @@ RunTest(
|
|||
error_goto(Error, cleanup);
|
||||
|
||||
cleanup:
|
||||
if (!Error)
|
||||
OutputResult(TestName);
|
||||
|
||||
KmtFreeResultBuffer(ResultBuffer);
|
||||
|
|
|
@ -9,20 +9,26 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <strsafe.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "kmtest.h"
|
||||
#include <kmt_test.h>
|
||||
#include <kmt_public.h>
|
||||
#include <kmt_test.h>
|
||||
|
||||
/* pseudo-tests */
|
||||
START_TEST(Create)
|
||||
{
|
||||
// nothing to do here. All tests start the service if needed
|
||||
// nothing to do here. All tests create the service if needed
|
||||
}
|
||||
|
||||
START_TEST(Delete)
|
||||
{
|
||||
// TODO: delete kmtest service
|
||||
SC_HANDLE Handle = NULL;
|
||||
DWORD Error = KmtDeleteService(L"Kmtest", &Handle);
|
||||
|
||||
ok_eq_hex(Error, (DWORD)ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
START_TEST(Start)
|
||||
|
@ -32,7 +38,14 @@ START_TEST(Start)
|
|||
|
||||
START_TEST(Stop)
|
||||
{
|
||||
// TODO: stop kmtest service
|
||||
// TODO: requiring the service to be started for this is... bad,
|
||||
// especially when it's marked for deletion and won't start ;)
|
||||
SC_HANDLE Handle = NULL;
|
||||
DWORD Error = KmtStopService(L"Kmtest", &Handle);
|
||||
|
||||
ok_eq_hex(Error, (DWORD)ERROR_SUCCESS);
|
||||
Error = KmtCloseService(&Handle);
|
||||
ok_eq_hex(Error, (DWORD)ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
/* test support functions for special-purpose drivers */
|
||||
|
@ -107,7 +120,7 @@ KmtOpenDriver(VOID)
|
|||
StringCbCopy(DevicePath, sizeof DevicePath, L"\\\\.\\Global\\GLOBALROOT\\Device\\");
|
||||
StringCbCat(DevicePath, sizeof DevicePath, TestServiceName);
|
||||
|
||||
TestDeviceHandle = CreateFile(KMTEST_DEVICE_PATH, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
TestDeviceHandle = CreateFile(DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (TestDeviceHandle == INVALID_HANDLE_VALUE)
|
||||
error(Error);
|
||||
|
||||
|
@ -139,8 +152,6 @@ KmtCloseDriver(VOID)
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO: check if these will be useful */
|
||||
|
||||
/**
|
||||
* @name KmtSendToDriver
|
||||
*
|
||||
|
@ -154,8 +165,12 @@ DWORD
|
|||
KmtSendToDriver(
|
||||
IN DWORD ControlCode)
|
||||
{
|
||||
// TODO
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
DWORD BytesRead;
|
||||
|
||||
if (!DeviceIoControl(TestDeviceHandle, KMT_MAKE_CODE(ControlCode), NULL, 0, NULL, 0, &BytesRead, NULL))
|
||||
return GetLastError();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,8 +188,12 @@ KmtSendStringToDriver(
|
|||
IN DWORD ControlCode,
|
||||
IN PCSTR String)
|
||||
{
|
||||
// TODO
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
DWORD BytesRead;
|
||||
|
||||
if (!DeviceIoControl(TestDeviceHandle, KMT_MAKE_CODE(ControlCode), (PVOID)String, strlen(String), NULL, 0, &BytesRead, NULL))
|
||||
return GetLastError();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,8 +209,12 @@ DWORD
|
|||
KmtSendBufferToDriver(
|
||||
IN DWORD ControlCode,
|
||||
IN OUT PVOID Buffer,
|
||||
IN DWORD Length)
|
||||
IN OUT PDWORD Length)
|
||||
{
|
||||
// TODO
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
assert(Length);
|
||||
|
||||
if (!DeviceIoControl(TestDeviceHandle, KMT_MAKE_CODE(ControlCode), Buffer, *Length, NULL, 0, Length, NULL))
|
||||
return GetLastError();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
|
@ -24,13 +24,6 @@ static DRIVER_DISPATCH DriverCreate;
|
|||
static DRIVER_DISPATCH DriverClose;
|
||||
static DRIVER_DISPATCH DriverIoControl;
|
||||
|
||||
/* Device Extension layout */
|
||||
typedef struct
|
||||
{
|
||||
PKMT_RESULTBUFFER ResultBuffer;
|
||||
PMDL Mdl;
|
||||
} KMT_DEVICE_EXTENSION, *PKMT_DEVICE_EXTENSION;
|
||||
|
||||
/* Globals */
|
||||
static PDEVICE_OBJECT MainDeviceObject;
|
||||
|
||||
|
@ -68,13 +61,13 @@ DriverEntry(
|
|||
&DeviceName,
|
||||
FILE_DEVICE_UNKNOWN,
|
||||
FILE_DEVICE_SECURE_OPEN | FILE_READ_ONLY_DEVICE,
|
||||
TRUE, &MainDeviceObject);
|
||||
FALSE, &MainDeviceObject);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto cleanup;
|
||||
|
||||
DPRINT("DriverEntry. Created DeviceObject %p\n",
|
||||
MainDeviceObject);
|
||||
DPRINT("DriverEntry. Created DeviceObject %p. DeviceExtension %p\n",
|
||||
MainDeviceObject, MainDeviceObject->DeviceExtension);
|
||||
DeviceExtension = MainDeviceObject->DeviceExtension;
|
||||
DeviceExtension->ResultBuffer = NULL;
|
||||
DeviceExtension->Mdl = NULL;
|
||||
|
@ -146,19 +139,14 @@ DriverCreate(
|
|||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PIO_STACK_LOCATION IoStackLocation;
|
||||
PKMT_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
DPRINT("DriverCreate. DeviceObject=%p\n",
|
||||
DeviceObject);
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
ASSERT(!DeviceExtension->Mdl);
|
||||
ASSERT(!DeviceExtension->ResultBuffer);
|
||||
ASSERT(!ResultBuffer);
|
||||
DPRINT("DriverCreate. DeviceObject=%p, RequestorMode=%d, FileObject=%p, FsContext=%p, FsContext2=%p\n",
|
||||
DeviceObject, Irp->RequestorMode, IoStackLocation->FileObject,
|
||||
IoStackLocation->FileObject->FsContext, IoStackLocation->FileObject->FsContext2);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
@ -195,17 +183,23 @@ DriverClose(
|
|||
|
||||
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
DPRINT("DriverClose. DeviceObject=%p\n",
|
||||
DeviceObject);
|
||||
DPRINT("DriverClose. DeviceObject=%p, RequestorMode=%d, FileObject=%p, FsContext=%p, FsContext2=%p\n",
|
||||
DeviceObject, Irp->RequestorMode, IoStackLocation->FileObject,
|
||||
IoStackLocation->FileObject->FsContext, IoStackLocation->FileObject->FsContext2);
|
||||
|
||||
ASSERT(IoStackLocation->FileObject->FsContext2 == NULL);
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
if (DeviceExtension->Mdl)
|
||||
if (DeviceExtension->Mdl && IoStackLocation->FileObject->FsContext == DeviceExtension->Mdl)
|
||||
{
|
||||
MmUnlockPages(DeviceExtension->Mdl);
|
||||
IoFreeMdl(DeviceExtension->Mdl);
|
||||
DeviceExtension->Mdl = NULL;
|
||||
ResultBuffer = DeviceExtension->ResultBuffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(IoStackLocation->FileObject->FsContext == NULL);
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
@ -242,9 +236,10 @@ DriverIoControl(
|
|||
|
||||
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
DPRINT("DriverIoControl. Code=0x%08X, DeviceObject=%p\n",
|
||||
DPRINT("DriverIoControl. Code=0x%08X, DeviceObject=%p, FileObject=%p, FsContext=%p, FsContext2=%p\n",
|
||||
IoStackLocation->Parameters.DeviceIoControl.IoControlCode,
|
||||
DeviceObject);
|
||||
DeviceObject, IoStackLocation->FileObject,
|
||||
IoStackLocation->FileObject->FsContext, IoStackLocation->FileObject->FsContext2);
|
||||
|
||||
switch (IoStackLocation->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
|
@ -315,8 +310,15 @@ DriverIoControl(
|
|||
|
||||
if (DeviceExtension->Mdl)
|
||||
{
|
||||
if (IoStackLocation->FileObject->FsContext != DeviceExtension->Mdl)
|
||||
{
|
||||
Status = STATUS_ACCESS_DENIED;
|
||||
break;
|
||||
}
|
||||
MmUnlockPages(DeviceExtension->Mdl);
|
||||
IoFreeMdl(DeviceExtension->Mdl);
|
||||
IoStackLocation->FileObject->FsContext = NULL;
|
||||
ResultBuffer = DeviceExtension->ResultBuffer = NULL;
|
||||
}
|
||||
|
||||
DeviceExtension->Mdl = IoAllocateMdl(IoStackLocation->Parameters.DeviceIoControl.Type3InputBuffer,
|
||||
|
@ -341,6 +343,7 @@ DriverIoControl(
|
|||
} _SEH2_END;
|
||||
|
||||
ResultBuffer = DeviceExtension->ResultBuffer = MmGetSystemAddressForMdlSafe(DeviceExtension->Mdl, NormalPagePriority);
|
||||
IoStackLocation->FileObject->FsContext = DeviceExtension->Mdl;
|
||||
|
||||
DPRINT("DriverIoControl. ResultBuffer: %ld %ld %ld %ld\n",
|
||||
ResultBuffer->Successes, ResultBuffer->Failures,
|
||||
|
|
Loading…
Reference in a new issue