mirror of
https://github.com/reactos/reactos.git
synced 2024-11-09 16:20:37 +00:00
75946e1764
- 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
219 lines
7.1 KiB
C
219 lines
7.1 KiB
C
/*
|
|
* 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;
|
|
|
|
}
|