- Add csqtest to build-system

- Add initial Kernel-Mode regression testing framework (thanks to Filip Navara for his PnPTest, thanks to Alexandre Julliard for Wine regression testing framework). Framework consists of: the driver (kmtest.sys) and the loader (kmtloader.exe).

svn path=/trunk/; revision=22208
This commit is contained in:
Aleksey Bragin 2006-06-04 14:18:24 +00:00
parent b5d6466d79
commit 42f34ff7ba
13 changed files with 1005 additions and 0 deletions

View file

@ -20,6 +20,9 @@
<directory name="storage">
<xi:include href="storage/directory.rbuild" />
</directory>
<directory name="test">
<xi:include href="test/directory.rbuild" />
</directory>
<directory name="usb">
<xi:include href="usb/directory.rbuild" />
</directory>

View file

@ -0,0 +1,9 @@
<module name="csqtest" type="kernelmodedriver" installbase="system32/drivers" installname="csqtest.sys">
<bootstrap base="reactos" />
<define name="__USE_W32API" />
<include base="ReactOS">include/reactos/drivers</include>
<library>ntoskrnl</library>
<library>hal</library>
<file>csqtest.c</file>
<file>csqtest.rc</file>
</module>

View file

@ -0,0 +1,6 @@
<directory name="csqtest">
<xi:include href="csqtest/csqtest.rbuild" />
</directory>
<directory name="kmtest">
<xi:include href="kmtest/kmtest.rbuild" />
</directory>

View file

@ -0,0 +1,542 @@
/*
* 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"
/* 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 STDCALL
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;
PKEY_BASIC_INFORMATION bip;
PKEY_VALUE_PARTIAL_INFORMATION vpip;
PWCHAR SymLinkList = NULL;
ULONG SymLinkListSize;
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;
}

View file

@ -0,0 +1,109 @@
/*
* PnP Test
* Device Interface functions test
*
* Copyright 2004 Filip Navara <xnavara@volny.cz>
*
* 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"
/* PRIVATE FUNCTIONS **********************************************************/
NTSTATUS STDCALL
(*IoGetDeviceInterfaces_Func)(
IN CONST GUID *InterfaceClassGuid,
IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL,
IN ULONG Flags,
OUT PWSTR *SymbolicLinkList);
NTSTATUS STDCALL
ReactOS_IoGetDeviceInterfaces(
IN CONST GUID *InterfaceClassGuid,
IN PDEVICE_OBJECT PhysicalDeviceObject OPTIONAL,
IN ULONG Flags,
OUT PWSTR *SymbolicLinkList);
VOID FASTCALL DeviceInterfaceTest_Func()
{
NTSTATUS Status;
PWSTR SymbolicLinkList;
PWSTR SymbolicLinkListPtr;
GUID Guid = {0x378de44c, 0x56ef, 0x11d1, {0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd}};
Status = IoGetDeviceInterfaces_Func(
&Guid,
NULL,
0,
&SymbolicLinkList);
if (!NT_SUCCESS(Status))
{
DPRINT(
"[PnP Test] IoGetDeviceInterfaces failed with status 0x%X\n",
Status);
return;
}
DPRINT("[PnP Test] IoGetDeviceInterfaces results:\n");
for (SymbolicLinkListPtr = SymbolicLinkList;
SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0;
SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1)
{
DPRINT("[PnP Test] %S\n", SymbolicLinkListPtr);
}
#if 0
DPRINT("[PnP Test] Trying to get aliases\n");
for (SymbolicLinkListPtr = SymbolicLinkList;
SymbolicLinkListPtr[0] != 0 && SymbolicLinkListPtr[1] != 0;
SymbolicLinkListPtr += wcslen(SymbolicLinkListPtr) + 1)
{
UNICODE_STRING SymbolicLink;
UNICODE_STRING AliasSymbolicLink;
SymbolicLink.Buffer = SymbolicLinkListPtr;
SymbolicLink.Length = SymbolicLink.MaximumLength = wcslen(SymbolicLinkListPtr);
RtlInitUnicodeString(&AliasSymbolicLink, NULL);
IoGetDeviceInterfaceAlias(
&SymbolicLink,
&AliasGuid,
&AliasSymbolicLink);
if (AliasSymbolicLink.Buffer != NULL)
{
DPRINT("[PnP Test] Original: %S\n", SymbolicLinkListPtr);
DPRINT("[PnP Test] Alias: %S\n", AliasSymbolicLink.Buffer);
}
}
#endif
ExFreePool(SymbolicLinkList);
}
VOID FASTCALL DeviceInterfaceTest()
{
DPRINT("Calling DeviceInterfaceTest_Func with native functions\n");
IoGetDeviceInterfaces_Func = IoGetDeviceInterfaces;
DeviceInterfaceTest_Func();
DPRINT("Calling DeviceInterfaceTest_Func with ReactOS functions\n");
IoGetDeviceInterfaces_Func = ReactOS_IoGetDeviceInterfaces;
DeviceInterfaceTest_Func();
}

