summaryrefslogtreecommitdiffstats
path: root/private/windbg/driver
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/windbg/driver
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/windbg/driver')
-rw-r--r--private/windbg/driver/crash/crash.bmpbin0 -> 2166 bytes
-rw-r--r--private/windbg/driver/crash/crash.c538
-rw-r--r--private/windbg/driver/crash/crash.icobin0 -> 1046 bytes
-rw-r--r--private/windbg/driver/crash/crash.rc30
-rw-r--r--private/windbg/driver/crash/crash.wavbin0 -> 50176 bytes
-rw-r--r--private/windbg/driver/crash/crashdrv.dbgbin0 -> 95588 bytes
-rw-r--r--private/windbg/driver/crash/crashdrv.sysbin0 -> 5312 bytes
-rw-r--r--private/windbg/driver/crash/crashrc.h7
-rw-r--r--private/windbg/driver/crash/makefile6
-rw-r--r--private/windbg/driver/crash/makefile.inc7
-rw-r--r--private/windbg/driver/crash/sources18
-rw-r--r--private/windbg/driver/crashdrv/crashdrv.c225
-rw-r--r--private/windbg/driver/crashdrv/crashdrv.h58
-rw-r--r--private/windbg/driver/crashdrv/crashdrv.rc11
-rw-r--r--private/windbg/driver/crashdrv/dirs1
-rw-r--r--private/windbg/driver/crashdrv/driver/makefile6
-rw-r--r--private/windbg/driver/crashdrv/driver/sources12
-rw-r--r--private/windbg/driver/crashdrv/tests.c266
-rw-r--r--private/windbg/driver/crashdrv/tests/install.c83
-rw-r--r--private/windbg/driver/crashdrv/tests/install.rc11
-rw-r--r--private/windbg/driver/crashdrv/tests/makefile6
-rw-r--r--private/windbg/driver/crashdrv/tests/makefile.inc3
-rw-r--r--private/windbg/driver/crashdrv/tests/sources17
-rw-r--r--private/windbg/driver/crashdrv/tests/test.c295
-rw-r--r--private/windbg/driver/crashdrv/tests/test.rc11
-rw-r--r--private/windbg/driver/dirs1
26 files changed, 1612 insertions, 0 deletions
diff --git a/private/windbg/driver/crash/crash.bmp b/private/windbg/driver/crash/crash.bmp
new file mode 100644
index 000000000..57e14678b
--- /dev/null
+++ b/private/windbg/driver/crash/crash.bmp
Binary files differ
diff --git a/private/windbg/driver/crash/crash.c b/private/windbg/driver/crash/crash.c
new file mode 100644
index 000000000..ebd3902fb
--- /dev/null
+++ b/private/windbg/driver/crash/crash.c
@@ -0,0 +1,538 @@
+#include <windows.h>
+#include <winioctl.h>
+#include <mmsystem.h>
+#include <stdio.h>
+#include <crashrc.h>
+#include "crashdrv.h"
+
+
+#if DBG
+#define DBGMSG(s) {\
+ char __buf[80]; \
+ OutputDebugString("************************\n"); \
+ OutputDebugString(s); \
+ sprintf(__buf,"Errorcode = %d\n",GetLastError());\
+ OutputDebugString( __buf ); \
+ OutputDebugString("************************\n"); \
+ }
+#else
+#define DBGMSG(s)
+#endif
+
+#define SERVICE_NAME "CrashDrv"
+#define DRIVER_NAME "\\systemroot\\system32\\drivers\\crashdrv.sys"
+#define CRASHDRV_DEVICE "\\\\.\\CrashDrv"
+
+
+HINSTANCE hInst;
+DWORD IoctlBuf[16];
+HBITMAP hBmp;
+
+
+
+LRESULT CrashWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+BOOL InstallDriver(VOID);
+BOOL CrashTheSystem(VOID);
+BOOL StartCrashDrvService(VOID);
+VOID SyncAllVolumes(VOID);
+BOOL IsUserAdmin(VOID);
+
+
+int _cdecl
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ HWND hwnd;
+ MSG msg;
+ WNDCLASS wndclass;
+
+
+ hInst = GetModuleHandle( NULL );
+ wndclass.style = CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = CrashWndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = DLGWINDOWEXTRA;
+ wndclass.hInstance = hInst;
+ wndclass.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(APPICON) );
+ wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
+ wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = "CrashDialog";
+ RegisterClass( &wndclass );
+
+ hwnd = CreateDialog( hInst,
+ MAKEINTRESOURCE( CRASHDLG ),
+ 0,
+ CrashWndProc
+ );
+
+ ShowWindow( hwnd, SW_SHOWNORMAL );
+
+ while (GetMessage (&msg, NULL, 0, 0)) {
+ if (!IsDialogMessage( hwnd, &msg )) {
+ TranslateMessage (&msg) ;
+ DispatchMessage (&msg) ;
+ }
+ }
+
+ return 0;
+}
+
+
+LRESULT
+CrashWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (message == WM_INITDIALOG) {
+ hBmp = LoadBitmap( hInst, MAKEINTRESOURCE(CRASHBMP) );
+ return 1;
+ }
+
+ if (message == WM_PAINT) {
+ PAINTSTRUCT ps;
+ HDC hdc;
+ HDC hdcMem;
+ RECT rect;
+
+ hdc = BeginPaint( hwnd, &ps );
+
+ hdcMem = CreateCompatibleDC( hdc );
+ SelectObject( hdcMem, hBmp );
+ GetClientRect( hwnd, &rect );
+
+ StretchBlt(
+ hdc,
+ rect.left,
+ rect.top,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ hdcMem,
+ 0,
+ 0,
+ 64,
+ 64,
+ SRCCOPY );
+ DeleteDC(hdcMem);
+
+ EndPaint( hwnd, &ps );
+ return 1;
+ }
+
+ if (message == WM_COMMAND) {
+ if (wParam == ID_CRASH) {
+ if (!IsUserAdmin()) {
+ MessageBeep( 0 );
+ MessageBox(
+ hwnd,
+ "You must be an administrator to crash the system!",
+ "Crash Error",
+ MB_SETFOREGROUND | MB_ICONSTOP | MB_OK );
+ } else {
+ if (!CrashTheSystem()) {
+ MessageBox(
+ hwnd,
+ "An error occurred while trying to crash the system!",
+ "Crash Error",
+ MB_SETFOREGROUND | MB_ICONSTOP | MB_OK );
+ }
+ }
+ } else if (wParam == IDCANCEL) {
+ SendMessage( hwnd, WM_CLOSE, 0, 0 );
+ }
+ }
+
+ if (message == WM_DESTROY) {
+ PostQuitMessage( 0 );
+ return 0;
+ }
+
+ return DefWindowProc( hwnd, message, wParam, lParam );
+}
+
+
+BOOL
+CrashTheSystem(
+ VOID
+ )
+{
+ HANDLE hCrashDrv;
+ DWORD ReturnedByteCount;
+ HGLOBAL hResource;
+ LPVOID lpResource;
+
+
+ if (!StartCrashDrvService()) {
+ return FALSE;
+ }
+
+ SyncAllVolumes();
+
+ hCrashDrv = CreateFile( CRASHDRV_DEVICE,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL
+ );
+
+ if (hCrashDrv == INVALID_HANDLE_VALUE) {
+ DBGMSG( "createfile() failed\n" );
+ return FALSE;
+ }
+
+ if (waveOutGetNumDevs()) {
+ hResource = LoadResource(
+ hInst,
+ FindResource( hInst, MAKEINTRESOURCE(CRASHWAV), MAKEINTRESOURCE(BINARY) ) );
+ if (hResource) {
+ lpResource = LockResource( hResource );
+ sndPlaySound( lpResource, SND_MEMORY );
+ FreeResource( hResource );
+ }
+ }
+
+ if (!DeviceIoControl(
+ hCrashDrv,
+ (DWORD)IOCTL_CRASHDRV_BUGCHECK,
+ NULL,
+ 0,
+ IoctlBuf,
+ sizeof(IoctlBuf),
+ &ReturnedByteCount,
+ NULL
+ )) {
+ DBGMSG( "deviceiocontrol() failed\n" );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL
+CopyResourceToDriver(
+ VOID
+ )
+{
+ HGLOBAL hResource;
+ LPVOID lpResource;
+ DWORD size;
+ PIMAGE_DOS_HEADER dh;
+ PIMAGE_NT_HEADERS nh;
+ PIMAGE_SECTION_HEADER sh;
+ HANDLE hFile;
+ CHAR buf[MAX_PATH];
+
+
+ hResource = LoadResource(
+ hInst,
+ FindResource( hInst, MAKEINTRESOURCE(CRASHDRVDRIVER), MAKEINTRESOURCE(BINARY) ) );
+
+ if (!hResource) {
+ DBGMSG( "load/findresource() failed\n" );
+ return FALSE;
+ }
+
+ lpResource = LockResource( hResource );
+
+ if (!lpResource) {
+ FreeResource( hResource );
+ DBGMSG( "lockresource() failed\n" );
+ return FALSE;
+ }
+
+ dh = (PIMAGE_DOS_HEADER) lpResource;
+ nh = (PIMAGE_NT_HEADERS) (dh->e_lfanew + (DWORD)lpResource);
+ sh = (PIMAGE_SECTION_HEADER) ((DWORD)nh + sizeof(IMAGE_NT_HEADERS) +
+ ((nh->FileHeader.NumberOfSections - 1) *
+ sizeof(IMAGE_SECTION_HEADER)));
+ size = sh->PointerToRawData + sh->SizeOfRawData;
+
+ GetEnvironmentVariable( "systemroot", buf, sizeof(buf) );
+ strcat( buf, "\\system32\\drivers\\CrashDrv.sys" );
+
+ hFile = CreateFile(
+ buf,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ 0,
+ NULL
+ );
+ if (hFile == INVALID_HANDLE_VALUE) {
+ FreeResource( hResource );
+ DBGMSG( "createfile() failed\n" );
+ return FALSE;
+ }
+
+ WriteFile( hFile, lpResource, size, &size, NULL );
+ CloseHandle( hFile );
+
+ FreeResource( hResource );
+
+ return TRUE;
+}
+
+BOOL
+InstallDriver(
+ VOID
+ )
+{
+ SC_HANDLE hService;
+ SC_HANDLE hOldService;
+ SERVICE_STATUS ServStat;
+
+
+ if (!CopyResourceToDriver()) {
+ DBGMSG( "copyresourcetodriver() failed\n" );
+ return FALSE;
+ }
+
+ if( !( hService = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ) ) ) {
+ DBGMSG( "openscmanager() failed\n" );
+ return FALSE;
+ }
+ 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 ) ) {
+ DBGMSG( "controlservice() failed\n" );
+ return FALSE;
+ }
+ }
+ if( ! DeleteService( hOldService ) ) {
+ DBGMSG( "deleteservice() failed\n" );
+ return FALSE;
+ }
+ if( ! CloseServiceHandle( hOldService ) ) {
+ DBGMSG( "closeservicehandle() failed\n" );
+ return FALSE;
+ }
+ }
+ 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 ) {
+ DBGMSG( "createservice() failed\n" );
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+BOOL
+StartCrashDrvService(
+ VOID
+ )
+{
+ SERVICE_STATUS ssStatus;
+ DWORD dwOldCheckPoint;
+ DWORD ec;
+ SC_HANDLE schService;
+ SC_HANDLE schSCManager;
+
+
+ schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
+ if (schSCManager == NULL) {
+ DBGMSG( "openscmanager() failed\n" );
+ return FALSE;
+ }
+
+ schService = OpenService( schSCManager, "CrashDrv", SERVICE_ALL_ACCESS );
+ if (schService == NULL) {
+install_driver:
+ if (InstallDriver()) {
+ schService = OpenService( schSCManager, "CrashDrv", SERVICE_ALL_ACCESS );
+ if (schService == NULL) {
+ DBGMSG( "openservice() failed\n" );
+ return FALSE;
+ }
+ } else {
+ DBGMSG( "installdriver() failed\n" );
+ return FALSE;
+ }
+ }
+
+ if (!StartService( schService, 0, NULL )) {
+ ec = GetLastError();
+ CloseServiceHandle( schService );
+ if (ec == ERROR_SERVICE_ALREADY_RUNNING) {
+ return TRUE;
+ }
+ if (ec == ERROR_FILE_NOT_FOUND) {
+ goto install_driver;
+ }
+ DBGMSG( "startservice failed\n" );
+ return FALSE;
+ }
+
+ if (!QueryServiceStatus( schService, &ssStatus)) {
+ DBGMSG( "queryservice failed\n" );
+ CloseServiceHandle( schService );
+ return FALSE;
+ }
+
+ while (ssStatus.dwCurrentState != SERVICE_RUNNING) {
+ dwOldCheckPoint = ssStatus.dwCheckPoint;
+ Sleep(ssStatus.dwWaitHint);
+ if (!QueryServiceStatus( schService, &ssStatus)) {
+ break;
+ }
+ if (dwOldCheckPoint >= ssStatus.dwCheckPoint) {
+ break;
+ }
+ }
+
+ CloseServiceHandle(schService);
+}
+
+
+BOOL
+SyncVolume(
+ CHAR c
+ )
+{
+ CHAR VolumeName[16];
+ HANDLE hVolume;
+
+
+ VolumeName[0] = '\\';
+ VolumeName[1] = '\\';
+ VolumeName[2] = '.';
+ VolumeName[3] = '\\';
+ VolumeName[4] = c;
+ VolumeName[5] = ':';
+ VolumeName[6] = '\0';
+
+ hVolume = CreateFile(
+ VolumeName,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL );
+
+ if (hVolume == INVALID_HANDLE_VALUE) {
+ return FALSE;
+ }
+
+ FlushFileBuffers( hVolume );
+
+ CloseHandle( hVolume );
+
+ return TRUE;
+}
+
+
+VOID
+SyncAllVolumes(
+ VOID
+ )
+{
+ DWORD i;
+
+
+ for(i=2; i<26; i++){
+ SyncVolume( (CHAR)((CHAR)i + (CHAR)'a') );
+ }
+}
+
+
+BOOL
+IsUserAdmin(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine returns TRUE if the caller's process is a
+ member of the Administrators local group.
+
+ Caller is NOT expected to be impersonating anyone and IS
+ expected to be able to open their own process and process
+ token.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ TRUE - Caller has Administrators local group.
+
+ FALSE - Caller does not have Administrators local group.
+
+--*/
+
+{
+ HANDLE Token;
+ DWORD BytesRequired;
+ PTOKEN_GROUPS Groups;
+ BOOL b;
+ DWORD i;
+ SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
+ PSID AdministratorsGroup;
+
+ //
+ // Open the process token.
+ //
+ if(!OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&Token)) {
+ return(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED); // Chicago
+ }
+
+ b = FALSE;
+ Groups = NULL;
+
+ //
+ // Get group information.
+ //
+ if(!GetTokenInformation(Token,TokenGroups,NULL,0,&BytesRequired)
+ && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ && (Groups = (PTOKEN_GROUPS)LocalAlloc(LPTR,BytesRequired))
+ && GetTokenInformation(Token,TokenGroups,Groups,BytesRequired,&BytesRequired)) {
+
+ b = AllocateAndInitializeSid(
+ &NtAuthority,
+ 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &AdministratorsGroup
+ );
+
+ if(b) {
+
+ //
+ // See if the user has the administrator group.
+ //
+ b = FALSE;
+ for(i=0; i<Groups->GroupCount; i++) {
+ if(EqualSid(Groups->Groups[i].Sid,AdministratorsGroup)) {
+ b = TRUE;
+ break;
+ }
+ }
+
+ FreeSid(AdministratorsGroup);
+ }
+ }
+
+ //
+ // Clean up and return.
+ //
+
+ if(Groups) {
+ LocalFree((HLOCAL)Groups);
+ }
+
+ CloseHandle(Token);
+
+ return(b);
+}
diff --git a/private/windbg/driver/crash/crash.ico b/private/windbg/driver/crash/crash.ico
new file mode 100644
index 000000000..d7196cfb6
--- /dev/null
+++ b/private/windbg/driver/crash/crash.ico
Binary files differ
diff --git a/private/windbg/driver/crash/crash.rc b/private/windbg/driver/crash/crash.rc
new file mode 100644
index 000000000..0ce121a18
--- /dev/null
+++ b/private/windbg/driver/crash/crash.rc
@@ -0,0 +1,30 @@
+#include <windows.h>
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_APP
+#define VER_FILESUBTYPE VFT2_UNKNOWN
+#define VER_FILEDESCRIPTION_STR "Microsoft\256 Kernel Crasher"
+
+#define VER_INTERNALNAME_STR "crash.exe"
+#define VER_ORIGINALFILENAME_STR "crash.exe"
+
+#include <common.ver>
+
+#include <crashrc.h>
+
+APPICON ICON "crash.ico"
+CRASHDRVDRIVER BINARY "crashdrv.sys"
+CRASHBMP BITMAP "crash.bmp"
+CRASHWAV BINARY "crash.wav"
+
+
+CRASHDLG DIALOG 21, 26, 101, 68
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP |
+ WS_VISIBLE | WS_CAPTION
+FONT 14, "Lucida Console"
+CLASS "CrashDialog"
+BEGIN
+ DEFPUSHBUTTON "E&xit", IDCANCEL, 56, 52, 34, 13, NOT WS_TABSTOP
+ PUSHBUTTON "&Crash", IDOK, 11, 52, 34, 13, NOT WS_TABSTOP
+END
diff --git a/private/windbg/driver/crash/crash.wav b/private/windbg/driver/crash/crash.wav
new file mode 100644
index 000000000..5ffc56dc5
--- /dev/null
+++ b/private/windbg/driver/crash/crash.wav
Binary files differ
diff --git a/private/windbg/driver/crash/crashdrv.dbg b/private/windbg/driver/crash/crashdrv.dbg
new file mode 100644
index 000000000..2cb6c7ae4
--- /dev/null
+++ b/private/windbg/driver/crash/crashdrv.dbg
Binary files differ
diff --git a/private/windbg/driver/crash/crashdrv.sys b/private/windbg/driver/crash/crashdrv.sys
new file mode 100644
index 000000000..ade67debf
--- /dev/null
+++ b/private/windbg/driver/crash/crashdrv.sys
Binary files differ
diff --git a/private/windbg/driver/crash/crashrc.h b/private/windbg/driver/crash/crashrc.h
new file mode 100644
index 000000000..265b09206
--- /dev/null
+++ b/private/windbg/driver/crash/crashrc.h
@@ -0,0 +1,7 @@
+#define ID_CRASH IDOK
+#define CRASHDLG 500
+#define APPICON 501
+#define CRASHDRVDRIVER 502
+#define CRASHBMP 503
+#define CRASHWAV 504
+#define BINARY 1024
diff --git a/private/windbg/driver/crash/makefile b/private/windbg/driver/crash/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/windbg/driver/crash/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/crash/makefile.inc b/private/windbg/driver/crash/makefile.inc
new file mode 100644
index 000000000..fa4f4b4a9
--- /dev/null
+++ b/private/windbg/driver/crash/makefile.inc
@@ -0,0 +1,7 @@
+obj\$(TARGET_DIRECTORY)\crashdrv.sys : crash.rc
+ copy ..\crashdrv\driver\obj\$(TARGET_DIRECTORY)\crashdrv.sys crashdrv.sys
+ copy ..\crashdrv\driver\obj\$(TARGET_DIRECTORY)\crashdrv.sys obj\$(TARGET_DIRECTORY)\crashdrv.sys
+ touch obj\$(TARGET_DIRECTORY)\crashdrv.sys
+ splitsym -a crashdrv.sys
+
+obj\$(TARGET_DIRECTORY)\crash.res : obj\$(TARGET_DIRECTORY)\crashdrv.sys
diff --git a/private/windbg/driver/crash/sources b/private/windbg/driver/crash/sources
new file mode 100644
index 000000000..890e4427e
--- /dev/null
+++ b/private/windbg/driver/crash/sources
@@ -0,0 +1,18 @@
+MAJORCOMP=windbg
+MINORCOMP=crash
+
+TARGETNAME=crash
+TARGETPATH=obj
+TARGETTYPE=PROGRAM
+
+INCLUDES=..\crashdrv;.
+
+SOURCES=crash.rc crash.c
+
+UMTYPE=windows
+
+NTTARGETFILE0=obj\$(TARGET_DIRECTORY)\crashdrv.sys
+
+# NTKEEPRESOURCETMPFILES=1
+
+LINKLIBS=$(BASEDIR)\public\sdk\lib\*\winmm.lib
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>
diff --git a/private/windbg/driver/dirs b/private/windbg/driver/dirs
new file mode 100644
index 000000000..8e56f9344
--- /dev/null
+++ b/private/windbg/driver/dirs
@@ -0,0 +1 @@
+dirs=crashdrv crash