mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 20:50:29 +00:00
[KMTEST]
- Add support for recovering from crashed tests - Add check to prevent us from running the test every boot - Delete some useless code - Record test result information in the registry - Under the Kmtest\Parameters key, you will find CurrentStage which is the stage that testing is on (almost always 8 if it boots). You will also find <Test Name>SuccessCount which is the number of successful tests, <Test Name>FailureCount which is the number of failed tests, <Test Name>TotalCount which is the total number of tests, and <Test Name>SkippedCount which is the number of tests that have been skipped - Enjoy your reg testing! :) svn path=/trunk/; revision=47309
This commit is contained in:
parent
d7bbeaed19
commit
afcd401a32
10 changed files with 330 additions and 676 deletions
|
@ -1,545 +0,0 @@
|
||||||
/*
|
|
||||||
* PnP Test
|
|
||||||
* ReactOS Device Interface functions implementation
|
|
||||||
*
|
|
||||||
* Copyright 2003, 2004 Filip Navara <xnavara@volny.cz>
|
|
||||||
* Copyright 2003, 2004 Matthew Brace <ismarc@austin.rr.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 <ddk/ntddk.h>
|
|
||||||
#include "kmtest.h"
|
|
||||||
|
|
||||||
//#define NDEBUG
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IoGetDeviceInterfaces
|
|
||||||
*
|
|
||||||
* Returns a list of device interfaces of a particular device interface class.
|
|
||||||
*
|
|
||||||
* Parameters
|
|
||||||
* InterfaceClassGuid
|
|
||||||
* Points to a class GUID specifying the device interface class.
|
|
||||||
*
|
|
||||||
* PhysicalDeviceObject
|
|
||||||
* Points to an optional PDO that narrows the search to only the
|
|
||||||
* device interfaces of the device represented by the PDO.
|
|
||||||
*
|
|
||||||
* Flags
|
|
||||||
* Specifies flags that modify the search for device interfaces. The
|
|
||||||
* DEVICE_INTERFACE_INCLUDE_NONACTIVE flag specifies that the list of
|
|
||||||
* returned symbolic links should contain also disabled device
|
|
||||||
* interfaces in addition to the enabled ones.
|
|
||||||
*
|
|
||||||
* SymbolicLinkList
|
|
||||||
* Points to a character pointer that is filled in on successful return
|
|
||||||
* with a list of unicode strings identifying the device interfaces
|
|
||||||
* that match the search criteria. The newly allocated buffer contains
|
|
||||||
* a list of symbolic link names. Each unicode string in the list is
|
|
||||||
* null-terminated; the end of the whole list is marked by an additional
|
|
||||||
* NULL. The caller is responsible for freeing the buffer (ExFreePool)
|
|
||||||
* when it is no longer needed.
|
|
||||||
* If no device interfaces match the search criteria, this routine
|
|
||||||
* returns STATUS_SUCCESS and the string contains a single NULL
|
|
||||||
* character.
|
|
||||||
*
|
|
||||||
* Status
|
|
||||||
* @unimplemented
|
|
||||||
*
|
|
||||||
* The parameters PhysicalDeviceObject and Flags aren't correctly
|
|
||||||
* processed. Rest of the cases was tested under Win XP and the
|
|
||||||
* function worked correctly.
|
|
||||||
*/
|
|
||||||
|
|
||||||
NTSTATUS NTAPI
|
|
||||||
ReactOS_IoGetDeviceInterfaces(
|
|
||||||
IN CONST GUID *InterfaceClassGuid,
|
|
||||||
IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL,
|
|
||||||
IN ULONG Flags,
|
|
||||||
OUT PWSTR *SymbolicLinkList)
|
|
||||||
{
|
|
||||||
PWCHAR BaseKeyString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\DeviceClasses\\";
|
|
||||||
PWCHAR BaseInterfaceString = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
|
|
||||||
UNICODE_STRING GuidString;
|
|
||||||
UNICODE_STRING BaseKeyName;
|
|
||||||
UNICODE_STRING AliasKeyName;
|
|
||||||
UNICODE_STRING SymbolicLink;
|
|
||||||
UNICODE_STRING Control;
|
|
||||||
UNICODE_STRING SubKeyName;
|
|
||||||
UNICODE_STRING SymbolicLinkKeyName;
|
|
||||||
UNICODE_STRING ControlKeyName;
|
|
||||||
UNICODE_STRING TempString;
|
|
||||||
HANDLE InterfaceKey;
|
|
||||||
HANDLE SubKey;
|
|
||||||
HANDLE SymbolicLinkKey;
|
|
||||||
PKEY_FULL_INFORMATION fip;
|
|
||||||
PKEY_FULL_INFORMATION bfip=NULL;
|
|
||||||
PKEY_BASIC_INFORMATION bip;
|
|
||||||
PKEY_VALUE_PARTIAL_INFORMATION vpip=NULL;
|
|
||||||
PWCHAR SymLinkList = NULL;
|
|
||||||
ULONG SymLinkListSize = 0;
|
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG Size = 0;
|
|
||||||
ULONG i = 0;
|
|
||||||
ULONG j = 0;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
|
|
||||||
Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("RtlStringFromGUID() Failed.\n");
|
|
||||||
return STATUS_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlInitUnicodeString(&AliasKeyName, BaseInterfaceString);
|
|
||||||
RtlInitUnicodeString(&SymbolicLink, L"SymbolicLink");
|
|
||||||
RtlInitUnicodeString(&Control, L"\\Control");
|
|
||||||
BaseKeyName.Length = wcslen(BaseKeyString) * sizeof(WCHAR);
|
|
||||||
BaseKeyName.MaximumLength = BaseKeyName.Length + (38 * sizeof(WCHAR));
|
|
||||||
BaseKeyName.Buffer = ExAllocatePool(
|
|
||||||
NonPagedPool,
|
|
||||||
BaseKeyName.MaximumLength);
|
|
||||||
ASSERT(BaseKeyName.Buffer != NULL);
|
|
||||||
wcscpy(BaseKeyName.Buffer, BaseKeyString);
|
|
||||||
RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);
|
|
||||||
|
|
||||||
if (PhysicalDeviceObject)
|
|
||||||
{
|
|
||||||
WCHAR GuidBuffer[40];
|
|
||||||
UNICODE_STRING PdoGuidString;
|
|
||||||
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
|
|
||||||
IoGetDeviceProperty(
|
|
||||||
PhysicalDeviceObject,
|
|
||||||
DevicePropertyClassGuid,
|
|
||||||
sizeof(GuidBuffer),
|
|
||||||
GuidBuffer,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
RtlInitUnicodeString(&PdoGuidString, GuidBuffer);
|
|
||||||
if (RtlCompareUnicodeString(&GuidString, &PdoGuidString, TRUE))
|
|
||||||
{
|
|
||||||
DPRINT("Inconsistent Guid's asked for in IoGetDeviceInterfaces()\n");
|
|
||||||
return STATUS_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("IoGetDeviceInterfaces() called with PDO, not implemented.\n");
|
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InitializeObjectAttributes(
|
|
||||||
&ObjectAttributes,
|
|
||||||
&BaseKeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Status = ZwOpenKey(
|
|
||||||
&InterfaceKey,
|
|
||||||
KEY_READ,
|
|
||||||
&ObjectAttributes);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = ZwQueryKey(
|
|
||||||
InterfaceKey,
|
|
||||||
KeyFullInformation,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
||||||
{
|
|
||||||
DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
fip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
|
||||||
ASSERT(fip != NULL);
|
|
||||||
|
|
||||||
Status = ZwQueryKey(
|
|
||||||
InterfaceKey,
|
|
||||||
KeyFullInformation,
|
|
||||||
fip,
|
|
||||||
Size,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i < fip->SubKeys; i++)
|
|
||||||
{
|
|
||||||
Status = ZwEnumerateKey(
|
|
||||||
InterfaceKey,
|
|
||||||
i,
|
|
||||||
KeyBasicInformation,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
||||||
{
|
|
||||||
DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
|
||||||
ASSERT(bip != NULL);
|
|
||||||
|
|
||||||
Status = ZwEnumerateKey(
|
|
||||||
InterfaceKey,
|
|
||||||
i,
|
|
||||||
KeyBasicInformation,
|
|
||||||
bip,
|
|
||||||
Size,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
ExFreePool(bip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
SubKeyName.Length = 0;
|
|
||||||
SubKeyName.MaximumLength = BaseKeyName.Length + bip->NameLength + sizeof(WCHAR);
|
|
||||||
SubKeyName.Buffer = ExAllocatePool(NonPagedPool, SubKeyName.MaximumLength);
|
|
||||||
ASSERT(SubKeyName.Buffer != NULL);
|
|
||||||
TempString.Length = TempString.MaximumLength = bip->NameLength;
|
|
||||||
TempString.Buffer = bip->Name;
|
|
||||||
RtlCopyUnicodeString(&SubKeyName, &BaseKeyName);
|
|
||||||
RtlAppendUnicodeToString(&SubKeyName, L"\\");
|
|
||||||
RtlAppendUnicodeStringToString(&SubKeyName, &TempString);
|
|
||||||
|
|
||||||
ExFreePool(bip);
|
|
||||||
|
|
||||||
InitializeObjectAttributes(
|
|
||||||
&ObjectAttributes,
|
|
||||||
&SubKeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Status = ZwOpenKey(
|
|
||||||
&SubKey,
|
|
||||||
KEY_READ,
|
|
||||||
&ObjectAttributes);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = ZwQueryKey(
|
|
||||||
SubKey,
|
|
||||||
KeyFullInformation,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
||||||
{
|
|
||||||
DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
bfip = (PKEY_FULL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
|
||||||
ASSERT(bfip != NULL);
|
|
||||||
|
|
||||||
Status = ZwQueryKey(
|
|
||||||
SubKey,
|
|
||||||
KeyFullInformation,
|
|
||||||
bfip,
|
|
||||||
Size,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(j = 0; j < bfip->SubKeys; j++)
|
|
||||||
{
|
|
||||||
Status = ZwEnumerateKey(
|
|
||||||
SubKey,
|
|
||||||
j,
|
|
||||||
KeyBasicInformation,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
||||||
{
|
|
||||||
DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
|
|
||||||
ExFreePool(bfip);
|
|
||||||
ExFreePool(fip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
|
||||||
ASSERT(bip != NULL);
|
|
||||||
|
|
||||||
Status = ZwEnumerateKey(
|
|
||||||
SubKey,
|
|
||||||
j,
|
|
||||||
KeyBasicInformation,
|
|
||||||
bip,
|
|
||||||
Size,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
ExFreePool(bfip);
|
|
||||||
ExFreePool(bip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wcsncmp(bip->Name, L"Control", bip->NameLength))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
SymbolicLinkKeyName.Length = 0;
|
|
||||||
SymbolicLinkKeyName.MaximumLength = SubKeyName.Length + bip->NameLength + sizeof(WCHAR);
|
|
||||||
SymbolicLinkKeyName.Buffer = ExAllocatePool(NonPagedPool, SymbolicLinkKeyName.MaximumLength);
|
|
||||||
ASSERT(SymbolicLinkKeyName.Buffer != NULL);
|
|
||||||
TempString.Length = TempString.MaximumLength = bip->NameLength;
|
|
||||||
TempString.Buffer = bip->Name;
|
|
||||||
RtlCopyUnicodeString(&SymbolicLinkKeyName, &SubKeyName);
|
|
||||||
RtlAppendUnicodeToString(&SymbolicLinkKeyName, L"\\");
|
|
||||||
RtlAppendUnicodeStringToString(&SymbolicLinkKeyName, &TempString);
|
|
||||||
|
|
||||||
ControlKeyName.Length = 0;
|
|
||||||
ControlKeyName.MaximumLength = SymbolicLinkKeyName.Length + Control.Length + sizeof(WCHAR);
|
|
||||||
ControlKeyName.Buffer = ExAllocatePool(NonPagedPool, ControlKeyName.MaximumLength);
|
|
||||||
ASSERT(ControlKeyName.Buffer != NULL);
|
|
||||||
RtlCopyUnicodeString(&ControlKeyName, &SymbolicLinkKeyName);
|
|
||||||
RtlAppendUnicodeStringToString(&ControlKeyName, &Control);
|
|
||||||
|
|
||||||
ExFreePool(bip);
|
|
||||||
|
|
||||||
InitializeObjectAttributes(
|
|
||||||
&ObjectAttributes,
|
|
||||||
&SymbolicLinkKeyName,
|
|
||||||
OBJ_CASE_INSENSITIVE,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
Status = ZwOpenKey(
|
|
||||||
&SymbolicLinkKey,
|
|
||||||
KEY_READ,
|
|
||||||
&ObjectAttributes);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwOpenKey() Failed. (0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
ExFreePool(bfip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = ZwQueryValueKey(
|
|
||||||
SymbolicLinkKey,
|
|
||||||
&SymbolicLink,
|
|
||||||
KeyValuePartialInformation,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
|
||||||
{
|
|
||||||
DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
ExFreePool(bfip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(SymbolicLinkKey);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
vpip = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(NonPagedPool, Size);
|
|
||||||
ASSERT(vpip != NULL);
|
|
||||||
|
|
||||||
Status = ZwQueryValueKey(
|
|
||||||
SymbolicLinkKey,
|
|
||||||
&SymbolicLink,
|
|
||||||
KeyValuePartialInformation,
|
|
||||||
vpip,
|
|
||||||
Size,
|
|
||||||
&Size);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status);
|
|
||||||
ExFreePool(fip);
|
|
||||||
ExFreePool(bfip);
|
|
||||||
ExFreePool(vpip);
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
ExFreePool(SymLinkList);
|
|
||||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(SymbolicLinkKey);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, ControlKeyName.Buffer);
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* Put the name in the string here */
|
|
||||||
if (SymLinkList == NULL)
|
|
||||||
{
|
|
||||||
SymLinkListSize = vpip->DataLength;
|
|
||||||
SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR));
|
|
||||||
ASSERT(SymLinkList != NULL);
|
|
||||||
RtlCopyMemory(SymLinkList, vpip->Data, vpip->DataLength);
|
|
||||||
SymLinkList[vpip->DataLength / sizeof(WCHAR)] = 0;
|
|
||||||
SymLinkList[1] = '?';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PWCHAR OldSymLinkList;
|
|
||||||
ULONG OldSymLinkListSize;
|
|
||||||
PWCHAR SymLinkListPtr;
|
|
||||||
|
|
||||||
OldSymLinkList = SymLinkList;
|
|
||||||
OldSymLinkListSize = SymLinkListSize;
|
|
||||||
SymLinkListSize += vpip->DataLength;
|
|
||||||
SymLinkList = ExAllocatePool(NonPagedPool, SymLinkListSize + sizeof(WCHAR));
|
|
||||||
ASSERT(SymLinkList != NULL);
|
|
||||||
RtlCopyMemory(SymLinkList, OldSymLinkList, OldSymLinkListSize);
|
|
||||||
ExFreePool(OldSymLinkList);
|
|
||||||
SymLinkListPtr = SymLinkList + (OldSymLinkListSize / sizeof(WCHAR));
|
|
||||||
RtlCopyMemory(SymLinkListPtr, vpip->Data, vpip->DataLength);
|
|
||||||
SymLinkListPtr[vpip->DataLength / sizeof(WCHAR)] = 0;
|
|
||||||
SymLinkListPtr[1] = '?';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlFreeUnicodeString(&SymbolicLinkKeyName);
|
|
||||||
RtlFreeUnicodeString(&ControlKeyName);
|
|
||||||
ZwClose(SymbolicLinkKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExFreePool(vpip);
|
|
||||||
RtlFreeUnicodeString(&SubKeyName);
|
|
||||||
ZwClose(SubKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SymLinkList != NULL)
|
|
||||||
{
|
|
||||||
SymLinkList[SymLinkListSize / sizeof(WCHAR)] = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SymLinkList = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
|
|
||||||
SymLinkList[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
*SymbolicLinkList = SymLinkList;
|
|
||||||
|
|
||||||
RtlFreeUnicodeString(&BaseKeyName);
|
|
||||||
ZwClose(InterfaceKey);
|
|
||||||
ExFreePool(bfip);
|
|
||||||
ExFreePool(fip);
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <ndk/iotypes.h>
|
#include <ndk/iotypes.h>
|
||||||
#include "kmtest.h"
|
#include "kmtest.h"
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
@ -52,26 +52,26 @@ VOID DeviceInterfaceTest_Func()
|
||||||
PWSTR SymbolicLinkListPtr;
|
PWSTR SymbolicLinkListPtr;
|
||||||
GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}};
|
GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}};
|
||||||
|
|
||||||
Status = IoGetDeviceInterfaces_Func(
|
Status = IoGetDeviceInterfaces(
|
||||||
&Guid,
|
&Guid,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
&SymbolicLinkList);
|
&SymbolicLinkList);
|
||||||
|
|
||||||
|
ok(NT_SUCCESS(Status),
|
||||||
|
"IoGetDeviceInterfaces failed with status 0x%X\n",
|
||||||
|
(unsigned int)Status);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT(
|
|
||||||
"[PnP Test] IoGetDeviceInterfaces failed with status 0x%X\n",
|
|
||||||
Status);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("[PnP Test] IoGetDeviceInterfaces results:\n");
|
DPRINT("IoGetDeviceInterfaces results:\n");
|
||||||
for (SymbolicLinkListPtr = SymbolicLinkList;
|
for (SymbolicLinkListPtr = SymbolicLinkList;
|
||||||
SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0;
|
SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0;
|
||||||
SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1)
|
SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1)
|
||||||
{
|
{
|
||||||
DPRINT("[PnP Test] %S\n", SymbolicLinkListPtr);
|
DPRINT1("Symbolic Link: %S\n", SymbolicLinkListPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -102,7 +102,7 @@ VOID DeviceInterfaceTest_Func()
|
||||||
ExFreePool(SymbolicLinkList);
|
ExFreePool(SymbolicLinkList);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID RegisterDI_Test()
|
VOID RegisterDI_Test(HANDLE KeyHandle)
|
||||||
{
|
{
|
||||||
GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}};
|
GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}};
|
||||||
DEVICE_OBJECT DeviceObject;
|
DEVICE_OBJECT DeviceObject;
|
||||||
|
@ -111,6 +111,8 @@ VOID RegisterDI_Test()
|
||||||
UNICODE_STRING SymbolicLinkName;
|
UNICODE_STRING SymbolicLinkName;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
StartTest();
|
||||||
|
|
||||||
RtlInitUnicodeString(&SymbolicLinkName, L"");
|
RtlInitUnicodeString(&SymbolicLinkName, L"");
|
||||||
|
|
||||||
// Prepare our surrogate of a Device Object
|
// Prepare our surrogate of a Device Object
|
||||||
|
@ -132,23 +134,8 @@ VOID RegisterDI_Test()
|
||||||
|
|
||||||
ok(Status == STATUS_INVALID_DEVICE_REQUEST,
|
ok(Status == STATUS_INVALID_DEVICE_REQUEST,
|
||||||
"IoRegisterDeviceInterface returned 0x%08lX\n", Status);
|
"IoRegisterDeviceInterface returned 0x%08lX\n", Status);
|
||||||
}
|
|
||||||
|
|
||||||
VOID NtoskrnlIoDeviceInterface()
|
|
||||||
{
|
|
||||||
StartTest();
|
|
||||||
|
|
||||||
// Test IoRegisterDeviceInterface() failures now
|
|
||||||
RegisterDI_Test();
|
|
||||||
|
|
||||||
/*
|
|
||||||
DPRINT("Calling DeviceInterfaceTest_Func with native functions\n");
|
|
||||||
IoGetDeviceInterfaces_Func = IoGetDeviceInterfaces;
|
|
||||||
DeviceInterfaceTest_Func();
|
DeviceInterfaceTest_Func();
|
||||||
DPRINT("Calling DeviceInterfaceTest_Func with ReactOS functions\n");
|
|
||||||
IoGetDeviceInterfaces_Func = ReactOS_IoGetDeviceInterfaces;
|
|
||||||
DeviceInterfaceTest_Func();
|
|
||||||
*/
|
|
||||||
|
|
||||||
FinishTest("NTOSKRNL Io Device Interface Test");
|
FinishTest(KeyHandle, L"IoDeviceInterfaceTest");
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,12 @@
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include "kmtest.h"
|
#include "kmtest.h"
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
LONG successes;
|
LONG successes;
|
||||||
LONG failures;
|
LONG failures;
|
||||||
|
LONG skipped;
|
||||||
tls_data glob_data;
|
tls_data glob_data;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS ***********************************************************/
|
/* PRIVATE FUNCTIONS ***********************************************************/
|
||||||
|
@ -35,12 +39,61 @@ StartTest()
|
||||||
{
|
{
|
||||||
successes = 0;
|
successes = 0;
|
||||||
failures = 0;
|
failures = 0;
|
||||||
|
skipped = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FinishTest(LPSTR TestName)
|
FinishTest(HANDLE KeyHandle, LPWSTR TestName)
|
||||||
{
|
{
|
||||||
DbgPrint("%s: %d test executed (0 marked as todo, %d failures), 0 skipped.\n", TestName, successes + failures, failures);
|
WCHAR KeyName[100];
|
||||||
|
LONG total = successes + failures;
|
||||||
|
UNICODE_STRING KeyNameU;
|
||||||
|
|
||||||
|
wcscpy(KeyName, TestName);
|
||||||
|
wcscat(KeyName, L"SuccessCount");
|
||||||
|
RtlInitUnicodeString(&KeyNameU, KeyName);
|
||||||
|
|
||||||
|
ZwSetValueKey(KeyHandle,
|
||||||
|
&KeyNameU,
|
||||||
|
0,
|
||||||
|
REG_DWORD,
|
||||||
|
&successes,
|
||||||
|
sizeof(ULONG));
|
||||||
|
|
||||||
|
wcscpy(KeyName, TestName);
|
||||||
|
wcscat(KeyName, L"FailureCount");
|
||||||
|
RtlInitUnicodeString(&KeyNameU, KeyName);
|
||||||
|
|
||||||
|
ZwSetValueKey(KeyHandle,
|
||||||
|
&KeyNameU,
|
||||||
|
0,
|
||||||
|
REG_DWORD,
|
||||||
|
&failures,
|
||||||
|
sizeof(ULONG));
|
||||||
|
|
||||||
|
wcscpy(KeyName, TestName);
|
||||||
|
wcscat(KeyName, L"TotalCount");
|
||||||
|
RtlInitUnicodeString(&KeyNameU, KeyName);
|
||||||
|
|
||||||
|
ZwSetValueKey(KeyHandle,
|
||||||
|
&KeyNameU,
|
||||||
|
0,
|
||||||
|
REG_DWORD,
|
||||||
|
&total,
|
||||||
|
sizeof(ULONG));
|
||||||
|
|
||||||
|
wcscpy(KeyName, TestName);
|
||||||
|
wcscat(KeyName, L"SkipCount");
|
||||||
|
RtlInitUnicodeString(&KeyNameU, KeyName);
|
||||||
|
|
||||||
|
ZwSetValueKey(KeyHandle,
|
||||||
|
&KeyNameU,
|
||||||
|
0,
|
||||||
|
REG_DWORD,
|
||||||
|
&skipped,
|
||||||
|
sizeof(ULONG));
|
||||||
|
|
||||||
|
DbgPrint("%S: %d test executed (0 marked as todo, %d failures), %d skipped.\n", TestName, total, failures, skipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kmtest_set_location(const char* file, int line)
|
void kmtest_set_location(const char* file, int line)
|
||||||
|
@ -105,11 +158,14 @@ PWCHAR CreateLowerDeviceRegistryKey(PUNICODE_STRING RegistryPath, PWCHAR NewDriv
|
||||||
/*
|
/*
|
||||||
* Test Declarations
|
* Test Declarations
|
||||||
*/
|
*/
|
||||||
VOID NtoskrnlIoTests();
|
VOID RegisterDI_Test(HANDLE KeyHandle);
|
||||||
VOID NtoskrnlKeTests();
|
VOID NtoskrnlIoMdlTest(HANDLE KeyHandle);
|
||||||
VOID NtoskrnlObTest();
|
VOID NtoskrnlIoIrpTest(HANDLE KeyHandle);
|
||||||
VOID NtoskrnlExecutiveTests();
|
VOID NtoskrnlObTest(HANDLE KeyHandle);
|
||||||
VOID NtoskrnlPoolsTest();
|
VOID ExTimerTest(HANDLE KeyHandle);
|
||||||
|
VOID PoolsTest(HANDLE KeyHandle);
|
||||||
|
VOID PoolsCorruption(HANDLE KeyHandle);
|
||||||
|
VOID KeStallTest(HANDLE KeyHandle);
|
||||||
VOID DriverObjectTest(PDRIVER_OBJECT, int);
|
VOID DriverObjectTest(PDRIVER_OBJECT, int);
|
||||||
VOID DeviceCreateDeleteTest(PDRIVER_OBJECT);
|
VOID DeviceCreateDeleteTest(PDRIVER_OBJECT);
|
||||||
VOID DeviceObjectTest(PDEVICE_OBJECT);
|
VOID DeviceObjectTest(PDEVICE_OBJECT);
|
||||||
|
@ -119,6 +175,19 @@ BOOLEAN DetachDeviceTest(PDEVICE_OBJECT);
|
||||||
BOOLEAN AttachDeviceTest(PDEVICE_OBJECT, PWCHAR);
|
BOOLEAN AttachDeviceTest(PDEVICE_OBJECT, PWCHAR);
|
||||||
VOID LowerDeviceKernelAPITest(PDEVICE_OBJECT, BOOLEAN);
|
VOID LowerDeviceKernelAPITest(PDEVICE_OBJECT, BOOLEAN);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TestStageExTimer = 0,
|
||||||
|
TestStageIoMdl,
|
||||||
|
TestStageIoDi,
|
||||||
|
TestStageIoIrp,
|
||||||
|
TestStageMmPoolTest,
|
||||||
|
TestStageMmPoolCorruption,
|
||||||
|
TestStageOb,
|
||||||
|
TestStageKeStall,
|
||||||
|
TestStageDrv,
|
||||||
|
TestStageMax
|
||||||
|
} TEST_STAGE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* KmtestDispatch
|
* KmtestDispatch
|
||||||
*/
|
*/
|
||||||
|
@ -192,39 +261,111 @@ KmtestUnload(IN PDRIVER_OBJECT DriverObject)
|
||||||
|
|
||||||
IoDeleteDevice(MainDeviceObject);
|
IoDeleteDevice(MainDeviceObject);
|
||||||
}
|
}
|
||||||
FinishTest("Driver Tests");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static
|
||||||
* DriverEntry
|
PKEY_VALUE_PARTIAL_INFORMATION
|
||||||
*/
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
NTAPI
|
||||||
DriverEntry(PDRIVER_OBJECT DriverObject,
|
ReadRegistryValue(HANDLE KeyHandle, PWCHAR ValueName)
|
||||||
PUNICODE_STRING RegistryPath)
|
|
||||||
{
|
{
|
||||||
int i;
|
NTSTATUS Status;
|
||||||
|
PKEY_VALUE_PARTIAL_INFORMATION InformationBuffer = NULL;
|
||||||
|
ULONG AllocatedLength = 0, RequiredLength = 0;
|
||||||
|
UNICODE_STRING ValueNameU;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&ValueNameU, ValueName);
|
||||||
|
|
||||||
|
Status = ZwQueryValueKey(KeyHandle,
|
||||||
|
&ValueNameU,
|
||||||
|
KeyValuePartialInformation,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
&RequiredLength);
|
||||||
|
if (Status == STATUS_BUFFER_TOO_SMALL || Status == STATUS_BUFFER_OVERFLOW)
|
||||||
|
{
|
||||||
|
InformationBuffer = ExAllocatePool(PagedPool, RequiredLength);
|
||||||
|
AllocatedLength = RequiredLength;
|
||||||
|
if (!InformationBuffer) return NULL;
|
||||||
|
|
||||||
|
Status = ZwQueryValueKey(KeyHandle,
|
||||||
|
&ValueNameU,
|
||||||
|
KeyValuePartialInformation,
|
||||||
|
InformationBuffer,
|
||||||
|
AllocatedLength,
|
||||||
|
&RequiredLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to read %S (0x%x)\n", ValueName, Status);
|
||||||
|
if (InformationBuffer != NULL)
|
||||||
|
ExFreePool(InformationBuffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return InformationBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
RunKernelModeTest(PDRIVER_OBJECT DriverObject,
|
||||||
|
PUNICODE_STRING RegistryPath,
|
||||||
|
HANDLE KeyHandle,
|
||||||
|
TEST_STAGE Stage)
|
||||||
|
{
|
||||||
|
UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"CurrentStage");
|
||||||
PWCHAR LowerDriverRegPath;
|
PWCHAR LowerDriverRegPath;
|
||||||
|
|
||||||
DbgPrint("\n===============================================\n");
|
DPRINT1("Running stage %d test...\n", Stage);
|
||||||
DbgPrint("Kernel Mode Regression Driver Test starting...\n");
|
|
||||||
DbgPrint("===============================================\n");
|
|
||||||
|
|
||||||
MainDeviceObject = NULL;
|
ZwSetValueKey(KeyHandle,
|
||||||
AttachDeviceObject = NULL;
|
&KeyName,
|
||||||
ThisDriverObject = DriverObject;
|
0,
|
||||||
|
REG_DWORD,
|
||||||
|
&Stage,
|
||||||
|
sizeof(ULONG));
|
||||||
|
|
||||||
NtoskrnlExecutiveTests();
|
switch (Stage)
|
||||||
NtoskrnlKeTests();
|
{
|
||||||
NtoskrnlIoTests();
|
case TestStageExTimer:
|
||||||
NtoskrnlObTest();
|
ExTimerTest(KeyHandle);
|
||||||
NtoskrnlPoolsTest();
|
break;
|
||||||
|
|
||||||
|
case TestStageIoMdl:
|
||||||
|
NtoskrnlIoMdlTest(KeyHandle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TestStageIoDi:
|
||||||
|
RegisterDI_Test(KeyHandle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TestStageIoIrp:
|
||||||
|
NtoskrnlIoIrpTest(KeyHandle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TestStageMmPoolTest:
|
||||||
|
PoolsTest(KeyHandle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TestStageMmPoolCorruption:
|
||||||
|
PoolsCorruption(KeyHandle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TestStageOb:
|
||||||
|
NtoskrnlObTest(KeyHandle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TestStageKeStall:
|
||||||
|
KeStallTest(KeyHandle);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TestStageDrv:
|
||||||
/* Start the tests for the driver routines */
|
/* Start the tests for the driver routines */
|
||||||
StartTest();
|
StartTest();
|
||||||
|
|
||||||
/* Do DriverObject Test for Driver Entry */
|
/* Do DriverObject Test for Driver Entry */
|
||||||
DriverObjectTest(DriverObject, 0);
|
DriverObjectTest(DriverObject, 0);
|
||||||
|
|
||||||
/* Create and delete device, on return MainDeviceObject has been created */
|
/* Create and delete device, on return MainDeviceObject has been created */
|
||||||
DeviceCreateDeleteTest(DriverObject);
|
DeviceCreateDeleteTest(DriverObject);
|
||||||
|
|
||||||
|
@ -254,11 +395,117 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
FinishTest(KeyHandle, L"DriverTest");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ASSERT(FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DriverEntry
|
||||||
|
*/
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DriverEntry(PDRIVER_OBJECT DriverObject,
|
||||||
|
PUNICODE_STRING RegistryPath)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
NTSTATUS Status;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING ParameterKeyName = RTL_CONSTANT_STRING(L"Parameters");
|
||||||
|
PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
|
||||||
|
PULONG KeyValue;
|
||||||
|
TEST_STAGE CurrentStage;
|
||||||
|
HANDLE DriverKeyHandle, ParameterKeyHandle;
|
||||||
|
|
||||||
|
DbgPrint("\n===============================================\n");
|
||||||
|
DbgPrint("Kernel Mode Regression Driver Test starting...\n");
|
||||||
|
DbgPrint("===============================================\n");
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
RegistryPath,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
Status = ZwOpenKey(&DriverKeyHandle,
|
||||||
|
KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
|
||||||
|
&ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to open %wZ\n", RegistryPath);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&ParameterKeyName,
|
||||||
|
OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
|
||||||
|
DriverKeyHandle,
|
||||||
|
NULL);
|
||||||
|
Status = ZwCreateKey(&ParameterKeyHandle,
|
||||||
|
KEY_SET_VALUE | KEY_QUERY_VALUE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
REG_OPTION_NON_VOLATILE,
|
||||||
|
NULL);
|
||||||
|
ZwClose(DriverKeyHandle);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to create %wZ\\%wZ\n", RegistryPath, &ParameterKeyName);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyInfo = ReadRegistryValue(ParameterKeyHandle, L"CurrentStage");
|
||||||
|
if (KeyInfo)
|
||||||
|
{
|
||||||
|
if (KeyInfo->DataLength != sizeof(ULONG))
|
||||||
|
{
|
||||||
|
DPRINT1("Invalid data length for CurrentStage: %d\n", KeyInfo->DataLength);
|
||||||
|
ExFreePool(KeyInfo);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyValue = (PULONG)KeyInfo->Data;
|
||||||
|
|
||||||
|
if ((*KeyValue) + 1 < TestStageMax)
|
||||||
|
{
|
||||||
|
DPRINT1("Resuming testing after a crash at stage %d\n", (*KeyValue));
|
||||||
|
|
||||||
|
CurrentStage = (TEST_STAGE)((*KeyValue) + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Testing was completed on a previous boot\n");
|
||||||
|
ExFreePool(KeyInfo);
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExFreePool(KeyInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Starting a fresh test\n");
|
||||||
|
CurrentStage = (TEST_STAGE)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run the tests */
|
||||||
|
while (CurrentStage < TestStageMax)
|
||||||
|
{
|
||||||
|
RunKernelModeTest(DriverObject,
|
||||||
|
RegistryPath,
|
||||||
|
ParameterKeyHandle,
|
||||||
|
CurrentStage);
|
||||||
|
CurrentStage++;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("Testing is complete!\n");
|
||||||
|
ZwClose(ParameterKeyHandle);
|
||||||
|
|
||||||
/* Set all MajorFunctions to NULL to verify that kernel fixes them */
|
/* Set all MajorFunctions to NULL to verify that kernel fixes them */
|
||||||
for (i = 1; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
for (i = 1; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
||||||
DriverObject->MajorFunction[i] = NULL;
|
DriverObject->MajorFunction[i] = NULL;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef PNPTEST_H
|
#ifndef KMTEST_H
|
||||||
#define PNPTEST_H
|
#define KMTEST_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -30,7 +30,7 @@ typedef struct
|
||||||
extern tls_data glob_data;
|
extern tls_data glob_data;
|
||||||
|
|
||||||
VOID StartTest();
|
VOID StartTest();
|
||||||
VOID FinishTest(LPSTR TestName);
|
VOID FinishTest(HANDLE KeyHandle, LPWSTR TestName);
|
||||||
void kmtest_set_location(const char* file, int line);
|
void kmtest_set_location(const char* file, int line);
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -51,4 +51,4 @@ PDEVICE_OBJECT AttachDeviceObject;
|
||||||
PDEVICE_OBJECT MainDeviceObject;
|
PDEVICE_OBJECT MainDeviceObject;
|
||||||
PDRIVER_OBJECT ThisDriverObject;
|
PDRIVER_OBJECT ThisDriverObject;
|
||||||
|
|
||||||
#endif /* PNPTEST_H */
|
#endif /* KMTEST_H */
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
<library>hal</library>
|
<library>hal</library>
|
||||||
<library>pseh</library>
|
<library>pseh</library>
|
||||||
<file>kmtest.c</file>
|
<file>kmtest.c</file>
|
||||||
<file>deviface.c</file>
|
|
||||||
<file>deviface_test.c</file>
|
<file>deviface_test.c</file>
|
||||||
<file>drvobj_test.c</file>
|
<file>drvobj_test.c</file>
|
||||||
<file>devobj_test.c</file>
|
<file>devobj_test.c</file>
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
#include <ndk/ntndk.h>
|
#include <ndk/ntndk.h>
|
||||||
#include "kmtest.h"
|
#include "kmtest.h"
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS ***********************************************************/
|
/* PRIVATE FUNCTIONS ***********************************************************/
|
||||||
|
@ -44,9 +44,10 @@ TestTimerApcRoutine(IN PVOID TimerContext,
|
||||||
(*ApcCount)++;
|
(*ApcCount)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS *************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
ExTimerTest()
|
ExTimerTest(HANDLE KeyHandle)
|
||||||
{
|
{
|
||||||
UNICODE_STRING TimerName;
|
UNICODE_STRING TimerName;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
@ -167,13 +168,5 @@ ExTimerTest()
|
||||||
Status = ZwClose(TimerHandle);
|
Status = ZwClose(TimerHandle);
|
||||||
ok(Status == STATUS_SUCCESS, "ZwClose failed with Status=0x%08lX", Status);
|
ok(Status == STATUS_SUCCESS, "ZwClose failed with Status=0x%08lX", Status);
|
||||||
|
|
||||||
FinishTest("NTOSKRNL Executive Timer");
|
FinishTest(KeyHandle, L"ExTimerTest");
|
||||||
}
|
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
||||||
|
|
||||||
VOID
|
|
||||||
NtoskrnlExecutiveTests()
|
|
||||||
{
|
|
||||||
ExTimerTest();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,10 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
VOID NtoskrnlIoDeviceInterface();
|
|
||||||
|
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
VOID NtoskrnlIoMdlTest()
|
VOID NtoskrnlIoMdlTest(HANDLE KeyHandle)
|
||||||
{
|
{
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
|
@ -81,10 +79,10 @@ VOID NtoskrnlIoMdlTest()
|
||||||
IoFreeIrp(Irp);
|
IoFreeIrp(Irp);
|
||||||
ExFreePool(VirtualAddress);
|
ExFreePool(VirtualAddress);
|
||||||
|
|
||||||
FinishTest("NTOSKRNL Io Mdl");
|
FinishTest(KeyHandle, L"IoMdlTest");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID NtoskrnlIoIrpTest()
|
VOID NtoskrnlIoIrpTest(HANDLE KeyHandle)
|
||||||
{
|
{
|
||||||
USHORT size;
|
USHORT size;
|
||||||
IRP *iorp;
|
IRP *iorp;
|
||||||
|
@ -166,12 +164,5 @@ VOID NtoskrnlIoIrpTest()
|
||||||
IoFreeIrp(iorp);
|
IoFreeIrp(iorp);
|
||||||
}
|
}
|
||||||
|
|
||||||
FinishTest("NTOSKRNL Io Irp");
|
FinishTest(KeyHandle, L"IoIrpTest");
|
||||||
}
|
|
||||||
|
|
||||||
VOID NtoskrnlIoTests()
|
|
||||||
{
|
|
||||||
NtoskrnlIoMdlTest();
|
|
||||||
NtoskrnlIoDeviceInterface();
|
|
||||||
NtoskrnlIoIrpTest();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,10 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
KeStallTest(HANDLE KeyHandle)
|
||||||
KeStallTest()
|
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
LARGE_INTEGER TimeStart, TimeFinish;
|
LARGE_INTEGER TimeStart, TimeFinish;
|
||||||
|
@ -74,13 +73,5 @@ KeStallTest()
|
||||||
KeQuerySystemTime(&TimeFinish);
|
KeQuerySystemTime(&TimeFinish);
|
||||||
DPRINT1("Time elapsed: %d secs\n", (TimeFinish.QuadPart - TimeStart.QuadPart) / 10000000); // 30
|
DPRINT1("Time elapsed: %d secs\n", (TimeFinish.QuadPart - TimeStart.QuadPart) / 10000000); // 30
|
||||||
|
|
||||||
FinishTest("NTOSKRNL KeStallmanExecution test");
|
FinishTest(KeyHandle, L"KeStallmanExecutionTest");
|
||||||
}
|
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
||||||
|
|
||||||
VOID
|
|
||||||
NtoskrnlKeTests()
|
|
||||||
{
|
|
||||||
KeStallTest();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <ddk/ntifs.h>
|
#include <ddk/ntifs.h>
|
||||||
#include "kmtest.h"
|
#include "kmtest.h"
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include "ntndk.h"
|
#include "ntndk.h"
|
||||||
|
@ -487,7 +487,7 @@ ObtReferenceTests()
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NtoskrnlObTest()
|
NtoskrnlObTest(HANDLE KeyHandle)
|
||||||
{
|
{
|
||||||
StartTest();
|
StartTest();
|
||||||
|
|
||||||
|
@ -515,5 +515,5 @@ NtoskrnlObTest()
|
||||||
ObtClose();
|
ObtClose();
|
||||||
DPRINT("Cleanup done\n");
|
DPRINT("Cleanup done\n");
|
||||||
|
|
||||||
FinishTest("NTOSKRNL Ob Manager");
|
FinishTest(KeyHandle, L"ObMgrTest");
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,15 +29,15 @@
|
||||||
#include <pseh/pseh2.h>
|
#include <pseh/pseh2.h>
|
||||||
#include "kmtest.h"
|
#include "kmtest.h"
|
||||||
|
|
||||||
//#define NDEBUG
|
#define NDEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define TAG_POOLTEST 'tstP'
|
#define TAG_POOLTEST 'tstP'
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
PoolsTest()
|
PoolsTest(HANDLE KeyHandle)
|
||||||
{
|
{
|
||||||
PVOID Ptr;
|
PVOID Ptr;
|
||||||
ULONG AllocSize, i, AllocNumber;
|
ULONG AllocSize, i, AllocNumber;
|
||||||
|
@ -124,11 +124,11 @@ PoolsTest()
|
||||||
ExFreePoolWithTag(Allocs, TAG_POOLTEST);
|
ExFreePoolWithTag(Allocs, TAG_POOLTEST);
|
||||||
|
|
||||||
|
|
||||||
FinishTest("NTOSKRNL Pools Tests");
|
FinishTest(KeyHandle, L"MmPoolAllocTest");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
PoolsCorruption()
|
PoolsCorruption(HANDLE KeyHandle)
|
||||||
{
|
{
|
||||||
PULONG Ptr, TestPtr;
|
PULONG Ptr, TestPtr;
|
||||||
ULONG AllocSize;
|
ULONG AllocSize;
|
||||||
|
@ -174,14 +174,5 @@ PoolsCorruption()
|
||||||
// free the pool
|
// free the pool
|
||||||
ExFreePoolWithTag(Ptr, TAG_POOLTEST);
|
ExFreePoolWithTag(Ptr, TAG_POOLTEST);
|
||||||
|
|
||||||
FinishTest("NTOSKRNL Pool Corruption");
|
FinishTest(KeyHandle, L"MmPoolCorruptionTest");
|
||||||
}
|
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
||||||
|
|
||||||
VOID
|
|
||||||
NtoskrnlPoolsTest()
|
|
||||||
{
|
|
||||||
PoolsTest();
|
|
||||||
//PoolsCorruption();
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue