diff options
Diffstat (limited to '')
-rw-r--r-- | private/windbg/driver/crashdrv/crashdrv.c | 225 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/crashdrv.h | 58 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/crashdrv.rc | 11 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/dirs | 1 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/driver/makefile | 6 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/driver/sources | 12 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/tests.c | 266 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/tests/install.c | 83 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/tests/install.rc | 11 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/tests/makefile | 6 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/tests/makefile.inc | 3 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/tests/sources | 17 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/tests/test.c | 295 | ||||
-rw-r--r-- | private/windbg/driver/crashdrv/tests/test.rc | 11 |
14 files changed, 1005 insertions, 0 deletions
diff --git a/private/windbg/driver/crashdrv/crashdrv.c b/private/windbg/driver/crashdrv/crashdrv.c new file mode 100644 index 000000000..e81655b9c --- /dev/null +++ b/private/windbg/driver/crashdrv/crashdrv.c @@ -0,0 +1,225 @@ +#include <ntddk.h> +#include <string.h> +#include "crashdrv.h" + + +#define MEMSIZE 4096 +#define FCN(cc) ((cc >> 2) & 0xFFFFFF) +#define DEVICE_NAME L"\\Device\\CrashDrv" +#define DOSDEVICE_NAME L"\\DosDevices\\CrashDrv" + + +typedef VOID (*PTESTFUNC)(PULONG ub); + +PTESTFUNC tests[] = + { + NULL, + CrashDrvBugCheck, + CrashDrvStackOverFlow, + CrashDrvSimpleTest, + CrashDrvExceptionTest, + CrashDrvHardError, + CrashSpecial + }; + +#define MaxTests (sizeof(tests)/sizeof(PTESTFUNC)) + +ULONG CrashDrvRequest; +KEVENT CrashEvent; +ULONG CrashRequest; +PULONG Funk; + + +NTSTATUS +CrashDrvOpenClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +VOID +CrashDrvUnload( + IN PDRIVER_OBJECT DriverObject + ); + +NTSTATUS +CrashDrvIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ); + +VOID +CrashThread( + PVOID Context + ); + + + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + UNICODE_STRING DeviceName; + PDEVICE_OBJECT deviceObject; + NTSTATUS status; + UNICODE_STRING LinkObject; + WCHAR LinkName[80]; + ULONG DeviceSize; + HANDLE ThreadHandle; + + + RtlInitUnicodeString( &DeviceName, DEVICE_NAME ); + status = IoCreateDevice( DriverObject, + 0, + &DeviceName, + FILE_DEVICE_NULL, + 0, + FALSE, + &deviceObject ); + if (!NT_SUCCESS( status )) { + return status; + } + + LinkName[0] = UNICODE_NULL; + + RtlInitUnicodeString(&LinkObject, LinkName); + + LinkObject.MaximumLength = sizeof(LinkName); + + RtlAppendUnicodeToString(&LinkObject, L"\\DosDevices"); + + DeviceSize = sizeof(L"\\Device") - sizeof(UNICODE_NULL); + DeviceName.Buffer += DeviceSize / sizeof(WCHAR); + DeviceName.Length -= (USHORT)DeviceSize; + + RtlAppendUnicodeStringToString(&LinkObject, &DeviceName); + + DeviceName.Buffer -= DeviceSize / sizeof(WCHAR); + DeviceName.Length += (USHORT)DeviceSize; + + status = IoCreateSymbolicLink(&LinkObject, &DeviceName); + + if (!NT_SUCCESS(status)) { + IoDeleteDevice( deviceObject ); + return status; + } + + DriverObject->MajorFunction[IRP_MJ_CREATE] = CrashDrvOpenClose; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = CrashDrvOpenClose; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CrashDrvIoControl; + DriverObject->DriverUnload = CrashDrvUnload; + + KeInitializeEvent( &CrashEvent, NotificationEvent, FALSE ); + + Funk = ExAllocatePool( PagedPool, MEMSIZE ); + + status = PsCreateSystemThread( + &ThreadHandle, + 0, + NULL, + 0, + NULL, + CrashThread, + NULL + ); + + return STATUS_SUCCESS; +} + +NTSTATUS +CrashDrvOpenClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) +{ + NTSTATUS status = STATUS_SUCCESS; + + Irp->IoStatus.Status = status; + Irp->IoStatus.Information = 0; + status = Irp->IoStatus.Status; + IoCompleteRequest( Irp, 0 ); + + return status; +} + +VOID +CrashDrvUnload( + IN PDRIVER_OBJECT DriverObject + ) +{ + PDEVICE_OBJECT currentDevice = DriverObject->DeviceObject; + UNICODE_STRING fullLinkName; + + while (currentDevice) { + + RtlInitUnicodeString( &fullLinkName, DOSDEVICE_NAME ); + IoDeleteSymbolicLink(&fullLinkName); + IoDeleteDevice(currentDevice); + + currentDevice = DriverObject->DeviceObject; + + } +} + +NTSTATUS +CrashDrvIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) +{ + NTSTATUS Status = STATUS_SUCCESS; + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + PULONG ub; + + + ub = (PULONG) MmGetSystemAddressForMdl( Irp->MdlAddress ); + + if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_CRASHDRV_CHECK_REQUEST) { + ub[0] = CrashDrvRequest; + CrashDrvRequest = 0; + } else { + if (FCN(IrpSp->Parameters.DeviceIoControl.IoControlCode) > MaxTests) { + DbgBreakPoint(); + } else { + tests[FCN(IrpSp->Parameters.DeviceIoControl.IoControlCode)]( ub ); + } + } + + Irp->IoStatus.Information = 0L; + Irp->IoStatus.Status = Status; + IoCompleteRequest( Irp, 0 ); + + return Status; +} + + +VOID +CrashThread( + PVOID Context + ) +{ + while( TRUE ) { + KeWaitForSingleObject( &CrashEvent, Executive, KernelMode, FALSE, NULL ); + KeResetEvent( &CrashEvent ); + switch( CrashRequest ) { + case KMODE_EXCEPTION_NOT_HANDLED: + { + ULONG i,j; + i = 0; + j = 0; + i = j / i; + } + break; + + case IRQL_NOT_LESS_OR_EQUAL: + { + KIRQL irql; + KeRaiseIrql( DISPATCH_LEVEL, &irql ); + Funk[0] = 0; + KeLowerIrql( irql ); + } + break; + } + } +} diff --git a/private/windbg/driver/crashdrv/crashdrv.h b/private/windbg/driver/crashdrv/crashdrv.h new file mode 100644 index 000000000..e9d5e4027 --- /dev/null +++ b/private/windbg/driver/crashdrv/crashdrv.h @@ -0,0 +1,58 @@ +// +// CrashDrv driver/test constants +// + +#define FILE_DEVICE_CRASHDRV 0x00008000 + + +#define TEST_CHECK_REQUEST 0 +#define TEST_BUGCHECK 1 +#define TEST_STACK_OVERFLOW 2 +#define TEST_SIMPLE 3 +#define TEST_EXCEPTION 4 +#define TEST_HARDERR 5 +#define TEST_SPECIAL 6 + +#define IOCTL_CRASHDRV_CHECK_REQUEST CTL_CODE(FILE_DEVICE_CRASHDRV, TEST_CHECK_REQUEST, METHOD_OUT_DIRECT,FILE_ANY_ACCESS) +#define IOCTL_CRASHDRV_BUGCHECK CTL_CODE(FILE_DEVICE_CRASHDRV, TEST_BUGCHECK, METHOD_OUT_DIRECT,FILE_ANY_ACCESS) +#define IOCTL_CRASHDRV_STACK_OVERFLOW CTL_CODE(FILE_DEVICE_CRASHDRV, TEST_STACK_OVERFLOW, METHOD_OUT_DIRECT,FILE_ANY_ACCESS) +#define IOCTL_CRASHDRV_SIMPLE CTL_CODE(FILE_DEVICE_CRASHDRV, TEST_SIMPLE, METHOD_OUT_DIRECT,FILE_ANY_ACCESS) +#define IOCTL_CRASHDRV_EXCEPTION CTL_CODE(FILE_DEVICE_CRASHDRV, TEST_EXCEPTION, METHOD_OUT_DIRECT,FILE_ANY_ACCESS) +#define IOCTL_CRASHDRV_HARDERR CTL_CODE(FILE_DEVICE_CRASHDRV, TEST_HARDERR, METHOD_OUT_DIRECT,FILE_ANY_ACCESS) +#define IOCTL_CRASHDRV_SPECIAL CTL_CODE(FILE_DEVICE_CRASHDRV, TEST_SPECIAL, METHOD_OUT_DIRECT,FILE_ANY_ACCESS) + + +// +// prototypes +// + +VOID +CrashDrvStackOverFlow( + PULONG ub + ); + +VOID +CrashDrvBugCheck( + PULONG ub + ); + +VOID +CrashDrvSimpleTest( + PULONG ub + ); + +VOID +CrashDrvExceptionTest( + PULONG ub + ); + +VOID +CrashDrvHardError( + PULONG ub + ); + +VOID +CrashSpecial( + PULONG ub + ); + diff --git a/private/windbg/driver/crashdrv/crashdrv.rc b/private/windbg/driver/crashdrv/crashdrv.rc new file mode 100644 index 000000000..4eeecf024 --- /dev/null +++ b/private/windbg/driver/crashdrv/crashdrv.rc @@ -0,0 +1,11 @@ +#include <windows.h> + +#include <ntverp.h> + +#define VER_FILETYPE VFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_SYSTEM +#define VER_FILEDESCRIPTION_STR "Crash Driver" +#define VER_INTERNALNAME_STR "crashdrv.sys" + +#include "common.ver" + diff --git a/private/windbg/driver/crashdrv/dirs b/private/windbg/driver/crashdrv/dirs new file mode 100644 index 000000000..b84056424 --- /dev/null +++ b/private/windbg/driver/crashdrv/dirs @@ -0,0 +1 @@ +DIRS=driver tests diff --git a/private/windbg/driver/crashdrv/driver/makefile b/private/windbg/driver/crashdrv/driver/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/windbg/driver/crashdrv/driver/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/windbg/driver/crashdrv/driver/sources b/private/windbg/driver/crashdrv/driver/sources new file mode 100644 index 000000000..b0b9ea22f --- /dev/null +++ b/private/windbg/driver/crashdrv/driver/sources @@ -0,0 +1,12 @@ +MAJORCOMP=windbg +MINORCOMP=driver + +TARGETNAME=crashdrv +TARGETPATH=obj +TARGETTYPE=DRIVER + +INCLUDES=$(BASEDIR)\private\ntos\inc + +SOURCES=..\crashdrv.c ..\tests.c ..\crashdrv.rc + +LINKER_FLAGS=-miscrdata diff --git a/private/windbg/driver/crashdrv/tests.c b/private/windbg/driver/crashdrv/tests.c new file mode 100644 index 000000000..d9e5143e1 --- /dev/null +++ b/private/windbg/driver/crashdrv/tests.c @@ -0,0 +1,266 @@ +#include <ntos.h> +#include <nturtl.h> +#include <ntexapi.h> + +extern KEVENT CrashEvent; +extern ULONG CrashRequest; + +unsigned int fExcept1 = 0; +unsigned int cTry1 = 0; +unsigned int cRaise1pre = 0; +unsigned int cRaise1post = 0; +unsigned int cExcept1 = 0; +unsigned int cFilter1 = 0; + +unsigned int fExcept2 = 0; +unsigned int cTry2 = 0; +unsigned int cRaise2pre = 0; +unsigned int cRaise2post = 0; +unsigned int cFinally2 = 0; + +unsigned int fExcept3 = 0; +unsigned int cTry3 = 0; +unsigned int cRaise3pre = 0; +unsigned int cRaise3post = 0; +unsigned int cExcept3 = 0; +unsigned int cFilter3 = 0; + +unsigned int fExcept4 = 0; +unsigned int cTry4 = 0; +unsigned int cRaise4pre = 0; +unsigned int cRaise4post = 0; +unsigned int cFinally4 = 0; + +unsigned int fExcept5 = 0; +unsigned int cTry5 = 0; +unsigned int cRaise5pre = 0; +unsigned int cRaise5post = 0; +unsigned int cExcept5 = 0; +unsigned int cFilter5 = 0; + +unsigned long GlobalVar = 0; + +int ExceptFilterFn5 (int ExceptCode) +{ + DbgPrint( "CrashDrv exception filter\n" ); + cFilter5 ++; + return ExceptCode == 0x00003344 ? EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_EXECUTION ; +} + +void function5 () +{ + _try + { + cTry5 ++; + if (fExcept5) + { + cRaise5pre ++; + ExRaiseStatus( fExcept4 ); + cRaise5post ++; + } + } + _except (ExceptFilterFn5 (GetExceptionCode ())) + { + cExcept5 ++; + } +} + +void function4 () +{ + _try + { + cTry4 ++; + function5 (); + if (fExcept4) + { + cRaise4pre ++; + ExRaiseStatus( fExcept4 ); + cRaise4post ++; + } + } + _finally + { + cFinally4 ++; + } +} + +int ExceptFilterFn3 (int ExceptCode) +{ + cFilter3 ++; + return ExceptCode == 0x00005678 ? EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH ; +} + +void function3 () +{ + _try + { + cTry3 ++; + function4 (); + if (fExcept3) + { + cRaise3pre ++; + ExRaiseStatus( fExcept3 ); + cRaise3post ++; + } + } + _except (ExceptFilterFn3 (GetExceptionCode ())) + { + cExcept3 ++; + } +} + +void function2 () +{ + _try + { + cTry2 ++; + function3 (); + if (fExcept2) + { + cRaise2pre ++; + ExRaiseStatus( fExcept2 ); + cRaise2post ++; + } + } + _finally + { + cFinally2 ++; + } +} + +int ExceptFilterMain (int ExceptCode) +{ + cFilter1 ++; + return ExceptCode == 0x00001010 ? EXCEPTION_EXECUTE_HANDLER : + ExceptCode == 0x00005678 ? EXCEPTION_CONTINUE_EXECUTION : + EXCEPTION_CONTINUE_SEARCH ; +} + +VOID +CrashDrvExceptionTest( + PULONG ub + ) +{ + int i = 0; + + while ( i++ < 10 ) { + _try { + cTry1 ++; + function2 (); + if (fExcept1) { + cRaise1pre ++; + ExRaiseStatus( fExcept1 ); + cRaise1post ++; + } + } + _except (ExceptFilterMain (GetExceptionCode ())) { + cExcept1 ++; + } + fExcept1 = 0; + fExcept2 = 0; + fExcept3 = 0; + fExcept4 = 0; + fExcept5 = 0; + } +} + +VOID +CrashDrvSimpleTest( + PULONG ub + ) +{ + int i = 0; + int j = 0; + int k = 0; + GlobalVar = 69; + i = 1; + j = 2; + k = 3; +} + +VOID +CrashDrvStackOverFlow( + PULONG ub + ) +{ +} + +VOID +CrashDrvBugCheck( + PULONG ub + ) +{ + KeBugCheck( 0x69696969 ); +} + +VOID +CrashDrvHardError( + PULONG ub + ) +{ + NTSTATUS Status; + NTSTATUS ErrorCode; + ULONG Response; + + + ErrorCode = STATUS_SYSTEM_PROCESS_TERMINATED; + + Status = ExRaiseHardError( + ErrorCode, + 0, + 0, + NULL, + OptionShutdownSystem, + &Response + ); + + return; +} + + +ULONG CurrentWatchPoint=0; + +VOID +AsyncSetBreakPoint( + ULONG LinearAddress + ) +{ +#ifdef i386 + CurrentWatchPoint = LinearAddress; + + _asm { + mov eax, LinearAddress + mov dr0, eax + mov eax, 10303h + mov dr7, eax + } +#endif +} + +VOID +AsyncRemoveBreakPoint( + ULONG LinearAddress + ) +{ +#ifdef i386 + CurrentWatchPoint = 0; + + _asm { + mov eax, 0 + mov dr7, eax + } +#endif +} + +#pragma optimize ( "", on ) + +VOID +CrashSpecial( + PULONG ub + ) +{ + CrashRequest = ub[0]; + KeSetEvent( &CrashEvent, 0, FALSE ); +} diff --git a/private/windbg/driver/crashdrv/tests/install.c b/private/windbg/driver/crashdrv/tests/install.c new file mode 100644 index 000000000..1f67de05d --- /dev/null +++ b/private/windbg/driver/crashdrv/tests/install.c @@ -0,0 +1,83 @@ +/*++ + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + install.c + +Abstract: + + This module contains the code that implements a driver installation + +Author: + + Wesley Witt (wesw) 1-Oct-1993 + +Environment: + + User mode + +Notes: + +Revision History: + + +--*/ + +#include <windows.h> +#include <winsvc.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define SERVICE_NAME "CrashDrv" +#define DRIVER_NAME "\\systemroot\\system32\\drivers\\CrashDrv.sys" + + +void _cdecl main( void ) +{ + SC_HANDLE hService; + SC_HANDLE hOldService; + SERVICE_STATUS ServStat; + CHAR buf[MAX_PATH]; + + + if( !( hService = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ) ) ) { + printf( "Error: Could not open handle to service manager for CrashDrv driver; error code = %u\n", GetLastError() ); + return; + } + if( hOldService = OpenService( hService, SERVICE_NAME, SERVICE_ALL_ACCESS ) ) { + if( ! ControlService( hOldService, SERVICE_CONTROL_STOP, & ServStat ) ) { + int fError = GetLastError(); + if( ( fError != ERROR_SERVICE_NOT_ACTIVE ) && ( fError != ERROR_INVALID_SERVICE_CONTROL ) ) { + printf( "Error: Could not stop %s service; error code = %u\n", SERVICE_NAME, fError ); + return; + } + } + if( ! DeleteService( hOldService ) ) { + printf( "Error: Could not delete old service for %s driver; error code = %u\n", SERVICE_NAME, GetLastError() ); + return; + } + if( ! CloseServiceHandle( hOldService ) ) { + printf( "Error: Could not delete old service for %s driver; error code = %u\n", SERVICE_NAME, GetLastError() ); + return; + } + } + if( ! CreateService( hService, SERVICE_NAME, SERVICE_NAME, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, + SERVICE_ERROR_NORMAL, DRIVER_NAME, "Extended base", NULL, NULL, NULL, NULL ) ) { + int fError = GetLastError(); + if( fError != ERROR_SERVICE_EXISTS ) { + printf( "Error: Could not create %s service; error code = %u\n", SERVICE_NAME, fError ); + return; + } + } + if( ! CloseServiceHandle( hService ) ) { + printf( "Error: Could not close handle to service manager for %s driver; error code = %u\n", SERVICE_NAME, GetLastError() ); + return; + } + + GetEnvironmentVariable( "systemroot", buf, sizeof(buf) ); + strcat( buf, "\\system32\\drivers\\CrashDrv.sys" ); + CopyFile( "CrashDrv.sys", buf, FALSE ); +} diff --git a/private/windbg/driver/crashdrv/tests/install.rc b/private/windbg/driver/crashdrv/tests/install.rc new file mode 100644 index 000000000..34b3cfa93 --- /dev/null +++ b/private/windbg/driver/crashdrv/tests/install.rc @@ -0,0 +1,11 @@ +#include <windows.h> +#include <ntverp.h> + +#define VER_FILETYPE VFT_APP +#define VER_FILESUBTYPE VFT2_UNKNOWN +#define VER_FILEDESCRIPTION_STR "Microsoft\256 Kernel Crash Driver Install Utility" + +#define VER_INTERNALNAME_STR "install.exe" +#define VER_ORIGINALFILENAME_STR "install.exe" + +#include <common.ver> diff --git a/private/windbg/driver/crashdrv/tests/makefile b/private/windbg/driver/crashdrv/tests/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/windbg/driver/crashdrv/tests/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/windbg/driver/crashdrv/tests/makefile.inc b/private/windbg/driver/crashdrv/tests/makefile.inc new file mode 100644 index 000000000..577865208 --- /dev/null +++ b/private/windbg/driver/crashdrv/tests/makefile.inc @@ -0,0 +1,3 @@ +obj\$(TARGET_DIRECTORY)\test.res: test.rc + +obj\$(TARGET_DIRECTORY)\install.res: install.rc diff --git a/private/windbg/driver/crashdrv/tests/sources b/private/windbg/driver/crashdrv/tests/sources new file mode 100644 index 000000000..049a81ec4 --- /dev/null +++ b/private/windbg/driver/crashdrv/tests/sources @@ -0,0 +1,17 @@ +MAJORCOMP=windbg +MINORCOMP=driver + +TARGETNAME=crashdrv +TARGETPATH=obj +TARGETTYPE=LIBRARY + +INCLUDES=$(BASEDIR)\private\ntos\inc;..\ + +SOURCES= + +UMTYPE=console +UMAPPL=test*install +UMRES=$(@R).res + +NTTARGETFILE0=obj\*\test.res \ + obj\*\install.res diff --git a/private/windbg/driver/crashdrv/tests/test.c b/private/windbg/driver/crashdrv/tests/test.c new file mode 100644 index 000000000..68b13fad8 --- /dev/null +++ b/private/windbg/driver/crashdrv/tests/test.c @@ -0,0 +1,295 @@ +#include <windows.h> +#include <winioctl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "crashdrv.h" + +#define CRASHDRV_DEVICE "\\\\.\\CrashDrv" +#define KMODE_EXCEPTION_NOT_HANDLED ((ULONG)0x0000001EL) +#define IRQL_NOT_LESS_OR_EQUAL ((ULONG)0x0000000AL) + +typedef struct _TESTINFO { + DWORD CtlCode; + DWORD TestNum; + LPSTR Description; +} TESTINFO, *LPTESTINFO; + +TESTINFO TestInformation[] = + { + 0, 0, NULL, + (DWORD)IOCTL_CRASHDRV_BUGCHECK, TEST_BUGCHECK, "Bugcheck", + (DWORD)IOCTL_CRASHDRV_STACK_OVERFLOW, TEST_STACK_OVERFLOW, "Stack overflow", + (DWORD)IOCTL_CRASHDRV_SIMPLE, TEST_SIMPLE, "Simple", + (DWORD)IOCTL_CRASHDRV_EXCEPTION, TEST_EXCEPTION, "Exception", + (DWORD)IOCTL_CRASHDRV_HARDERR, TEST_HARDERR, "Hard error", + (DWORD)IOCTL_CRASHDRV_SPECIAL, TEST_SPECIAL, "Special" + }; + +#define MaxTests (sizeof(TestInformation)/sizeof(TESTINFO)) + +DWORD IoctlBuf[16]; +DWORD TestNumber; + +VOID GetCommandLineArgs(VOID); +VOID Usage(VOID); +DWORD CrashDrvCheckRequest(HANDLE); +BOOL StartCrashDrvService(VOID); + +void _cdecl +main( void ) +{ + HANDLE hCrashDrv; + DWORD rq; + DWORD ReturnedByteCount; + + + ZeroMemory( IoctlBuf, sizeof(IoctlBuf) ); + + GetCommandLineArgs(); + + if (!StartCrashDrvService()) { + return; + } + + hCrashDrv = CreateFile( CRASHDRV_DEVICE, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + if ( hCrashDrv == INVALID_HANDLE_VALUE ) { + printf("Could not open the CrashDrv device (%d)\n",GetLastError()); + ExitProcess(1); + } + + printf("Successfuly opened the CrashDrv device\n"); + + if (TestNumber) { + if (TestNumber > MaxTests) { + printf( "invalid test number\n" ); + Usage(); + } + if (!DeviceIoControl( + hCrashDrv, + TestInformation[TestNumber].CtlCode, + NULL, + 0, + IoctlBuf, + sizeof(IoctlBuf), + &ReturnedByteCount, + NULL + )) { + printf( "call to driver failed <ec=%d>\n", GetLastError() ); + } + return; + } + + while( TRUE ) { + + rq = CrashDrvCheckRequest( hCrashDrv ); + + if (rq) { + if (!DeviceIoControl( + hCrashDrv, + CTL_CODE(FILE_DEVICE_CRASHDRV, rq, METHOD_BUFFERED,FILE_ANY_ACCESS), + NULL, + 0, + IoctlBuf, + sizeof(IoctlBuf), + &ReturnedByteCount, + NULL + )) { + printf( "call to driver failed <ec=%d>\n", GetLastError() ); + } + } + + Sleep(500); + } + + CloseHandle( hCrashDrv ); + return; +} + + +DWORD +CrashDrvCheckRequest( + HANDLE hCrashDrv + ) +{ + DWORD ReturnedByteCount; + BOOL rc; + + + ZeroMemory( IoctlBuf, sizeof(IoctlBuf) ); + + rc = DeviceIoControl( + hCrashDrv, + (DWORD)IOCTL_CRASHDRV_CHECK_REQUEST, + NULL, + 0, + IoctlBuf, + sizeof(IoctlBuf), + &ReturnedByteCount, + NULL + ); + + return IoctlBuf[0]; +} + + +VOID +Usage( + VOID + ) +{ + DWORD i; + + printf( "usage: TEST [options]\n" ); + printf( " [-?] Display this message\n" ); + printf( " [-t test-number] Execute a test\n" ); + for (i=1; i<MaxTests; i++) { + printf( " #%d %s\n", i, TestInformation[i].Description ); + } + ExitProcess(0); +} + + +VOID +GetCommandLineArgs( + VOID + ) +{ + char *lpstrCmd = GetCommandLine(); + UCHAR ch; + DWORD i = 0; + char buf[10]; + + // skip over program name + do { + ch = *lpstrCmd++; + } + while (ch != ' ' && ch != '\t' && ch != '\0'); + + // skip over any following white space + while (ch == ' ' || ch == '\t') { + ch = *lpstrCmd++; + } + + // process each switch character '-' as encountered + + while (ch == '-' || ch == '/') { + ch = tolower(*lpstrCmd++); + // process multiple switch characters as needed + do { + switch (ch) { + case 't': + i=0; + ch = *lpstrCmd++; + while (ch == ' ' || ch == '\t') { + ch = *lpstrCmd++; + } + while (ch != ' ' && ch != '\0' && ch != ',') { + buf[i++] = ch; + ch = *lpstrCmd++; + } + buf[i] = 0; + TestNumber = atoi( buf ); + if (ch == ',') { + i=0; + ch = *lpstrCmd++; + while (ch != ' ' && ch != '\0') { + buf[i++] = ch; + ch = *lpstrCmd++; + } + buf[i] = 0; + IoctlBuf[0] = atoi( buf ); + if (TestNumber == TEST_SPECIAL) { + if (IoctlBuf[0] == 1) { + IoctlBuf[0] = KMODE_EXCEPTION_NOT_HANDLED; + } + if (IoctlBuf[0] == 2) { + IoctlBuf[0] = IRQL_NOT_LESS_OR_EQUAL; + } + } + } + break; + + case '?': + Usage(); + ch = *lpstrCmd++; + break; + + default: + return; + } + } while (ch != ' ' && ch != '\t' && ch != '\0'); + + while (ch == ' ' || ch == '\t') { + ch = *lpstrCmd++; + } + } + + return; +} + + +BOOL +StartCrashDrvService( + VOID + ) +{ + SERVICE_STATUS ssStatus; + DWORD dwOldCheckPoint; + SC_HANDLE schService; + SC_HANDLE schSCManager; + + + schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); + if (schSCManager == NULL) { + printf( "could not open service controller database\n" ); + return FALSE; + } + + schService = OpenService( schSCManager, "CrashDrv", SERVICE_ALL_ACCESS ); + if (schService == NULL) { + printf( "CrashDrv service is not installed, run install.exe\n" ); + return FALSE; + } + + if (!StartService( schService, 0, NULL )) { + if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) { + printf( "CrashDrv service already running\n" ); + return TRUE; + } + printf( "CrashDrv service could not be started\n" ); + return FALSE; + } + + if (!QueryServiceStatus( schService, &ssStatus)) { + printf( "CrashDrv service could not be started\n" ); + return FALSE; + } + + while (ssStatus.dwCurrentState != SERVICE_RUNNING) { + dwOldCheckPoint = ssStatus.dwCheckPoint; + Sleep(ssStatus.dwWaitHint); + if (!QueryServiceStatus( schService, &ssStatus)) { + break; + } + if (dwOldCheckPoint >= ssStatus.dwCheckPoint) { + break; + } + } + + if (ssStatus.dwCurrentState == SERVICE_RUNNING) + printf("CrashDrv service started\n"); + else { + printf("CrashDrv service not started: \n"); + } + + CloseServiceHandle(schService); +} diff --git a/private/windbg/driver/crashdrv/tests/test.rc b/private/windbg/driver/crashdrv/tests/test.rc new file mode 100644 index 000000000..8c4cc9dc4 --- /dev/null +++ b/private/windbg/driver/crashdrv/tests/test.rc @@ -0,0 +1,11 @@ +#include <windows.h> +#include <ntverp.h> + +#define VER_FILETYPE VFT_APP +#define VER_FILESUBTYPE VFT2_UNKNOWN +#define VER_FILEDESCRIPTION_STR "Microsoft\256 Kernel Crash Driver Tester" + +#define VER_INTERNALNAME_STR "test.exe" +#define VER_ORIGINALFILENAME_STR "test.exe" + +#include <common.ver> |