From bf054095dfd90ed4636a3273361ee5711d47c298 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Mon, 4 Jul 2011 19:47:49 +0000 Subject: [PATCH] [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 --- kmtests/include/kmt_test.h | 28 ++++++++++++++++-- kmtests/kmtest/kmtest.c | 7 +++-- kmtests/kmtest/support.c | 51 ++++++++++++++++++++++++--------- kmtests/kmtest_drv/kmtest_drv.c | 49 ++++++++++++++++--------------- 4 files changed, 93 insertions(+), 42 deletions(-) diff --git a/kmtests/include/kmt_test.h b/kmtests/include/kmt_test.h index b04927b3ba6..b43c78f492a 100644 --- a/kmtests/include/kmt_test.h +++ b/kmtests/include/kmt_test.h @@ -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); diff --git a/kmtests/kmtest/kmtest.c b/kmtests/kmtest/kmtest.c index 2ca7ce50a19..0f8e9204deb 100644 --- a/kmtests/kmtest/kmtest.c +++ b/kmtests/kmtest/kmtest.c @@ -9,13 +9,13 @@ #define WIN32_LEAN_AND_MEAN #include #include +#include #include #include #include #include "kmtest.h" -#include #include #define KMT_DEFINE_TEST_FUNCTIONS #include @@ -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,7 +229,8 @@ RunTest( error_goto(Error, cleanup); cleanup: - OutputResult(TestName); + if (!Error) + OutputResult(TestName); KmtFreeResultBuffer(ResultBuffer); diff --git a/kmtests/kmtest/support.c b/kmtests/kmtest/support.c index 8ddabddd214..f495cf9a9ef 100644 --- a/kmtests/kmtest/support.c +++ b/kmtests/kmtest/support.c @@ -9,20 +9,26 @@ #define WIN32_LEAN_AND_MEAN #include #include +#include + +#include #include "kmtest.h" -#include #include +#include /* 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; } \ No newline at end of file diff --git a/kmtests/kmtest_drv/kmtest_drv.c b/kmtests/kmtest_drv/kmtest_drv.c index f50feb1ccac..be595f219ce 100644 --- a/kmtests/kmtest_drv/kmtest_drv.c +++ b/kmtests/kmtest_drv/kmtest_drv.c @@ -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,