View file

@ -0,0 +1,122 @@
/*
* Kernel Mode regression Test
* Driver Core
*
* Copyright 2004 Filip Navara <xnavara@volny.cz>
*
* 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"
ULONG successes;
ULONG failures;
tls_data glob_data;
/* PRIVATE FUNCTIONS ***********************************************************/
VOID
StartTest()
{
successes = 0;
failures = 0;
}
VOID
FinishTest(LPSTR TestName)
{
DbgPrint("Test %s finished with %d succeses and %d failures\n", TestName, successes, failures);
}
void kmtest_set_location(const char* file, int line)
{
glob_data.current_file=strrchr(file,'/');
if (glob_data.current_file==NULL)
glob_data.current_file=strrchr(file,'\\');
if (glob_data.current_file==NULL)
glob_data.current_file=file;
else
glob_data.current_file++;
glob_data.current_line=line;
}
/*
* Checks condition.
* Parameters:
* - condition - condition to check;
* - msg test description;
* - file - test application source code file name of the check
* - line - test application source code file line number of the check
* Return:
* 0 if condition does not have the expected value, 1 otherwise
*/
int kmtest_ok(int condition, const char *msg, ... )
{
va_list valist;
if (!condition)
{
if (msg[0])
{
char string[1024];
va_start(valist, msg);
vsprintf(string, msg, valist);
DbgPrint( "%s:%d: Test failed: %s\n",
glob_data.current_file, glob_data.current_line, string );
va_end(valist);
}
else
{
DbgPrint( "%s:%d: Test failed\n",
glob_data.current_file, glob_data.current_line );
}
InterlockedIncrement(&failures);
return 0;
}
else
{/*
if (report_success)
fprintf( stdout, "%s:%d: Test succeeded\n",
glob_data.current_file, glob_data.current_line);*/
InterlockedIncrement(&successes);
}
return 1;
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*
* Test Declarations
*/
VOID FASTCALL DeviceInterfaceTest();
VOID FASTCALL NtoskrnlIoMdlTest();
/*
* DriverEntry
*/
NTSTATUS
NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
{
DbgPrint("Kernel Mode Regression Test driver starting...\n");
//DeviceInterfaceTest();
NtoskrnlIoMdlTest();
return STATUS_UNSUCCESSFUL;
}

View file

@ -0,0 +1,53 @@
#ifndef PNPTEST_H
#define PNPTEST_H
#include <stdio.h>
#include <stdarg.h>
/*
Some macros, structs, and vars are based or inspired from the great
Wine regression tests Copyright (C) 2002 Alexandre Julliard.
Everything else is done by Aleksey Bragin based on PnPTest by Filip Navara
*/
#if 0
#define DPRINT DbgPrint("%s:%d ", __FILE__, __LINE__), DbgPrint
#else
#define DPRINT DbgPrint
#endif
extern ULONG successes; /* number of successful tests */
extern ULONG failures; /* number of failures */
//static ULONG todo_successes; /* number of successful tests inside todo block */
//static ULONG todo_failures; /* number of failures inside todo block */
// We don't do multithreading, so we just keep this struct in a global var
typedef struct
{
const char* current_file; /* file of current check */
int current_line; /* line of current check */
int todo_level; /* current todo nesting level */
int todo_do_loop;
} tls_data;
extern tls_data glob_data;
VOID StartTest();
VOID FinishTest(LPSTR TestName);
void kmtest_set_location(const char* file, int line);
#ifdef __GNUC__
extern int kmtest_ok( int condition, const char *msg, ... ) __attribute__((format (printf,2,3) ));
#else /* __GNUC__ */
extern int kmtest_ok( int condition, const char *msg, ... );
#endif /* __GNUC__ */
#define ok_(file, line) (kmtest_set_location(file, line), 0) ? 0 : kmtest_ok
#define ok ok_(__FILE__, __LINE__)
#endif /* PNPTEST_H */

View file

@ -0,0 +1,12 @@
<module name="kmtest" type="kernelmodedriver" installbase="system32/drivers" installname="kmtest.sys">
<bootstrap base="reactos" />
<define name="__USE_W32API" />
<include base="ReactOS">include/reactos/drivers</include>
<library>ntoskrnl</library>
<library>hal</library>
<file>kmtest.c</file>
<file>deviface.c</file>
<file>deviface_test.c</file>
<file>ntos_io.c</file>
<file>kmtest.rc</file>
</module>

View file

@ -0,0 +1,7 @@
/* $Id: csqtest.rc 21842 2006-05-07 19:16:11Z ion $ */
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "Kernel Mode Regression Tests\0"
#define REACTOS_STR_INTERNAL_NAME "kmtest\0"
#define REACTOS_STR_ORIGINAL_FILENAME "kmtest.sys\0"
#include <reactos/version.rc>

View file

@ -0,0 +1,44 @@
/*
* NTOSKRNL Io Regressions KM-Test
* ReactOS Device Interface functions implementation
*
* Copyright 2006 Aleksey Bragin <aleksey@reactos.org>
*
* 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"
/* PUBLIC FUNCTIONS ***********************************************************/
VOID FASTCALL NtoskrnlIoMdlTest()
{
PMDL Mdl;
StartTest();
// Try to alloc 2Gb MDL
Mdl = IoAllocateMdl(NULL, 2048UL*0x100000, FALSE, FALSE, NULL);
ok(Mdl == NULL, "IoAllocateMdl should fail allocation of 2Gb or more, but got Mdl=0x%X", (UINT)Mdl);
if (Mdl)
IoFreeMdl(Mdl);
FinishTest("NTOSKRNL Io Mdl");
}

View file

@ -1,4 +1,7 @@
<group>
<directory name="kmtloader">
<xi:include href="kmtloader/kmtloader.rbuild" />
</directory>
<directory name="regtests">
<xi:include href="regtests/regtests.rbuild" />
</directory>

View file

@ -0,0 +1,90 @@
/*
* Kernel-Mode Tests Loader (based on PnP Test Driver Loader by Filip Navara)
*
* Copyright 2004 Filip Navara <xnavara@volny.cz>
*
* 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 <windows.h>
#include <stdio.h>
/* PUBLIC FUNCTIONS ***********************************************************/
int main()
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
PWCHAR DriverName = L"KMTEST";
WCHAR ServiceExe[MAX_PATH];
printf("Kernel Mode Tests loader\n\n");
GetCurrentDirectoryW(MAX_PATH, ServiceExe);
wcscat(ServiceExe, L"\\kmtest.sys");
printf("Opening SC Manager...\n");
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
{
DWORD Err = GetLastError();
printf("OpenSCManager failed with error 0x%lx\n", Err);
return 0;
}
printf("Creating service...\n");
schService = CreateServiceW(
schSCManager,
DriverName,
DriverName,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
ServiceExe,
NULL,
NULL,
NULL,
NULL,
NULL);
if (schService == NULL)
{
printf("Opening service...\n");
schService = OpenServiceW(schSCManager, DriverName, SERVICE_ALL_ACCESS);
}
if (schService == NULL)
{
DWORD Err = GetLastError();
printf("Create/OpenService failed with error 0x%lx\n", Err);
CloseServiceHandle(schSCManager);
return 0;
}
//for (;;) ;
printf("Starting service...\n");
StartService(schService, 0, NULL);
printf("Cleaning up and exiting\n");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return 0;
}

View file

@ -0,0 +1,5 @@
<module name="kmtloader" type="win32cui" installbase="system32" installname="kmtloader.exe">
<define name="__USE_W32API" />
<!-- <library>kernel32</library>-->
<file>kmtloader.c</file>
</module>