mirror of
https://github.com/reactos/reactos.git
synced 2025-07-29 14:32:21 +00:00
- 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. svn path=/trunk/; revision=41381
This commit is contained in:
parent
978fcad8fb
commit
75946e1764
9 changed files with 877 additions and 5 deletions
|
@ -7,6 +7,9 @@
|
||||||
<directory name="kmtest">
|
<directory name="kmtest">
|
||||||
<xi:include href="kmtest/kmtest.rbuild" />
|
<xi:include href="kmtest/kmtest.rbuild" />
|
||||||
</directory>
|
</directory>
|
||||||
|
<directory name="kmtest">
|
||||||
|
<xi:include href="kmtest/kmtestassist.rbuild" />
|
||||||
|
</directory>
|
||||||
<directory name="memtest">
|
<directory name="memtest">
|
||||||
<xi:include href="memtest/memtest.rbuild" />
|
<xi:include href="memtest/memtest.rbuild" />
|
||||||
</directory>
|
</directory>
|
||||||
|
|
266
rostests/drivers/kmtest/devobj_test.c
Normal file
266
rostests/drivers/kmtest/devobj_test.c
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
/*
|
||||||
|
* Driver Regression Tests
|
||||||
|
*
|
||||||
|
* Copyright 2009 Michael Martin <martinmnet@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;
|
||||||
|
}
|
141
rostests/drivers/kmtest/drvobj_test.c
Normal file
141
rostests/drivers/kmtest/drvobj_test.c
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* Driver Regression Tests
|
||||||
|
*
|
||||||
|
* Copyright 2009 Michael Martin <martinmnet@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;
|
||||||
|
}
|
|
@ -40,7 +40,7 @@ StartTest()
|
||||||
VOID
|
VOID
|
||||||
FinishTest(LPSTR TestName)
|
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)
|
void kmtest_set_location(const char* file, int line)
|
||||||
|
@ -100,6 +100,8 @@ int kmtest_ok(int condition, const char *msg, ... )
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
|
PWCHAR CreateLowerDeviceRegistryKey(PUNICODE_STRING RegistryPath, PWCHAR NewDriver);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test Declarations
|
* Test Declarations
|
||||||
*/
|
*/
|
||||||
|
@ -107,6 +109,63 @@ VOID NtoskrnlIoTests();
|
||||||
VOID NtoskrnlObTest();
|
VOID NtoskrnlObTest();
|
||||||
VOID NtoskrnlExecutiveTests();
|
VOID NtoskrnlExecutiveTests();
|
||||||
VOID NtoskrnlPoolsTest();
|
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
|
* KmtestUnload
|
||||||
|
@ -115,7 +174,24 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KmtestUnload(IN PDRIVER_OBJECT DriverObject)
|
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 @@ NTAPI
|
||||||
DriverEntry(PDRIVER_OBJECT DriverObject,
|
DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||||
PUNICODE_STRING RegistryPath)
|
PUNICODE_STRING RegistryPath)
|
||||||
{
|
{
|
||||||
DbgPrint("\n===============================================\nKernel Mode Regression Test driver starting...\n");
|
int i;
|
||||||
|
PWCHAR LowerDriverRegPath;
|
||||||
|
|
||||||
/* Set necessary routines */
|
DbgPrint("\n===============================================\n");
|
||||||
DriverObject->DriverUnload = KmtestUnload;
|
DbgPrint("Kernel Mode Regression Driver Test starting...\n");
|
||||||
|
DbgPrint("===============================================\n");
|
||||||
|
|
||||||
|
MainDeviceObject = NULL;
|
||||||
|
AttachDeviceObject = NULL;
|
||||||
|
ThisDriverObject = DriverObject;
|
||||||
|
|
||||||
NtoskrnlExecutiveTests();
|
NtoskrnlExecutiveTests();
|
||||||
NtoskrnlIoTests();
|
NtoskrnlIoTests();
|
||||||
NtoskrnlObTest();
|
NtoskrnlObTest();
|
||||||
NtoskrnlPoolsTest();
|
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;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "ntddk.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Some macros, structs, and vars are based or inspired from the great
|
Some macros, structs, and vars are based or inspired from the great
|
||||||
|
@ -45,4 +47,8 @@ extern int kmtest_ok( int condition, const char *msg, ... );
|
||||||
#define ok_(file, line) (kmtest_set_location(file, line), 0) ? 0 : kmtest_ok
|
#define ok_(file, line) (kmtest_set_location(file, line), 0) ? 0 : kmtest_ok
|
||||||
#define ok ok_(__FILE__, __LINE__)
|
#define ok ok_(__FILE__, __LINE__)
|
||||||
|
|
||||||
|
PDEVICE_OBJECT AttachDeviceObject;
|
||||||
|
PDEVICE_OBJECT MainDeviceObject;
|
||||||
|
PDRIVER_OBJECT ThisDriverObject;
|
||||||
|
|
||||||
#endif /* PNPTEST_H */
|
#endif /* PNPTEST_H */
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
<file>kmtest.c</file>
|
<file>kmtest.c</file>
|
||||||
<file>deviface.c</file>
|
<file>deviface.c</file>
|
||||||
<file>deviface_test.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_ex.c</file>
|
||||||
<file>ntos_io.c</file>
|
<file>ntos_io.c</file>
|
||||||
<file>ntos_ob.c</file>
|
<file>ntos_ob.c</file>
|
||||||
|
|
95
rostests/drivers/kmtest/kmtestassist.c
Normal file
95
rostests/drivers/kmtest/kmtestassist.c
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Driver Regression Tests
|
||||||
|
*
|
||||||
|
* Copyright 2009 Michael Martin <martinmnet@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;
|
||||||
|
}
|
8
rostests/drivers/kmtest/kmtestassist.rbuild
Normal file
8
rostests/drivers/kmtest/kmtestassist.rbuild
Normal file
|
@ -0,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>
|
219
rostests/drivers/kmtest/reghelper.c
Normal file
219
rostests/drivers/kmtest/reghelper.c
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
/*
|
||||||
|
* Driver Regression Tests
|
||||||
|
*
|
||||||
|
* Copyright 2009 Michael Martin <martinmnet@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;
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue