Author: mjmartin
Date: Thu Jun 11 18:13:11 2009
New Revision: 41381
URL:
http://svn.reactos.org/svn/reactos?rev=41381&view=rev
Log:
- FinishTest: Modify DbgPrint to match format of winetests.
- Added basic tests for DriverObject, DeviceObject and Loading/Unloading of drivers.
- Added kmtestassist to be used for testing Attached DeviceObject.
- Added CreateLowerDeviceRegistryKey to manually create volatile registry entry for
kmtestassist driver.
- More tests still need to be implemented and still need a user mode application to
control kmtest.
Added:
trunk/rostests/drivers/kmtest/devobj_test.c (with props)
trunk/rostests/drivers/kmtest/drvobj_test.c (with props)
trunk/rostests/drivers/kmtest/kmtestassist.c (with props)
trunk/rostests/drivers/kmtest/kmtestassist.rbuild (with props)
trunk/rostests/drivers/kmtest/reghelper.c (with props)
Modified:
trunk/rostests/drivers/directory.rbuild
trunk/rostests/drivers/kmtest/kmtest.c
trunk/rostests/drivers/kmtest/kmtest.h
trunk/rostests/drivers/kmtest/kmtest.rbuild
Modified: trunk/rostests/drivers/directory.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/drivers/directory.rbuild?…
==============================================================================
--- trunk/rostests/drivers/directory.rbuild [iso-8859-1] (original)
+++ trunk/rostests/drivers/directory.rbuild [iso-8859-1] Thu Jun 11 18:13:11 2009
@@ -7,6 +7,9 @@
<directory name="kmtest">
<xi:include href="kmtest/kmtest.rbuild" />
</directory>
+ <directory name="kmtest">
+ <xi:include href="kmtest/kmtestassist.rbuild" />
+ </directory>
<directory name="memtest">
<xi:include href="memtest/memtest.rbuild" />
</directory>
Added: trunk/rostests/drivers/kmtest/devobj_test.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/drivers/kmtest/devobj_tes…
==============================================================================
--- trunk/rostests/drivers/kmtest/devobj_test.c (added)
+++ trunk/rostests/drivers/kmtest/devobj_test.c [iso-8859-1] Thu Jun 11 18:13:11 2009
@@ -1,0 +1,266 @@
+/*
+ * Driver Regression Tests
+ *
+ * Copyright 2009 Michael Martin <martinmnet(a)hotmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; see the file COPYING.LIB.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "kmtest.h"
+#include <ddk/ntddk.h>
+#include <ddk/ntifs.h>
+#include "ntddser.h"
+#include "ntndk.h"
+
+VOID LowerDeviceKernelAPITest(PDEVICE_OBJECT DeviceObject, BOOLEAN UnLoading)
+{
+ PDEVICE_OBJECT RetObject;
+
+ RetObject = IoGetLowerDeviceObject(DeviceObject);
+
+ if (UnLoading)
+ {
+ ok(RetObject == 0,
+ "Expected no Lower DeviceObject, got %p", RetObject);
+ }
+ else
+ {
+ ok(RetObject == AttachDeviceObject,
+ "Expected an Attached DeviceObject %p, got %p", AttachDeviceObject,
RetObject);
+ }
+
+ if (RetObject)
+ {
+ ObDereferenceObject(RetObject);
+ }
+
+ RetObject = IoGetDeviceAttachmentBaseRef(DeviceObject);
+ ok(RetObject == DeviceObject,
+ "Expected an Attached DeviceObject %p, got %p", DeviceObject,
RetObject);
+
+ if (RetObject)
+ {
+ ObDereferenceObject(RetObject);
+ }
+
+}
+VOID DeviceCreatedTest(PDEVICE_OBJECT DeviceObject, BOOLEAN ExclusiveAccess)
+{
+ PEXTENDED_DEVOBJ_EXTENSION extdev;
+
+ /*Check the device object members */
+ ok(DeviceObject->Type==3, "Expected Type = 3, got %x",
DeviceObject->Type);
+ ok(DeviceObject->Size = 0xb8, "Expected Size = 0xba, got %x",
DeviceObject->Size);
+ ok(DeviceObject->ReferenceCount == 0, "Expected ReferenceCount = 0, got
%lu",
+ DeviceObject->ReferenceCount);
+ ok(DeviceObject->DriverObject == ThisDriverObject,
+ "Expected DriverObject member to match this DriverObject %p, got %p",
+ ThisDriverObject, DeviceObject->DriverObject);
+ ok(DeviceObject->NextDevice == NULL, "Expected NextDevice to be NULL, got
%p", DeviceObject->NextDevice);
+ ok(DeviceObject->AttachedDevice == NULL, "Expected AttachDevice to be NULL,
got %p", DeviceObject->AttachedDevice);
+ ok(DeviceObject->Characteristics == 0, "Expected Characteristics to be
0");
+ if (ExclusiveAccess)
+ {
+ ok((DeviceObject->Flags == (DO_DEVICE_HAS_NAME | DO_DEVICE_INITIALIZING |
DO_EXCLUSIVE)),
+ "Expected Flags DO_DEVICE_HAS_NAME | DO_DEVICE_INITIALIZING |
DO_EXCLUSIVE, got %lu", DeviceObject->Flags);
+ }
+ else
+ {
+ ok((DeviceObject->Flags == (DO_DEVICE_HAS_NAME | DO_DEVICE_INITIALIZING)),
+ "Expected Flags DO_DEVICE_HAS_NAME | DO_DEVICE_INITIALIZING, got
%lu", DeviceObject->Flags);
+ }
+ ok(DeviceObject->DeviceType == FILE_DEVICE_UNKNOWN,
+ "Expected DeviceType to match creation parameter FILE_DEVICE_UNKNWOWN, got
%lu",
+ DeviceObject->DeviceType);
+ ok(DeviceObject->ActiveThreadCount == 0, "Expected ActiveThreadCount = 0, got
%lu\n", DeviceObject->ActiveThreadCount);
+
+ /*Check the extended extension */
+ extdev = (PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension;
+ ok(extdev->ExtensionFlags == 0, "Expected Extended ExtensionFlags to be 0,
got %lu", extdev->ExtensionFlags);
+ ok (extdev->Type == 13, "Expected Type of 13, got %d",
extdev->Type);
+ ok (extdev->Size == 0, "Expected Size of 0, got %d", extdev->Size);
+ ok (extdev->DeviceObject == DeviceObject, "Expected DeviceOject to match
newly created device %p, got %p",
+ DeviceObject, extdev->DeviceObject);
+ ok(extdev->AttachedTo == NULL, "Expected AttachTo to be NULL, got %p",
extdev->AttachedTo);
+ ok(extdev->StartIoCount == 0, "Expected StartIoCount = 0, got %lu",
extdev->StartIoCount);
+ ok(extdev->StartIoKey == 0, "Expected StartIoKey = 0, got %lu",
extdev->StartIoKey);
+ ok(extdev->StartIoFlags == 0, "Expected StartIoFlags = 0, got %lu",
extdev->StartIoFlags);
+}
+
+VOID DeviceDeletionTest(PDEVICE_OBJECT DeviceObject, BOOLEAN Lower)
+{
+ PEXTENDED_DEVOBJ_EXTENSION extdev;
+
+ /*Check the device object members */
+ ok(DeviceObject->Type==3, "Expected Type = 3, got %d",
DeviceObject->Type);
+ ok(DeviceObject->Size = 0xb8, "Expected Size = 0xba, got %d",
DeviceObject->Size);
+ ok(DeviceObject->ReferenceCount == 0, "Expected ReferenceCount = 0, got
%lu",
+ DeviceObject->ReferenceCount);
+ if (!Lower)
+ {
+ ok(DeviceObject->DriverObject == ThisDriverObject,
+ "Expected DriverObject member to match this DriverObject %p, got
%p",
+ ThisDriverObject, DeviceObject->DriverObject);
+ }
+ ok(DeviceObject->NextDevice == NULL, "Expected NextDevice to be NULL, got
%p", DeviceObject->NextDevice);
+
+ if (Lower)
+ {
+ ok(DeviceObject->AttachedDevice == MainDeviceObject,
+ "Expected AttachDevice to be %p, got %p", MainDeviceObject,
DeviceObject->AttachedDevice);
+ }
+ else
+ {
+ ok(DeviceObject->AttachedDevice == NULL, "Expected AttachDevice to be
NULL, got %p", DeviceObject->AttachedDevice);
+ }
+
+ ok(DeviceObject->Flags ==FILE_VIRTUAL_VOLUME,
+ "Expected Flags FILE_VIRTUAL_VOLUME, got %lu",
DeviceObject->Flags);
+ ok(DeviceObject->DeviceType == FILE_DEVICE_UNKNOWN,
+ "Expected DeviceType to match creation parameter FILE_DEVICE_UNKNWOWN, got
%lu",
+ DeviceObject->DeviceType);
+ ok(DeviceObject->ActiveThreadCount == 0, "Expected ActiveThreadCount = 0, got
%lu\n", DeviceObject->ActiveThreadCount);
+
+ /*Check the extended extension */
+ extdev = (PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension;
+ ok(extdev->ExtensionFlags == DOE_UNLOAD_PENDING,
+ "Expected Extended ExtensionFlags to be DOE_UNLOAD_PENDING, got %lu",
extdev->ExtensionFlags);
+ ok (extdev->Type == 13, "Expected Type of 13, got %d",
extdev->Type);
+ ok (extdev->Size == 0, "Expected Size of 0, got %d", extdev->Size);
+ ok (extdev->DeviceObject == DeviceObject, "Expected DeviceOject to match
newly created device %p, got %p",
+ DeviceObject, extdev->DeviceObject);
+ if (Lower)
+ {
+ /* Skip this for now */
+ //ok(extdev->AttachedTo == MainDeviceObject, "Expected AttachTo to %p,
got %p", MainDeviceObject, extdev->AttachedTo);
+ }
+ else
+ {
+ ok(extdev->AttachedTo == NULL, "Expected AttachTo to be NULL, got
%p", extdev->AttachedTo);
+ }
+ ok(extdev->StartIoCount == 0, "Expected StartIoCount = 0, got %lu",
extdev->StartIoCount);
+ ok(extdev->StartIoKey == 0, "Expected StartIoKey = 0, got %lu",
extdev->StartIoKey);
+ ok(extdev->StartIoFlags == 0, "Expected StartIoFlags = 0, got %lu",
extdev->StartIoFlags);
+}
+
+VOID DeviceCreateDeleteTest(PDRIVER_OBJECT DriverObject)
+{
+ NTSTATUS Status;
+ UNICODE_STRING DeviceString;
+ UNICODE_STRING DosDeviceString;
+ PDEVICE_OBJECT DeviceObject;
+
+ /* Create using wrong directory */
+ RtlInitUnicodeString(&DeviceString, L"\\Device1\\Kmtest");
+ Status = IoCreateDevice(DriverObject,
+ 0,
+ &DeviceString,
+ FILE_DEVICE_UNKNOWN,
+ 0,
+ FALSE,
+ &DeviceObject);
+ ok(Status == STATUS_OBJECT_PATH_NOT_FOUND, "Expected
STATUS_OBJECT_PATH_NOT_FOUND, got 0x%lX", Status);
+
+ /* Create using correct params with exlusice access */
+ RtlInitUnicodeString(&DeviceString, L"\\Device\\Kmtest");
+ Status = IoCreateDevice(DriverObject,
+ 0,
+ &DeviceString,
+ FILE_DEVICE_UNKNOWN,
+ 0,
+ TRUE,
+ &DeviceObject);
+ ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX",
Status);
+
+ DeviceCreatedTest(DeviceObject, TRUE);
+
+ /* Delete the device */
+ if (NT_SUCCESS(Status))
+ {
+ IoDeleteDevice(DeviceObject);
+ ok(DriverObject->DeviceObject == 0, "Expected
DriverObject->DeviceObject to be NULL, got %p",
+ DriverObject->DeviceObject);
+ }
+
+ /* Create using correct params with exlusice access */
+ Status = IoCreateDevice(DriverObject,
+ 0,
+ &DeviceString,
+ FILE_DEVICE_UNKNOWN,
+ 0,
+ FALSE,
+ &DeviceObject);
+ ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX",
Status);
+
+ DeviceCreatedTest(DeviceObject, FALSE);
+
+ /* Delete the device */
+ if (NT_SUCCESS(Status))
+ {
+ IoDeleteDevice(DeviceObject);
+ ok(DriverObject->DeviceObject == 0, "Expected
DriverObject->DeviceObject to be NULL, got %p",
+ DriverObject->DeviceObject);
+ }
+
+ /* Recreate device */
+ Status = IoCreateDevice(DriverObject,
+ 0,
+ &DeviceString,
+ FILE_DEVICE_UNKNOWN,
+ 0,
+ FALSE,
+ &DeviceObject);
+ ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX",
Status);
+
+ RtlInitUnicodeString(&DosDeviceString, L"\\DosDevices\\kmtest");
+ Status = IoCreateSymbolicLink(&DosDeviceString, &DeviceString);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* Delete device object if not successful */
+ IoDeleteDevice(DeviceObject);
+ return;
+ }
+
+ MainDeviceObject = DeviceObject;
+
+ return;
+}
+
+BOOLEAN AttachDeviceTest(PDEVICE_OBJECT DeviceObject, PWCHAR NewDriverRegPath)
+{
+ NTSTATUS Status;
+ UNICODE_STRING LowerDeviceName;
+
+ RtlInitUnicodeString(&LowerDeviceName, NewDriverRegPath);
+ Status = IoAttachDevice(DeviceObject, &LowerDeviceName,
&AttachDeviceObject);
+
+ /* TODO: Add more tests */
+
+ return TRUE;
+}
+
+BOOLEAN DetachDeviceTest(PDEVICE_OBJECT AttachedDevice)
+{
+
+ IoDetachDevice(AttachedDevice);
+
+ /* TODO: Add more tests */
+
+ return TRUE;
+}
Propchange: trunk/rostests/drivers/kmtest/devobj_test.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rostests/drivers/kmtest/drvobj_test.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/drivers/kmtest/drvobj_tes…
==============================================================================
--- trunk/rostests/drivers/kmtest/drvobj_test.c (added)
+++ trunk/rostests/drivers/kmtest/drvobj_test.c [iso-8859-1] Thu Jun 11 18:13:11 2009
@@ -1,0 +1,141 @@
+/*
+ * Driver Regression Tests
+ *
+ * Copyright 2009 Michael Martin <martinmnet(a)hotmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; see the file COPYING.LIB.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "kmtest.h"
+#include <ddk/ntddk.h>
+#include <ddk/ntifs.h>
+
+VOID DriverObjectTest(PDRIVER_OBJECT DriverObject, int DriverStatus)
+{
+ BOOLEAN CheckThisDispatchRoutine;
+ PVOID FirstMajorFunc;
+ int i;
+
+ ok(DriverObject->Size == sizeof(DRIVER_OBJECT), "Size does not match, got
%x",DriverObject->Size);
+ ok(DriverObject->Type == 4, "Type does not match 4. got
%d",DriverObject->Type);
+
+ if (DriverStatus == 0)
+ {
+ ok(DriverObject->DeviceObject == NULL, "Expected DeviceObject pointer to
be 0, got %p",
+ DriverObject->DeviceObject);
+ ok (DriverObject->Flags == DRVO_LEGACY_DRIVER,
+ "Expected Flags to be DRVO_LEGACY_DRIVER, got %lu",
+ DriverObject->Flags);
+ }
+ else if (DriverStatus == 1)
+ {
+ ok(DriverObject->DeviceObject != NULL, "Expected DeviceObject pointer to
non null");
+ ok (DriverObject->Flags == (DRVO_LEGACY_DRIVER | DRVO_INITIALIZED),
+ "Expected Flags to be DRVO_LEGACY_DRIVER | DRVO_INITIALIZED, got
%lu",
+ DriverObject->Flags);
+ }
+ else
+ {
+ ok(DriverObject->DeviceObject != NULL, "Expected DeviceObject pointer to
non null");
+ ok (DriverObject->Flags == (DRVO_LEGACY_DRIVER | DRVO_INITIALIZED |
DRVO_UNLOAD_INVOKED),
+ "Expected Flags to be DRVO_LEGACY_DRIVER | DRVO_INITIALIZED |
DRVO_UNLOAD_INVOKED, got %lu",
+ DriverObject->Flags);
+ }
+
+ /* Select a routine that was not changed */
+ FirstMajorFunc = DriverObject->MajorFunction[1];
+ ok(FirstMajorFunc != 0, "Expected MajorFunction[1] to be non NULL");
+
+ if (FirstMajorFunc)
+ {
+ for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
+ {
+ if (DriverStatus > 0) CheckThisDispatchRoutine = (i > 3) && (i
!= 14);
+ else CheckThisDispatchRoutine = TRUE;
+
+ if (CheckThisDispatchRoutine)
+ {
+ ok(DriverObject->MajorFunction[i] == FirstMajorFunc, "Expected
MajorFunction[%d] to match %p",
+ i, FirstMajorFunc);
+ }
+ }
+ }
+ else
+ {
+ ok(TRUE, "Skipped testing for all MajorFunction");
+ }
+}
+
+BOOLEAN ZwLoadTest(PDRIVER_OBJECT DriverObject, PUNICODE_STRING DriverRegistryPath,
PWCHAR NewDriverRegPath)
+{
+ UNICODE_STRING RegPath;
+ NTSTATUS Status;
+
+ /* Try to load ourself */
+ Status = ZwLoadDriver(DriverRegistryPath);
+ ok (Status == STATUS_IMAGE_ALREADY_LOADED, "Expected NTSTATUS
STATUS_IMAGE_ALREADY_LOADED, got 0x%lX", Status);
+
+ if (Status != STATUS_IMAGE_ALREADY_LOADED)
+ {
+ DbgPrint("WARNING: Loading this a second time will cause
BUGCHECK!\n");
+ }
+
+ /* Try to load with a Registry Path that doesnt exist */
+ RtlInitUnicodeString(&RegPath,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\deadbeef");
+ Status = ZwLoadDriver(&RegPath);
+ ok (Status == STATUS_OBJECT_NAME_NOT_FOUND, "Expected NTSTATUS
STATUS_OBJECT_NAME_NOT_FOUND, got 0x%lX", Status);
+
+ /* Load the driver */
+ RtlInitUnicodeString(&RegPath, NewDriverRegPath);
+ Status = ZwLoadDriver(&RegPath);
+ ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX",
Status);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOLEAN ZwUnloadTest(PDRIVER_OBJECT DriverObject, PUNICODE_STRING DriverRegistryPath,
PWCHAR NewDriverRegPath)
+{
+ UNICODE_STRING RegPath;
+ NTSTATUS Status;
+
+ /* Try to unload ourself, which should fail as our Unload routine hasnt been set yet.
*/
+ Status = ZwUnloadDriver(DriverRegistryPath);
+ ok (Status == STATUS_INVALID_DEVICE_REQUEST, "Expected NTSTATUS
STATUS_INVALID_DEVICE_REQUEST, got 0x%lX", Status);
+
+ /* Try to unload with a Registry Path that doesnt exist */
+ RtlInitUnicodeString(&RegPath,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\deadbeef");
+ Status = ZwUnloadDriver(&RegPath);
+ ok (Status == STATUS_OBJECT_NAME_NOT_FOUND, "Expected NTSTATUS
STATUS_OBJECT_NAME_NOT_FOUND, got 0x%lX", Status);
+
+ /* Unload the driver */
+ RtlInitUnicodeString(&RegPath, NewDriverRegPath);
+ Status = ZwUnloadDriver(&RegPath);
+ ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX",
Status);
+
+ if (!NT_SUCCESS(Status))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
Propchange: trunk/rostests/drivers/kmtest/drvobj_test.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/rostests/drivers/kmtest/kmtest.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/drivers/kmtest/kmtest.c?r…
==============================================================================
--- trunk/rostests/drivers/kmtest/kmtest.c [iso-8859-1] (original)
+++ trunk/rostests/drivers/kmtest/kmtest.c [iso-8859-1] Thu Jun 11 18:13:11 2009
@@ -40,7 +40,7 @@
VOID
FinishTest(LPSTR TestName)
{
- DbgPrint("Test %s finished with %d succeses and %d failures\n", TestName,
successes, failures);
+ DbgPrint("%s: %d test executed (0 marked as todo, %d failures), 0
skipped.\n", TestName, successes + failures, failures);
}
void kmtest_set_location(const char* file, int line)
@@ -100,6 +100,8 @@
/* PUBLIC FUNCTIONS ***********************************************************/
+PWCHAR CreateLowerDeviceRegistryKey(PUNICODE_STRING RegistryPath, PWCHAR NewDriver);
+
/*
* Test Declarations
*/
@@ -107,6 +109,63 @@
VOID NtoskrnlObTest();
VOID NtoskrnlExecutiveTests();
VOID NtoskrnlPoolsTest();
+VOID DriverObjectTest(PDRIVER_OBJECT, int);
+VOID DeviceCreateDeleteTest(PDRIVER_OBJECT);
+VOID DeviceObjectTest(PDEVICE_OBJECT);
+BOOLEAN ZwLoadTest(PDRIVER_OBJECT, PUNICODE_STRING, PWCHAR);
+BOOLEAN ZwUnloadTest(PDRIVER_OBJECT, PUNICODE_STRING, PWCHAR);
+BOOLEAN DetachDeviceTest(PDEVICE_OBJECT);
+BOOLEAN AttachDeviceTest(PDEVICE_OBJECT, PWCHAR);
+VOID LowerDeviceKernelAPITest(PDEVICE_OBJECT, BOOLEAN);
+
+/*
+ * KmtestDispatch
+ */
+NTSTATUS
+NTAPI
+KmtestDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
+
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (AttachDeviceObject)
+ {
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(AttachDeviceObject, Irp);
+ return Status;
+ }
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+}
+
+/*
+ * KmtestCreateClose
+ */
+NTSTATUS
+NTAPI
+KmtestCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (AttachDeviceObject)
+ {
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(AttachDeviceObject, Irp);
+ return Status;
+ }
+
+ /* Do DriverObject Test with Driver Initialized */
+ DriverObjectTest(DeviceObject->DriverObject, 1);
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information=0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
/*
* KmtestUnload
@@ -115,7 +174,24 @@
NTAPI
KmtestUnload(IN PDRIVER_OBJECT DriverObject)
{
- /* Nothing to do here */
+ UNICODE_STRING DosDeviceString;
+
+ if(AttachDeviceObject)
+ {
+ IoDetachDevice(AttachDeviceObject);
+ }
+
+ /* Do DriverObject Test for Unload */
+ DriverObjectTest(DriverObject, 2);
+
+ if (MainDeviceObject)
+ {
+ RtlInitUnicodeString(&DosDeviceString, L"\\DosDevices\\Kmtest");
+ IoDeleteSymbolicLink(&DosDeviceString);
+
+ IoDeleteDevice(MainDeviceObject);
+ }
+ FinishTest("Driver Tests");
}
/*
@@ -126,15 +202,70 @@
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
{
- DbgPrint("\n===============================================\nKernel Mode
Regression Test driver starting...\n");
-
- /* Set necessary routines */
- DriverObject->DriverUnload = KmtestUnload;
+ int i;
+ PWCHAR LowerDriverRegPath;
+
+ DbgPrint("\n===============================================\n");
+ DbgPrint("Kernel Mode Regression Driver Test starting...\n");
+ DbgPrint("===============================================\n");
+
+ MainDeviceObject = NULL;
+ AttachDeviceObject = NULL;
+ ThisDriverObject = DriverObject;
NtoskrnlExecutiveTests();
NtoskrnlIoTests();
NtoskrnlObTest();
NtoskrnlPoolsTest();
+ /* Start the tests for the driver routines */
+ StartTest();
+
+ /* Do DriverObject Test for Driver Entry */
+ DriverObjectTest(DriverObject, 0);
+ /* Create and delete device, on return MainDeviceObject has been created */
+ DeviceCreateDeleteTest(DriverObject);
+
+ /* Make sure a device object was created */
+ if (MainDeviceObject)
+ {
+ LowerDriverRegPath = CreateLowerDeviceRegistryKey(RegistryPath,
L"kmtestassist");
+
+ if (LowerDriverRegPath)
+ {
+ /* Load driver test and load the lower driver */
+ if (ZwLoadTest(DriverObject, RegistryPath, LowerDriverRegPath))
+ {
+ AttachDeviceTest(MainDeviceObject, L"kmtestassists");
+ if (AttachDeviceObject)
+ {
+ LowerDeviceKernelAPITest(MainDeviceObject, FALSE);
+ }
+
+ /* Unload lower driver without detaching from its device */
+ ZwUnloadTest(DriverObject, RegistryPath, LowerDriverRegPath);
+ LowerDeviceKernelAPITest(MainDeviceObject, TRUE);
+ }
+ else
+ {
+ DbgPrint("Failed to load kmtestassist driver\n");
+ }
+ }
+ }
+ else
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Set all MajorFunctions to NULL to verify that kernel fixes them */
+ for (i = 1; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
+ DriverObject->MajorFunction[i] = NULL;
+
+ /* Set necessary routines */
+ DriverObject->DriverUnload = KmtestUnload;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KmtestDispatch;
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = KmtestCreateClose;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = KmtestCreateClose;
+
return STATUS_SUCCESS;
}
Modified: trunk/rostests/drivers/kmtest/kmtest.h
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/drivers/kmtest/kmtest.h?r…
==============================================================================
--- trunk/rostests/drivers/kmtest/kmtest.h [iso-8859-1] (original)
+++ trunk/rostests/drivers/kmtest/kmtest.h [iso-8859-1] Thu Jun 11 18:13:11 2009
@@ -4,6 +4,8 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
+#include "ntddk.h"
+
/*
Some macros, structs, and vars are based or inspired from the great
@@ -45,4 +47,8 @@
#define ok_(file, line) (kmtest_set_location(file, line), 0) ? 0 : kmtest_ok
#define ok ok_(__FILE__, __LINE__)
+PDEVICE_OBJECT AttachDeviceObject;
+PDEVICE_OBJECT MainDeviceObject;
+PDRIVER_OBJECT ThisDriverObject;
+
#endif /* PNPTEST_H */
Modified: trunk/rostests/drivers/kmtest/kmtest.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/drivers/kmtest/kmtest.rbu…
==============================================================================
--- trunk/rostests/drivers/kmtest/kmtest.rbuild [iso-8859-1] (original)
+++ trunk/rostests/drivers/kmtest/kmtest.rbuild [iso-8859-1] Thu Jun 11 18:13:11 2009
@@ -6,6 +6,9 @@
<file>kmtest.c</file>
<file>deviface.c</file>
<file>deviface_test.c</file>
+ <file>drvobj_test.c</file>
+ <file>devobj_test.c</file>
+ <file>reghelper.c</file>
<file>ntos_ex.c</file>
<file>ntos_io.c</file>
<file>ntos_ob.c</file>
Added: trunk/rostests/drivers/kmtest/kmtestassist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/drivers/kmtest/kmtestassi…
==============================================================================
--- trunk/rostests/drivers/kmtest/kmtestassist.c (added)
+++ trunk/rostests/drivers/kmtest/kmtestassist.c [iso-8859-1] Thu Jun 11 18:13:11 2009
@@ -1,0 +1,95 @@
+/*
+ * Driver Regression Tests
+ *
+ * Copyright 2009 Michael Martin <martinmnet(a)hotmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; see the file COPYING.LIB.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "ntddk.h"
+#include "ntddser.h"
+
+NTSTATUS
+NTAPI
+DriverDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
+{
+ DbgPrint(" ControlCode
%x\n",IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information=0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+DriverCreateClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
+{
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+DriverUnload(IN PDRIVER_OBJECT DriverObject)
+{
+ UNICODE_STRING DeviceString;
+
+ RtlInitUnicodeString(&DeviceString, L"\\DosDevices\\kmtestassist");
+ IoDeleteSymbolicLink(&DeviceString);
+
+ IoDeleteDevice(DriverObject->DeviceObject);
+}
+
+NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING path)
+{
+ PDEVICE_OBJECT pDeviceObject;
+ UNICODE_STRING DriverString;
+ UNICODE_STRING DeviceString;
+
+ NTSTATUS Status= STATUS_DEVICE_CONFIGURATION_ERROR;
+
+ RtlInitUnicodeString(&DriverString, L"\\Device\\kmtestassist");
+
+ Status =
IoCreateDevice(DriverObject,0,&DriverString,FILE_DEVICE_UNKNOWN,0,FALSE,&pDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ RtlInitUnicodeString(&DeviceString, L"\\DosDevices\\kmtestassist");
+
+ Status = IoCreateSymbolicLink(&DeviceString, &DriverString);
+ if (!NT_SUCCESS(Status))
+ {
+ // Delete device object if not successful
+ IoDeleteDevice(pDeviceObject);
+ return Status;
+ }
+
+ DriverObject->DriverUnload = DriverUnload;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDispatch;
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverCreateClose;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverCreateClose;
+
+ return Status;
+}
Propchange: trunk/rostests/drivers/kmtest/kmtestassist.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rostests/drivers/kmtest/kmtestassist.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/drivers/kmtest/kmtestassi…
==============================================================================
--- trunk/rostests/drivers/kmtest/kmtestassist.rbuild (added)
+++ trunk/rostests/drivers/kmtest/kmtestassist.rbuild [iso-8859-1] Thu Jun 11 18:13:11
2009
@@ -1,0 +1,8 @@
+<module name="kmtestassist" type="kernelmodedriver"
installbase="system32/drivers" installname="kmtestassist.sys">
+ <bootstrap base="$(CDOUTPUT)" />
+ <define name="__USE_W32API" />
+ <include base="ReactOS">include/reactos/drivers</include>
+ <library>ntoskrnl</library>
+ <library>hal</library>
+ <file>kmtestassist.c</file>
+</module>
Propchange: trunk/rostests/drivers/kmtest/kmtestassist.rbuild
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rostests/drivers/kmtest/reghelper.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/drivers/kmtest/reghelper.…
==============================================================================
--- trunk/rostests/drivers/kmtest/reghelper.c (added)
+++ trunk/rostests/drivers/kmtest/reghelper.c [iso-8859-1] Thu Jun 11 18:13:11 2009
@@ -1,0 +1,219 @@
+/*
+ * Driver Regression Tests
+ *
+ * Copyright 2009 Michael Martin <martinmnet(a)hotmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; see the file COPYING.LIB.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "kmtest.h"
+
+/*
+ Adds a service registry entry for a driver
+ The driver must reside in the same path as this loaded driver
+ The caller is resposible for releasing memory
+*/
+PWCHAR CreateLowerDeviceRegistryKey(PUNICODE_STRING RegistryPath, PWCHAR NewDriver)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING Name;
+ UNICODE_STRING Value;
+ UNICODE_STRING NewDriverRegPath;
+ PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInfo = NULL;
+ HANDLE ServiceKey;
+ NTSTATUS Status;
+ ULONG Disposition;
+ ULONG ServiceDWordValue;
+ ULONG ResultLength = 0;
+ ULONG Length = 0;
+ PWCHAR ReturnPath = NULL;
+ /* Now lets find out where we were loaded from by using registry */
+ InitializeObjectAttributes(&ObjectAttributes, RegistryPath, OBJ_CASE_INSENSITIVE,
NULL, NULL);
+ Status = ZwOpenKey(&ServiceKey, KEY_READ, &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("ZwOpenKey () failed (Status %x)\n", Status);
+ return NULL;
+ }
+
+ RtlInitUnicodeString(&Name, L"ImagePath");
+
+ /* First query how much memory we need */
+ Status = ZwQueryValueKey(ServiceKey, &Name, KeyValuePartialInformation, 0, 0,
&ResultLength);
+
+ ResultLength += sizeof(KEY_VALUE_PARTIAL_INFORMATION);
+ ValuePartialInfo = ExAllocatePool(PagedPool, ResultLength);
+ if (!ValuePartialInfo)
+ {
+ DbgPrint("Out of memory!\n");
+ goto cleanup;
+ }
+
+ Length = ResultLength;
+ Status = ZwQueryValueKey(ServiceKey, &Name, KeyValuePartialInformation,
(PVOID)ValuePartialInfo, Length, &ResultLength);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("ZwQueryValueKey() failed (Status %lx)\n", Status);
+ goto cleanup;
+ }
+
+ /* Remove the current driver name from the string */
+ /* FIXME: Dont use hard coded driver name, determine it from the string returned from
the above Query */
+ Length = (wcslen((PWCHAR)ValuePartialInfo->Data) * 2) -
(wcslen(L"kmtest.sys") * 2);
+ RtlZeroMemory((PVOID)((ULONG)ValuePartialInfo->Data + Length),
+ wcslen(L"drvtests.sys") * 2);
+ ZwClose(ServiceKey);
+
+ /* Now add a registry entry for the driver */
+
+ NewDriverRegPath.Length = 0;
+ NewDriverRegPath.MaximumLength =
(wcslen(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\") +
+ wcslen(NewDriver) + 1) * sizeof(WCHAR);
+ NewDriverRegPath.Buffer = ExAllocatePool(PagedPool, NewDriverRegPath.MaximumLength);
+ if (!NewDriverRegPath.Buffer)
+ {
+ DbgPrint("Out of memory!\n");
+ ExFreePool(NewDriverRegPath.Buffer);
+ goto cleanup;
+ }
+
+ RtlAppendUnicodeToString(&NewDriverRegPath,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+ RtlAppendUnicodeToString(&NewDriverRegPath, NewDriver);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &NewDriverRegPath,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ 0,
+ NULL);
+
+ Status = ZwCreateKey(&ServiceKey,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ &Disposition);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("ZwCreateKey() failed (Status %lx)\n", Status);
+ ExFreePool(NewDriverRegPath.Buffer);
+ goto cleanup;
+ }
+
+ ReturnPath = NewDriverRegPath.Buffer;
+ RtlInitUnicodeString(&Name, L"ImagePath");
+
+ Value.Length = 0;
+ Value.MaximumLength = (wcslen((PWCHAR)ValuePartialInfo->Data) +
+ wcslen(NewDriver) + 5) * sizeof(WCHAR);
+ Value.Buffer = ExAllocatePool(PagedPool, Value.MaximumLength);
+
+ if (!Value.Buffer)
+ {
+ DbgPrint("Out of memory!\n");
+ ExFreePool(Value.Buffer);
+ goto cleanup;
+ }
+
+ RtlAppendUnicodeToString(&Value, (PWCHAR)ValuePartialInfo->Data);
+ RtlAppendUnicodeToString(&Value, NewDriver);
+ RtlAppendUnicodeToString(&Value, L".sys");
+
+ Status = ZwSetValueKey(ServiceKey,
+ &Name,
+ 0,
+ REG_SZ,
+ Value.Buffer,
+ (wcslen(Value.Buffer)+1) * sizeof(WCHAR));
+ ExFreePool(Value.Buffer);
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("ZwCreateKey() failed (Status %lx)\n", Status);
+ goto cleanup;
+ }
+
+ RtlInitUnicodeString(&Name, L"DisplayName");
+ RtlInitUnicodeString(&Value, NewDriver);
+
+ Status = ZwSetValueKey(ServiceKey,
+ &Name,
+ 0,
+ REG_SZ,
+ Value.Buffer,
+ (wcslen(Value.Buffer)+1) * sizeof(WCHAR));
+
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("ZwCreateKey() failed (Status %lx)\n", Status);
+ goto cleanup;
+ }
+
+ RtlInitUnicodeString(&Name, L"ErrorControl");
+ ServiceDWordValue = 0;
+
+ Status = ZwSetValueKey(ServiceKey,
+ &Name,
+ 0,
+ REG_DWORD,
+ &ServiceDWordValue,
+ sizeof(ULONG));
+
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("ZwCreateKey() failed (Status %lx)\n", Status);
+ goto cleanup;
+ }
+
+ RtlInitUnicodeString(&Name, L"Start");
+ ServiceDWordValue = 3;
+ Status = ZwSetValueKey(ServiceKey,
+ &Name,
+ 0,
+ REG_DWORD,
+ &ServiceDWordValue,
+ sizeof(ULONG));
+
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("ZwCreateKey() failed (Status %lx)\n", Status);
+ goto cleanup;
+ }
+
+ RtlInitUnicodeString(&Name, L"Type");
+ ServiceDWordValue = 0;
+ Status = ZwSetValueKey(ServiceKey,
+ &Name,
+ 0,
+ REG_DWORD,
+ &ServiceDWordValue,
+ sizeof(ULONG));
+
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("ZwCreateKey() failed (Status %lx)\n", Status);
+ goto cleanup;
+ }
+
+cleanup:
+ ZwClose(ServiceKey);
+ if (ValuePartialInfo) ExFreePool(ValuePartialInfo);
+
+ return ReturnPath;
+
+}
Propchange: trunk/rostests/drivers/kmtest/reghelper.c
------------------------------------------------------------------------------
svn:eol-style = native