Programming The Windows Driver Model 2003 5BSAMPLE FILES 5D

Embed Size (px)

Citation preview

Samples/AppendixA/dirsdirs= harderr newstub wdmcheck whichos

Samples/AppendixA/harderr/Driver.h// Declarations for harderr driver// Copyright (C) 1999 by Walter Oney// All rights reserved

#ifndef DRIVER_H#define DRIVER_H#include "generic.h"

#define DRIVERNAME "HARDERR"// for use in messages#define LDRIVERNAME L"HARDERR"// for use in UNICODE string constants

///////////////////////////////////////////////////////////////////////////////// Device extension structure

typedef struct _DEVICE_EXTENSION {PDEVICE_OBJECT DeviceObject;// device object this extension belongs toPDEVICE_OBJECT LowerDeviceObject;// next lower driver in same stackPDEVICE_OBJECT Pdo;// the PDOIO_REMOVE_LOCK RemoveLock;// removal control locking structureUNICODE_STRING ifname;// interface namePGENERIC_EXTENSION pgx;// device extension for GENERIC.SYS

// TODO add additional per-device declarations

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

///////////////////////////////////////////////////////////////////////////////// Global functions

VOID RemoveDevice(IN PDEVICE_OBJECT fdo);NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info);NTSTATUS StartDevice(PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated);VOID StopDevice(PDEVICE_OBJECT fdo, BOOLEAN oktouch = FALSE);

// I/O request handlers

NTSTATUS DispatchPower(PDEVICE_OBJECT fdo, PIRP Irp);NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp);NTSTATUS DispatchWmi(PDEVICE_OBJECT fdo, PIRP Irp);

extern BOOLEAN win98;extern UNICODE_STRING servkey;

#endif // DRIVER_H

Samples/AppendixA/harderr/driver.rc// Resource script for harderr driver// Generated by Walt Oney's driver wizard

#include

LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL

// TODO Customize the following version resource appropriately

VS_VERSION_INFO VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 FILEFLAGSMASK 0x3fL#ifdef _DEBUG FILEFLAGS 0x1L#else FILEFLAGS 0x0L#endif FILEOS 0x40004L FILETYPE 0x1L FILESUBTYPE 0x0LBEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Walter Oney Software\0" VALUE "FileDescription", "harderr.sys\0" VALUE "FileVersion", "1, 0, 0, 0\0" VALUE "InternalName", "HARDERR\0" VALUE "LegalCopyright", "Copyright 1999 Walter Oney Software\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "harderr.sys\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Hard Error Test\0" VALUE "ProductVersion", "1, 0, 0, 0\0" VALUE "SpecialBuild", "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 ENDEND

Samples/AppendixA/harderr/DriverEntry.cpp

Samples/AppendixA/harderr/DriverEntry.cpp//Mainprogramforharderrdriver

//Copyright(C)1999byWalterOney

//Allrightsreserved

#include"stddcls.h"

#include"driver.h"

#include

#include"guids.h"

NTSTATUSAddDevice(INPDRIVER_OBJECTDriverObject,INPDEVICE_OBJECTpdo);

VOIDDriverUnload(INPDRIVER_OBJECTfdo);

BOOLEANwin98=FALSE;

UNICODE_STRINGservkey;

///////////////////////////////////////////////////////////////////////////////

#pragmaPAGEDCODE

extern"C"NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,

INPUNICODE_STRINGRegistryPath)

{//DriverEntry

KdPrint((DRIVERNAME"-EnteringDriverEntry:DriverObject%8.8lX\n",DriverObject));

//InsistthatOSsupportatleasttheWDMleveloftheDDKweuse

if(!IoIsWdmVersionAvailable(1,0))

{

KdPrint((DRIVERNAME"-ExpectedversionofWDM(%d.%2.2d)notavailable\n",1,0));

returnSTATUS_UNSUCCESSFUL;

}

//Seeifwe'rerunningunderWin98orNT:

win98=IsWin98();

#ifDBG

if(win98)

KdPrint((DRIVERNAME"-RunningunderWindows98\n"));

else

KdPrint((DRIVERNAME"-RunningunderNT\n"));

#endif

//Savethenameoftheservicekey

servkey.Buffer=(PWSTR)ExAllocatePool(PagedPool,RegistryPath->Length+sizeof(WCHAR));

if(!servkey.Buffer)

{

KdPrint((DRIVERNAME"-Unabletoallocate%dbytesforcopyofservicekeyname\n",RegistryPath->Length+sizeof(WCHAR)));

returnSTATUS_INSUFFICIENT_RESOURCES;

}

servkey.MaximumLength=RegistryPath->Length+sizeof(WCHAR);

RtlCopyUnicodeString(&servkey,RegistryPath);

servkey.Buffer[RegistryPath->Length/2]=0;

//Initializefunctionpointers

DriverObject->DriverUnload=DriverUnload;

DriverObject->DriverExtension->AddDevice=AddDevice;

DriverObject->MajorFunction[IRP_MJ_POWER]=DispatchPower;

DriverObject->MajorFunction[IRP_MJ_PNP]=DispatchPnp;

DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL]=DispatchWmi;


returnSTATUS_SUCCESS;

}//DriverEntry

///////////////////////////////////////////////////////////////////////////////

#pragmaPAGEDCODE

VOIDDriverUnload(INPDRIVER_OBJECTDriverObject)

{//DriverUnload

PAGED_CODE();

KdPrint((DRIVERNAME"-EnteringDriverUnload:DriverObject%8.8lX\n",DriverObject));

RtlFreeUnicodeString(&servkey);

}//DriverUnload

///////////////////////////////////////////////////////////////////////////////

NTSTATUSAddDevice(INPDRIVER_OBJECTDriverObject,INPDEVICE_OBJECTpdo)

{//AddDevice

PAGED_CODE();

KdPrint((DRIVERNAME"-EnteringAddDevice:DriverObject%8.8lX,pdo%8.8lX\n",DriverObject,pdo));

NTSTATUSstatus;

//Createafunctiondeviceobjecttorepresentthehardwarewe'remanaging.

PDEVICE_OBJECTfdo;

ULONGdxsize=(sizeof(DEVICE_EXTENSION)+7)&~7;

ULONGxsize=dxsize+GetSizeofGenericExtension();

status=IoCreateDevice(DriverObject,xsize,NULL,

FILE_DEVICE_UNKNOWN,FILE_DEVICE_SECURE_OPEN,FALSE,&fdo);

if(!NT_SUCCESS(status))

{//can'tcreatedeviceobject

KdPrint((DRIVERNAME"-IoCreateDevicefailed-%X\n",status));

returnstatus;

}//can'tcreatedeviceobject


PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

//Fromthispointforward,anyerrorwillhavesideeffectsthatneedto

//becleanedup.

do

{//finishinitialization

pdx->DeviceObject=fdo;

pdx->Pdo=pdo;

//LinkourdeviceobjectintothestackleadingtothePDO


pdx->LowerDeviceObject=IoAttachDeviceToDeviceStack(fdo,pdo);

if(!pdx->LowerDeviceObject)

{//can'tattachdevice

KdPrint((DRIVERNAME"-IoAttachDeviceToDeviceStackfailed\n"));

status=STATUS_DEVICE_REMOVED;

break;;

}//can'tattachdevice

//Setpowermanagementflagsinthedeviceobject

fdo->Flags|=DO_POWER_PAGABLE;

//InitializetousetheGENERIC.SYSlibrary

pdx->pgx=(PGENERIC_EXTENSION)((PUCHAR)pdx+dxsize);

GENERIC_INIT_STRUCTgis={sizeof(GENERIC_INIT_STRUCT)};

gis.DeviceObject=fdo;

gis.Pdo=pdo;

gis.Ldo=pdx->LowerDeviceObject;

gis.RemoveLock=&pdx->RemoveLock;

gis.StartDevice=StartDevice;

gis.StopDevice=StopDevice;

gis.RemoveDevice=RemoveDevice;

RtlInitUnicodeString(&gis.DebugName,LDRIVERNAME);

status=InitializeGenericExtension(pdx->pgx,&gis);

if(!NT_SUCCESS(status))

{

KdPrint((DRIVERNAME"-InitializeGenericExtensionfailed-%X\n",status));

break;;

}

GenericRegisterInterface(pdx->pgx,&GUID_DEVINTERFACE_HARDERR);

//Clearthe"initializing"flagsothatwecangetIRPs

fdo->Flags&=~DO_DEVICE_INITIALIZING;

}//finishinitialization

while(FALSE);

if(!NT_SUCCESS(status))

{//needtocleanup

if(pdx->ifname.Buffer)

RtlFreeUnicodeString(&pdx->ifname);

if(pdx->LowerDeviceObject)

IoDetachDevice(pdx->LowerDeviceObject);

IoDeleteDevice(fdo);

}//needtocleanup

returnstatus;

}//AddDevice

///////////////////////////////////////////////////////////////////////////////

#pragmaLOCKEDCODE

NTSTATUSCompleteRequest(INPIRPIrp,INNTSTATUSstatus,INULONG_PTRinfo)

{//CompleteRequest

Irp->IoStatus.Status=status;

Irp->IoStatus.Information=info;

IoCompleteRequest(Irp,IO_NO_INCREMENT);

returnstatus;

}//CompleteRequest

///////////////////////////////////////////////////////////////////////////////

#pragmaPAGEDCODE

NTSTATUSDispatchPnp(PDEVICE_OBJECTfdo,PIRPIrp)

{//DispatchPnp

PAGED_CODE();

PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

returnGenericDispatchPnp(pdx->pgx,Irp);

}//DispatchPnp

NTSTATUSDispatchPower(PDEVICE_OBJECTfdo,PIRPIrp)

{//DispatchPower

PAGED_CODE();

PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

returnGenericDispatchPower(pdx->pgx,Irp);

}//DispatchPower

NTSTATUSDispatchWmi(PDEVICE_OBJECTfdo,PIRPIrp)

{//DispatchWmi

PAGED_CODE();

PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

IoSkipCurrentIrpStackLocation(Irp);

returnIoCallDriver(pdx->LowerDeviceObject,Irp);

}//DispatchWmi

///////////////////////////////////////////////////////////////////////////////

#pragmaPAGEDCODE

VOIDRemoveDevice(INPDEVICE_OBJECTfdo)

{//RemoveDevice

PAGED_CODE();

PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

NTSTATUSstatus;


if(pdx->LowerDeviceObject)

IoDetachDevice(pdx->LowerDeviceObject);

IoDeleteDevice(fdo);

}//RemoveDevice

#pragmaLOCKEDCODE//forceinlinefunctionsintolockedcode

Samples/AppendixA/harderr/guids.h// guids.h -- WMI Guids for harderr driver// Copyright (C) 1999 by Walter Oney// All rights reserved

#ifndef GUIDS_H#define GUIDS_H

// {A44380A2-8B78-11D3-81B5-00C04FA330A6}DEFINE_GUID(GUID_DEVINTERFACE_HARDERR, 0xa44380a2L, 0x8b78, 0x11d3, 0x81, 0xb5, 0x00, 0xc0, 0x4f, 0xa3, 0x30, 0xa6);

#endif

Samples/AppendixA/harderr/harderr.dsp# Microsoft Developer Studio Project File - Name="harderr" - Package Owner=# Microsoft Developer Studio Generated Build File, Format Version 6.00# ** DO NOT EDIT **

# TARGTYPE "Win32 (x86) Application" 0x0101

CFG=harderr - Win32 Checked!MESSAGE This is not a valid makefile. To build this project using NMAKE,!MESSAGE use the Export Makefile command and run!MESSAGE !MESSAGE NMAKE /f "harderr.mak".!MESSAGE !MESSAGE You can specify a configuration when running NMAKE!MESSAGE by defining the macro CFG on the command line. For example:!MESSAGE !MESSAGE NMAKE /f "harderr.mak" CFG="harderr - Win32 Checked"!MESSAGE !MESSAGE Possible choices for configuration are:!MESSAGE !MESSAGE "harderr - Win32 Free" (based on "Win32 (x86) Application")!MESSAGE "harderr - Win32 Checked" (based on "Win32 (x86) Application")!MESSAGE

# Begin Project# PROP AllowPerConfigDependencies 0# PROP Scc_ProjName ""# PROP Scc_LocalPath ""CPP=cl.exeMTL=midl.exeRSC=rc.exe

!IF "$(CFG)" == "harderr - Win32 Free"

# PROP BASE Use_MFC 0# PROP BASE Use_Debug_Libraries 0# PROP BASE Output_Dir "objfre_wxp_x86\i386"# PROP BASE Intermediate_Dir "objfre_wxp_x86\i386"# PROP BASE Target_Dir ""# PROP Use_MFC 0# PROP Use_Debug_Libraries 0# PROP Output_Dir "objfre_wxp_x86\i386"# PROP Intermediate_Dir "objfre_wxp_x86\i386"# PROP Ignore_Export_Lib 0# PROP Target_Dir ""# ADD BASE CPP -nologo -DCONDITION_HANDLING=1 -DDBG=0 -DDEVL=1 -DDRIVER -DFPO=1 -DNDEBUG -DNT_INST=0 -DNT_UP=1 -DSTD_CALL -DWIN32 -DWIN32=100 -DWIN32_LEAN_AND_MEAN=1 -DWINNT=1 -DWINVER=0x0501 -D_DLL=1 -D_IDWBUILD -D_MBCS -D_NT1X_=100 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -D_WINDOWS -D_X86_=1 -Di386=1 -FD -FI$(ddkpath)\inc\wxp\warning.h -FR -G6 -GF -GR- -GX- -Gi- -Gm- -Gy -Gz -O2 -Oxs -Oy -QI0f -QIf -QIfdiv- -W3 -WX -Yu"stddcls.h" -Zel -Zp8 -c -cbstring -I"$(wdmbook)\generic" -I$(ddkpath)\inc\wxp -I"$(ddkpath)\inc\ddk\wxp" -I"$(ddkpath)\inc\ddk\wdm\wxp" -I"$(ddkpath)\inc\crt" # ADD CPP -nologo -DCONDITION_HANDLING=1 -DDBG=0 -DDEVL=1 -DDRIVER -DFPO=1 -DNDEBUG -DNT_INST=0 -DNT_UP=1 -DSTD_CALL -DWIN32 -DWIN32=100 -DWIN32_LEAN_AND_MEAN=1 -DWINNT=1 -DWINVER=0x0501 -D_DLL=1 -D_IDWBUILD -D_MBCS -D_NT1X_=100 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -D_WINDOWS -D_X86_=1 -Di386=1 -FD -FI$(ddkpath)\inc\wxp\warning.h -FR -G6 -GF -GR- -GX- -Gi- -Gm- -Gy -Gz -O2 -Oxs -Oy -QI0f -QIf -QIfdiv- -W3 -WX -Yu"stddcls.h" -Zel -Zp8 -c -cbstring -I"$(wdmbook)\generic" -I$(ddkpath)\inc\wxp -I"$(ddkpath)\inc\ddk\wxp" -I"$(ddkpath)\inc\ddk\wdm\wxp" -I"$(ddkpath)\inc\crt" # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32# ADD BASE RSC /l 0x409 /d "NDEBUG" /i "$(wdmbook)\generic" /i $(ddkpath)\inc\wxp /i "$(ddkpath)\inc\ddk\wxp" /i "$(ddkpath)\inc\ddk\wdm\wxp" /i "$(ddkpath)\inc\crt" # ADD RSC /l 0x409 /d "NDEBUG" /i "$(wdmbook)\generic" /i $(ddkpath)\inc\wxp /i "$(ddkpath)\inc\ddk\wxp" /i "$(ddkpath)\inc\ddk\wdm\wxp" /i "$(ddkpath)\inc\crt" BSC32=bscmake.exe# ADD BASE BSC32 /nologo# ADD BSC32 /nologoLINK32=link.exe# ADD BASE LINK32 -nologo -align:0x80 -base:0x10000 -debug:full -debugtype:cv -debugtype:cv -driver:wdm -entry:DriverEntry@8 -fullbuild -ignore:4010,4037,4039,4049,4065,4070,4078,4087,4089,4198,4221 -incremental:no -libpath:"$(ddkpath)\lib\wxp\i386" -libpath:"$(wdmbook)\generic\objfre_wxp_x86\i386" -merge:_PAGE=PAGE -merge:_TEXT=.text -nodefaultlib -opt:icf -opt:nowin98 -opt:ref -osversion:4.00 -release -section:init,d -stack:0x40000,0x1000 -subsystem:native,4.00 -version:5.1 wdm.lib generic.lib ntoskrnl.lib wmilib.lib -out:objfre_wxp_x86\i386\harderr.sys# ADD LINK32 -nologo -align:0x80 -base:0x10000 -debug:full -debugtype:cv -debugtype:cv -driver:wdm -entry:DriverEntry@8 -fullbuild -ignore:4010,4037,4039,4049,4065,4070,4078,4087,4089,4198,4221 -incremental:no -libpath:"$(ddkpath)\lib\wxp\i386" -libpath:"$(wdmbook)\generic\objfre_wxp_x86\i386" -merge:_PAGE=PAGE -merge:_TEXT=.text -nodefaultlib -opt:icf -opt:nowin98 -opt:ref -osversion:4.00 -release -section:init,d -stack:0x40000,0x1000 -subsystem:native,4.00 -version:5.1 wdm.lib generic.lib ntoskrnl.lib wmilib.lib -out:objfre_wxp_x86\i386\harderr.sys# Begin Special Build ToolTargetPath=.\objfre_wxp_x86\i386harderr.sysSOURCE="$(InputPath)"PostBuild_Cmds=copy $(TargetPath) $(WINDIR)\system32\drivers$(SIWPATH)\nmsym -translate:source,package,always $(TargetPath)# End Special Build Tool

!ELSEIF "$(CFG)" == "harderr - Win32 Checked"

# PROP BASE Use_MFC 0# PROP BASE Use_Debug_Libraries 1# PROP BASE Output_Dir "objchk_wxp_x86\i386"# PROP BASE Intermediate_Dir "objchk_wxp_x86\i386"# PROP BASE Target_Dir ""# PROP Use_MFC 0# PROP Use_Debug_Libraries 1# PROP Output_Dir "objchk_wxp_x86\i386"# PROP Intermediate_Dir "objchk_wxp_x86\i386"# PROP Ignore_Export_Lib 0# PROP Target_Dir ""# ADD BASE CPP -nologo -DCONDITION_HANDLING=1 -DDBG=1 -DDEVL=1 -DDRIVER -DFPO=0 -DNDEBUG -DNT_INST=0 -DNT_UP=1 -DRDRDBG -DSRVDBG -DSTD_CALL -DWIN32 -DWIN32=100 -DWIN32_LEAN_AND_MEAN=1 -DWINNT=1 -DWINVER=0x0501 -D_DEBUG -D_DLL=1 -D_IDWBUILD -D_MBCS -D_NT1X_=100 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -D_WINDOWS -D_X86_=1 -Di386=1 -FD -FI$(ddkpath)\inc\wxp\warning.h -FR -G6 -GF -GR- -GX- -Gi- -Gm- -Gy -Gz -Od -Oi -Oy- -QI0f -QIf -QIfdiv- -W3 -WX -Yu"stddcls.h" -Z7 -Zel -Zp8 -c -cbstring -I"$(wdmbook)\generic" -I$(ddkpath)\inc\wxp -I"$(ddkpath)\inc\ddk\wxp" -I"$(ddkpath)\inc\ddk\wdm\wxp" -I"$(ddkpath)\inc\crt" # ADD CPP -nologo -DCONDITION_HANDLING=1 -DDBG=1 -DDEVL=1 -DDRIVER -DFPO=0 -DNDEBUG -DNT_INST=0 -DNT_UP=1 -DRDRDBG -DSRVDBG -DSTD_CALL -DWIN32 -DWIN32=100 -DWIN32_LEAN_AND_MEAN=1 -DWINNT=1 -DWINVER=0x0501 -D_DEBUG -D_DLL=1 -D_IDWBUILD -D_MBCS -D_NT1X_=100 -D_WIN32_IE=0x0600 -D_WIN32_WINNT=0x0501 -D_WINDOWS -D_X86_=1 -Di386=1 -FD -FI$(ddkpath)\inc\wxp\warning.h -FR -G6 -GF -GR- -GX- -Gi- -Gm- -Gy -Gz -Od -Oi -Oy- -QI0f -QIf -QIfdiv- -W3 -WX -Yu"stddcls.h" -Z7 -Zel -Zp8 -c -cbstring -I"$(wdmbook)\generic" -I$(ddkpath)\inc\wxp -I"$(ddkpath)\inc\ddk\wxp" -I"$(ddkpath)\inc\ddk\wdm\wxp" -I"$(ddkpath)\inc\crt" # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32# ADD BASE RSC /l 0x409 /d "_DEBUG" /i "$(wdmbook)\generic" /i $(ddkpath)\inc\wxp /i "$(ddkpath)\inc\ddk\wxp" /i "$(ddkpath)\inc\ddk\wdm\wxp" /i "$(ddkpath)\inc\crt" # ADD RSC /l 0x409 /d "_DEBUG" /i "$(wdmbook)\generic" /i $(ddkpath)\inc\wxp /i "$(ddkpath)\inc\ddk\wxp" /i "$(ddkpath)\inc\ddk\wdm\wxp" /i "$(ddkpath)\inc\crt" BSC32=bscmake.exe# ADD BASE BSC32 /nologo# ADD BSC32 /nologoLINK32=link.exe# ADD BASE LINK32 -nologo -align:0x80 -base:0x10000 -debug:full -debugtype:cv -debugtype:cv -driver:wdm -entry:DriverEntry@8 -fullbuild -ignore:4010,4037,4039,4049,4065,4070,4078,4087,4089,4198,4221 -incremental:no -libpath:"$(ddkpath)\lib\wxp\i386" -libpath:"$(wdmbook)\generic\objchk_wxp_x86\i386" -merge:_PAGE=PAGE -merge:_TEXT=.text -nodefaultlib -opt:icf -opt:nowin98 -opt:ref -osversion:4.00 -release -section:init,d -stack:0x40000,0x1000 -subsystem:native,4.00 -version:5.1 wdm.lib generic.lib ntoskrnl.lib wmilib.lib -out:objchk_wxp_x86\i386\harderr.sys# ADD LINK32 -nologo -align:0x80 -base:0x10000 -debug:full -debugtype:cv -debugtype:cv -driver:wdm -entry:DriverEntry@8 -fullbuild -ignore:4010,4037,4039,4049,4065,4070,4078,4087,4089,4198,4221 -incremental:no -libpath:"$(ddkpath)\lib\wxp\i386" -libpath:"$(wdmbook)\generic\objchk_wxp_x86\i386" -merge:_PAGE=PAGE -merge:_TEXT=.text -nodefaultlib -opt:icf -opt:nowin98 -opt:ref -osversion:4.00 -release -section:init,d -stack:0x40000,0x1000 -subsystem:native,4.00 -version:5.1 wdm.lib generic.lib ntoskrnl.lib wmilib.lib -out:objchk_wxp_x86\i386\harderr.sys# Begin Special Build ToolTargetPath=.\objchk_wxp_x86\i386\harderr.sysSOURCE="$(InputPath)"PostBuild_Cmds=copy $(TargetPath) $(WINDIR)\system32\drivers$(SIWPATH)\nmsym -translate:source,package,always $(TargetPath)# End Special Build Tool

!ENDIF

# Begin Target

# Name "harderr - Win32 Free"# Name "harderr - Win32 Checked"# Begin Group "Source Files"

# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"# Begin Source File

SOURCE=.\driver.rc# End Source File# Begin Source File

SOURCE=.\DriverEntry.cpp# End Source File# Begin Source File

SOURCE=.\ReadWrite.cpp# End Source File# Begin Source File

SOURCE=.\stddcls.cpp# ADD CPP /Yc"stddcls.h"# End Source File# End Group# Begin Group "Header Files"

# PROP Default_Filter "h;hpp;hxx;hm;inl"# Begin Source File

SOURCE=.\Driver.h# End Source File# Begin Source File

SOURCE=.\guids.h# End Source File# Begin Source File

SOURCE=.\stddcls.h# End Source File# End Group# Begin Group "Resource Files"

# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"# End Group# Begin Source File

SOURCE=.\harderr.inf# End Source File# End Target# End Project

Samples/AppendixA/harderr/harderr.htm

The HARDERR Sample

The HARDERR Sample accompanies Appendix A and illustrates how to log an I/O error. The real purpose of this sample is to demonstrate how to use the Windows 98/Me implementation of IoRaiseInformationalHardError that was added to WDMSTUB.VXD in Service Pack 2 for the 1st edition.

The sample includes one component:

HARDERR.SYS is a WDM driver for a non-existent hardware device.

Building HARDERR

To build HARDERR.SYS, follow the general instructions for building a WDM sample. The Microsoft Visual C++ project file is named HARDERR.DSP.

Testing HARDERR

Follow the general instructions for using FastInst in either Windows XP or Windows 98/Me. The INF file is named HARDERR.INF. Each time you start the HARDERR device (including the first time, which occurs during installation), it will call IoRaiseInformationalHardError, which will in turn display a dialog box informing you of an unspecified error.

What to look for

It would more interesting to look at the implementation of IoRaiseInformationalHardErrorin wdmstub.sys than at this sample.

Samples/AppendixA/harderr/harderr.inf[Version]Signature=$CHICAGO$Class=SampleClassGuid={894A7460-A033-11D2-821E-444553540000}Provider=%MFGNAME%

;------------------------------------------------------------------------------; SAMPLE class definition;------------------------------------------------------------------------------

[ClassInstall32]AddReg=ClassInstall32AddRegCopyFiles=ClassInstall32CopyFiles

[ClassInstall32AddReg]HKR,,,,"WDM Book Samples"HKR,,Installer32,,"samclass.dll,SampleClassInstaller"HKR,,EnumPropPages32,,samclass.dllHKR,,Icon,,101

[ClassInstall32CopyFiles]samclass.dll,,,2

[ClassInstall]AddReg=ClassInstallAddRegCopyFiles=ClassInstallCopyFiles

[ClassInstallAddReg]HKR,,,,"WDM Book Samples"HKR,,EnumPropPages,,samcls16.dllHKR,,Icon,,102

[ClassInstallCopyFiles]samcls16.dll,,,2

;------------------------------------------------------------------------------; Standard INF sections;------------------------------------------------------------------------------

[Manufacturer]%MFGNAME%=DeviceList

[DestinationDirs]DefaultDestDir=10,System32\DriversClassInstallCopyFiles=11ClassInstall32CopyFiles=11

[SourceDisksFiles]harderr.sys=1,objchk~1\i386generic.sys=1,..\..\generic\objchk~1\i386,wdmstub.sys=1,..\..\Append~1\newstub\objchk~1\i386,samclass.dll=1,..\..\Chap15\samclass\release,samcls16.dll=1,..\..\Chap15\samclass\samcls16,

[SourceDisksNames]1=%INSTDISK%,,,

[DeviceList]%DESCRIPTION%=DriverInstall,*WCO0A01

;------------------------------------------------------------------------------; Windows 2000 Sections;------------------------------------------------------------------------------

[DriverInstall.ntx86]CopyFiles=DriverCopyFiles

[DriverCopyFiles]harderr.sys,,,2generic.sys,,,2

[DriverInstall.ntx86.Services]AddService=HARDERR,2,DriverService

[DriverService]ServiceType=1StartType=3ErrorControl=1ServiceBinary=%10%\system32\drivers\harderr.sys

[DriverInstall.ntx86.hw]AddReg=DriverHwAddReg

[DriverHwAddReg]HKR,,SampleInfo,,"%wdmbook%\AppendixA\harderr\harderr.htm"

;------------------------------------------------------------------------------; Windows 98 Sections;------------------------------------------------------------------------------

[DriverInstall]AddReg=DriverAddRegCopyFiles=DriverCopyFiles;,StubCopyFiles

[DriverAddReg]HKR,,DevLoader,,*ntkernHKR,,NTMPDriver,,"wdmstub.sys,harderr.sys"

[StubCopyFiles]wdmstub.sys,,,2

[DriverInstall.HW]AddReg=DriverHwAddReg

;------------------------------------------------------------------------------; String Definitions;------------------------------------------------------------------------------

[Strings]MFGNAME="Walter Oney Software"INSTDISK="Walter Oney Software Installation Disc"DESCRIPTION="Hard Error Test"

Samples/AppendixA/harderr/makefile## 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 Windows NT#!INCLUDE $(NTMAKEENV)\makefile.def

Samples/AppendixA/harderr/objchk_wxp_x86/i386/harderr.NMS

Samples/AppendixA/harderr/objchk_wxp_x86/i386/harderr.pdb

Samples/AppendixA/harderr/objchk_wxp_x86/i386/harderr.sys

Samples/AppendixA/harderr/ReadWrite.cpp

Samples/AppendixA/harderr/ReadWrite.cpp//Read/Writerequestprocessorsforharderrdriver

//Copyright(C)1999byWalterOney

//Allrightsreserved

#include"stddcls.h"

#include"driver.h"

///////////////////////////////////////////////////////////////////////////////

#pragmaPAGEDCODE

NTSTATUSStartDevice(PDEVICE_OBJECTfdo,PCM_PARTIAL_RESOURCE_LISTraw,PCM_PARTIAL_RESOURCE_LISTtranslated)

{//StartDevice

PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

UNICODE_STRINGmsg;

RtlInitUnicodeString(&msg,L"Hello,world!");

IoRaiseInformationalHardError(STATUS_UNSUCCESSFUL,&msg,NULL);

returnSTATUS_SUCCESS;

}//StartDevice

///////////////////////////////////////////////////////////////////////////////

#pragmaPAGEDCODE

VOIDStopDevice(INPDEVICE_OBJECTfdo,BOOLEANoktouch/*=FALSE*/)

{//StopDevice

PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

}//StopDevice

Samples/AppendixA/harderr/sourcesTARGETNAME=harderrTARGETPATH=objTARGETTYPE=DRIVERUSE_PDB=1

INCLUDES=$(WDMBOOK)\genericTARGETLIBS=$(WDMBOOK)\generic\obj$(BUILD_ALT_DIR)\*\generic.libSOURCES= DriverEntry.cpp \ReadWrite.cpp

Samples/AppendixA/harderr/stddcls.cpp

Samples/AppendixA/harderr/stddcls.cpp//stddcls.cpp--PrecompiledheaderstubforWDMdriver

//Copyright(C)1999byWalterOney

//Allrightsreserved

#include"stddcls.h"

Samples/AppendixA/harderr/stddcls.h// stddcls.h -- Precompiled headers for WDM drivers// Copyright (C) 1999 by Walter Oney// All rights reserved

#ifdef __cplusplusextern "C" {#endif

#pragma warning(disable:4201)// nameless struct/union#define DEPRECATE_DDK_FUNCTIONS 1

#include #include

#ifdef __cplusplus}#endif

#define PAGEDCODE code_seg("page")#define LOCKEDCODE code_seg()#define INITCODE code_seg("init")

#define PAGEDDATA data_seg("page")#define LOCKEDDATA data_seg()#define INITDATA data_seg("init")

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))

Samples/AppendixA/Newstub/Driver.h// Declarations for wdmstub driver// Copyright (C) 1999, 2000 by Walter Oney// All rights reserved

#ifndef DRIVER_H#define DRIVER_H

#define DRIVERNAME "WDMSTUB"// for use in messages#define LDRIVERNAME L"WDMSTUB"// for use in UNICODE string constants

///////////////////////////////////////////////////////////////////////////////// Device extension structure

typedef struct _DEVICE_EXTENSION {ULONG flags;// flags common to dummy device extensionPDEVICE_OBJECT DeviceObject;// device object this extension belongs toPDEVICE_OBJECT LowerDeviceObject;// next lower driver in same stackPDEVICE_OBJECT Pdo;// the PDO} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

typedef struct _DUMMY_DEVICE_EXTENSION {ULONG flags;// flags common to layered device object} DUMMY_DEVICE_EXTENSION, *PDUMMY_DEVICE_EXTENSION;

#define DUMMY_DEVICE_FLAG0x00000001// TRUE if this is the dummy device object

///////////////////////////////////////////////////////////////////////////////

typedef struct _COMPLETION_CONTEXT {PIO_COMPLETION_ROUTINE CompletionRoutine;PVOID Context;PDEVICE_OBJECT fdo;} COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT;

///////////////////////////////////////////////////////////////////////////////// This internal IOCTL is used for version checking between clones of WDMSTUB:

#define IOCTL_INTERNAL_WDMSTUB_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)

///////////////////////////////////////////////////////////////////////////////// Global functions

VOID RemoveDevice(IN PDEVICE_OBJECT fdo);NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info);BOOLEAN DefineStubs();VOID UndefineStubs();

#endif // DRIVER_H

Samples/AppendixA/Newstub/driver.rc// Resource script for wdmstub driver// Generated by Walt Oney's driver wizard

#include #include "version.h"

LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL

VS_VERSION_INFO VERSIONINFO FILEVERSION VERMAJOR,VERMINOR,0,BUILD PRODUCTVERSION VERMAJOR,VERMINOR,0,BUILD FILEFLAGSMASK 0x3fL#ifdef _DEBUG FILEFLAGS 0x1L#else FILEFLAGS 0x0L#endif FILEOS 0x40004L FILETYPE 0x1L FILESUBTYPE 0x0LBEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "This driver may be redistributed only under special license from Walter Oney Software\0" VALUE "CompanyName", "Walter Oney Software\0" VALUE "FileDescription", "WDM stub functions for Windows 98\0" VALUE "FileVersion", PRODVER VALUE "InternalName", "WDMSTUB\0" VALUE "LegalCopyright", "Copyright 2000 by Walter Oney\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "wdmstub.sys\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Programming the Microsoft Windows Driver Model SP-4\0" VALUE "ProductVersion", PRODVER VALUE "SpecialBuild", "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 ENDEND

Samples/AppendixA/Newstub/DriverEntry.cpp

Samples/AppendixA/Newstub/DriverEntry.cpp//Mainprogramforwdmstubdriver

//Copyright(C)2000byWalterOney

//Allrightsreserved

//UsethisdriverasalowerfilterforanyWDMdriverthatusesoneormore

//ofthenon-WDMfunctionsthisdriversupports.

#include"stddcls.h"

#include"driver.h"

#include"version.h"

NTSTATUSAddDevice(INPDRIVER_OBJECTDriverObject,INPDEVICE_OBJECTpdo);

VOIDDriverUnload(INPDRIVER_OBJECTfdo);

NTSTATUSDispatchAny(INPDEVICE_OBJECTfido,INPIRPIrp);

NTSTATUSDispatchInternalControl(INPDEVICE_OBJECTfido,INPIRPIrp);

NTSTATUSDispatchPower(INPDEVICE_OBJECTfido,INPIRPIrp);

NTSTATUSDispatchPnp(INPDEVICE_OBJECTfido,INPIRPIrp);

BOOLEANIsWin98();

BOOLEANStubsDefined=FALSE;//trueifwedefinedanystubs

PDEVICE_OBJECTDummyDeviceObject=NULL;//dummydeviceobject

BOOLEANCheckCloneVersions(PDRIVER_OBJECTDriverObject);

///////////////////////////////////////////////////////////////////////////////

//Declaredummysymbolstoboundthepointersemittedbythecompilerfor

//staticinitializationfunctions.

typedefvoid(__cdecl*INITFUNCTION)();

#pragmadata_seg(".CRT$XCA")

staticINITFUNCTIONBeginInitFunctions[1]={0};

#pragmadata_seg(".CRT$XCZ")

staticINITFUNCTIONEndInitFunctions[1]={0};

#pragmadata_seg()

///////////////////////////////////////////////////////////////////////////////

#pragmaINITCODE

extern"C"NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,

INPUNICODE_STRINGRegistryPath)

{//DriverEntry

//Seeifwe'rerunningunderWin98orNT:

if(!IsWin98())

{

KdPrint((DRIVERNAME"-DrivershouldonlybeusedinWindows98"));

returnSTATUS_UNSUCCESSFUL;

}

//Executestaticinitializationroutines.ThisbecamenecessarywithSP-9

//whenwestartedusingtheXpDDKcompiler

for(INITFUNCTION*p=BeginInitFunctions+1;pDriverUnload=DriverUnload;

DriverObject->DriverExtension->AddDevice=AddDevice;

for(inti=0;iMajorFunction);++i)

DriverObject->MajorFunction[i]=DispatchAny;

DriverObject->MajorFunction[IRP_MJ_POWER]=DispatchPower;

DriverObject->MajorFunction[IRP_MJ_PNP]=DispatchPnp;

DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]=DispatchInternalControl;

//SeeifthereareotherinstancesofWDMSTUBrunningonthiscomputer.These

//mightincludetheoriginalWDMSTUB.VXDfromthebookoranOEMcloneofthis

//driver.

StubsDefined=CheckCloneVersions(DriverObject);

//CreateexportdefinitionsfortheWDMfunctionsthisdriversupplies

if(StubsDefined&&!DefineStubs())

{//errordefiningstubs

ObDereferenceObject(DriverObject);

IoDeleteDevice(DummyDeviceObject);

returnSTATUS_UNSUCCESSFUL;

}//errordefiningstubs

returnSTATUS_SUCCESS;

}//DriverEntry

///////////////////////////////////////////////////////////////////////////////

#pragmaPAGEDCODE

NTSTATUSAddDevice(INPDRIVER_OBJECTDriverObject,INPDEVICE_OBJECTpdo)

{//AddDevice

PAGED_CODE();

NTSTATUSstatus;

//Createafunctiondeviceobjecttorepresentthehardwarewe'remanaging.

PDEVICE_OBJECTfdo;

#definexsizesizeof(DEVICE_EXTENSION)

status=IoCreateDevice(DriverObject,xsize,NULL,

FILE_DEVICE_UNKNOWN,0,FALSE,&fdo);

if(!NT_SUCCESS(status))

{//can'tcreatedeviceobject

KdPrint((DRIVERNAME"-IoCreateDevicefailed-%X\n",status));

returnstatus;

}//can'tcreatedeviceobject


PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

//Fromthispointforward,anyerrorwillhavesideeffectsthatneedto

//becleanedup.

do

{//finishinitialization

pdx->DeviceObject=fdo;

pdx->Pdo=pdo;

//Addourdeviceobjecttothestackandpropagatecriticalsettings

//fromtheimmediatelylowerdeviceobject

PDEVICE_OBJECTldo=IoAttachDeviceToDeviceStack(fdo,pdo);

if(!ldo)

{//can'tattachdevice

KdPrint((DRIVERNAME"-IoAttachDeviceToDeviceStackfailed\n"));

status=STATUS_DEVICE_REMOVED;

break;;

}//can'tattachdevice

pdx->LowerDeviceObject=ldo;

fdo->DeviceType=ldo->DeviceType;

fdo->Characteristics=ldo->Characteristics;

//CopytheflagsrelatedtoI/ObufferingfromthelowerdeviceobjectsotheI/Omanager

//willcreatetheexpecteddatastructuresforreadsandwrites.

fdo->Flags|=ldo->Flags&(DO_DIRECT_IO|DO_BUFFERED_IO);

//Indicatethatwehaveapagablepowerhandler.Thereasonwedothisisactuallyfairly

//complex,asfollows.It'sokaytohaveapagablepowerhandlerlayeredaboveanon-paged

//orin-rushpowerhandler,butnottheotherwayaround.Ifwe'reanupperfilterforany

//kindofdevice,it'ssafertoleavethisflagsetalways.Ifweweretoclearit(for

//example,becausewenoticethattheguyunderusisnon-pagedorbecomessoafter

//processingausagenotification),wewouldhavetoalwayssetitwhenpassingdown

//usagenotificationslateronorriskviolatingtherule.

//IFWEAREALOWERFILTERFORADEVICETHATHASANON-PAGABLEPOWERHANDLER,ORFORA

//DEVICETHATCHANGESBETWEENPAGEDANDNON-PAGEDDEPENDINGONUSAGENOTIFICATIONS,THIS

//SIMPLISTICCODEISWRONG.YOUMUSTFINDOUTHOWTHEUPPERDRIVERWILLHANDLETHE

//DO_POWER_PAGABLEFLAGANDDOTHERIGHTTHING.

fdo->Flags|=DO_POWER_PAGABLE;

//Clearthe"initializing"flagsothatwecangetIRPs

fdo->Flags&=~DO_DEVICE_INITIALIZING;

}//finishinitialization

while(FALSE);

if(!NT_SUCCESS(status))

{//needtocleanup

if(pdx->LowerDeviceObject)

IoDetachDevice(pdx->LowerDeviceObject);

IoDeleteDevice(fdo);

}//needtocleanup

returnstatus;

}//AddDevice

///////////////////////////////////////////////////////////////////////////////

//CheckCloneVersionslooksfortheVxDversionofWDMSTUBoranOEMcloneof

//thissamefilterdriverandevaluatestheversionnumber(s)ofanysuch.

//ItreturnsTRUEifversioncheckingindicatesthatweshouldstuborimplement

//atleastonefunction.

#pragmaPAGEDCODE

BOOLEANCheckCloneVersions(PDRIVER_OBJECTDriverObject)

{//CheckCloneVersions

BOOLEANresult=TRUE;

//SeeifthereisaVxDversionofWDMSTUBloadedand,ifso,whatit'sversion

//numberis.

PVMMDDBddb=Get_DDB(0,"WDMSTUB");

if(ddb)

{//VxDversionloaded

if(ddb->DDB_Dev_Major_Version>VERMAJOR||(ddb->DDB_Dev_Major_Version==VERMAJOR&&ddb->DDB_Dev_Minor_Version>VERMINOR))

{//defertoVxD

KdPrint((DRIVERNAME"-DeferringtoWDMSTUB.VXDversion%d.%2.2d\n",ddb->DDB_Dev_Major_Version,ddb->DDB_Dev_Minor_Version));

result=FALSE;

}//defertoVxD

else

KdPrint((DRIVERNAME"-OverridingWDMSTUB.VXDversion%d.%2.2d\n",ddb->DDB_Dev_Major_Version,ddb->DDB_Dev_Minor_Version));

}//VxDversionloaded

//Seeifthereisacloneofthisfilterdriverwithahigherversionnumber

ULONGindex;//currentdriverindex

ULONGavail=0xFFFFFFFF;//anavailabledriverindex

WCHARnamebuf[32];

UNICODE_STRINGdevname;

KEVENTevent;

KeInitializeEvent(&event,SynchronizationEvent,FALSE);

IO_STATUS_BLOCKiostatus;

NTSTATUSstatus;

//LookfordummydeviceobjectsWDMSTUB0throughWDMSTUB99

for(index=0;index=((VERMAJOR16,version&0xFFFF));

result=FALSE;

}//foundhigherversion

else

KdPrint((DRIVERNAME"-OverridingWDMSTUBcloneversion%d.%2.2d\n",version>>16,version&0xFFFF));

}//checkversion#

else

KdPrint((DRIVERNAME"-IOCTL_INTERNAL_WDMSTUB_GET_VERSIONfailedto%ws-%X\n",devname,status));

}//sendIRP

//Dereferencethefileobjecttoreleaseourholdontheclonedeviceobject

ObDereferenceObject(fop);

}//foundaclone

//Ifthere'snodeviceobjectbythisname,remembertheindexforwhenweneedtocreateourown

//deviceobject

elseif(avail==0xFFFFFFFF)

avail=index;

}//foreachpossibledriverindex

//Checktheresultoftheversioncomparisons

if(!result)

returnFALSE;

//Wehavedecidedtostubsomefunctions.Createadummydeviceobjectso

//otherclonescanfindus.Alsotakeanextrareferencetothedriverobject

//topinusintomemory--someotherWDMdrivermayendupusingoneofour

//stubs

if(avail==0xFFFFFFFF)

{

KdPrint((DRIVERNAME"-Morethan100WDMSTUBclonesareloadedinthissystem!\n"));

returnFALSE;

}

_snwprintf(namebuf,arraysize(namebuf),L"\\Device\\WDMSTUB%d",avail);

RtlInitUnicodeString(&devname,namebuf);

status=IoCreateDevice(DriverObject,sizeof(DUMMY_DEVICE_EXTENSION),&devname,FILE_DEVICE_UNKNOWN,0,FALSE,&DummyDeviceObject);

if(!NT_SUCCESS(status))

{

KdPrint((DRIVERNAME"-IoCreateDevicefailed-%X\n",status));

returnFALSE;

}

ObReferenceObject(DriverObject);//pinthisdriverintomemoryforever

//InitializethedummydeviceextensionsoIRPdispatchfunctionscandistinguishbetweenthis

//andalayereddeviceobject

PDUMMY_DEVICE_EXTENSIONddx=(PDUMMY_DEVICE_EXTENSION)DummyDeviceObject->DeviceExtension;

ddx->flags|=DUMMY_DEVICE_FLAG;

returnTRUE;

}//CheckCloneVersions

///////////////////////////////////////////////////////////////////////////////

#pragmaLOCKEDCODE

NTSTATUSCompleteRequest(INPIRPIrp,INNTSTATUSstatus,INULONG_PTRinfo)

{//CompleteRequest

Irp->IoStatus.Status=status;

Irp->IoStatus.Information=info;

IoCompleteRequest(Irp,IO_NO_INCREMENT);

returnstatus;

}//CompleteRequest

NTSTATUSCompleteRequest(INPIRPIrp,INNTSTATUSstatus)

{//CompleteRequest

Irp->IoStatus.Status=status;

IoCompleteRequest(Irp,IO_NO_INCREMENT);

returnstatus;

}//CompleteRequest

///////////////////////////////////////////////////////////////////////////////

#pragmaLOCKEDCODE//makenoassumptionsaboutpageabilityofdispatchfcns

NTSTATUSDispatchAny(INPDEVICE_OBJECTfido,INPIRPIrp)

{//DispatchAny

PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fido->DeviceExtension;


//FailanyIRPsaddressedtothedummydeviceobjectotherthanCREATEandCLOSE

if(pdx->flags&DUMMY_DEVICE_FLAG)

{//IRPfordummydevice

PIO_STACK_LOCATIONstack=IoGetCurrentIrpStackLocation(Irp);

NTSTATUSstatus=STATUS_INVALID_DEVICE_REQUEST;

if(stack->MajorFunction==IRP_MJ_CREATE||stack->MajorFunction==IRP_MJ_CLOSE)

status=STATUS_SUCCESS;

returnCompleteRequest(Irp,status);

}//IRPfordummydevice

//PassdownIRPsaddressedtotheFiDO

IoSkipCurrentIrpStackLocation(Irp);

returnIoCallDriver(pdx->LowerDeviceObject,Irp);

}//DispatchAny

///////////////////////////////////////////////////////////////////////////////

NTSTATUSDispatchInternalControl(PDEVICE_OBJECTdummy,PIRPIrp)

{//DispatchInternalControl

PDUMMY_DEVICE_EXTENSIONddx=(PDUMMY_DEVICE_EXTENSION)dummy->DeviceExtension;

if(!(ddx->flags&DUMMY_DEVICE_FLAG))

{//notforus

IoSkipCurrentIrpStackLocation(Irp);

returnIoCallDriver(((PDEVICE_EXTENSION)(ddx))->LowerDeviceObject,Irp);

}//notforus

NTSTATUSstatus;

ULONGinfo=0;


PIO_STACK_LOCATIONstack=IoGetCurrentIrpStackLocation(Irp);

ULONGcode=stack->Parameters.DeviceIoControl.IoControlCode;

ULONGcbin=stack->Parameters.DeviceIoControl.InputBufferLength;

ULONGcbout=stack->Parameters.DeviceIoControl.OutputBufferLength;

switch(code)

{//processinternalcontroloperation

//Versionquery:returntheversionnumberofthisdriver

caseIOCTL_INTERNAL_WDMSTUB_GET_VERSION:

if(cboutUserBuffer)=(VERMAJORflags&DUMMY_DEVICE_FLAG)

returnCompleteRequest(Irp,STATUS_SUCCESS);//shouldn'thappeninthe1stplace

IoSkipCurrentIrpStackLocation(Irp);

returnPoCallDriver(pdx->LowerDeviceObject,Irp);

}//DispatchPower

///////////////////////////////////////////////////////////////////////////////

#pragmaLOCKEDCODE

NTSTATUSDispatchPnp(INPDEVICE_OBJECTfido,INPIRPIrp)

{//DispatchPnp

PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fido->DeviceExtension;

//Thedummydeviceshouldn'tgetanyPnPIRPs

if(pdx->flags&DUMMY_DEVICE_FLAG)

returnCompleteRequest(Irp,STATUS_SUCCESS);//don'tchangeInformationfield

//PassdownPnPrequest

PIO_STACK_LOCATIONstack=IoGetCurrentIrpStackLocation(Irp);

ULONGfcn=stack->MinorFunction;

NTSTATUSstatus;

IoSkipCurrentIrpStackLocation(Irp);

status=IoCallDriver(pdx->LowerDeviceObject,Irp);

if(fcn==IRP_MN_REMOVE_DEVICE)

RemoveDevice(fido);

returnstatus;

}//DispatchPnp

///////////////////////////////////////////////////////////////////////////////

#pragmaPAGEDCODE

VOIDDriverUnload(INPDRIVER_OBJECTDriverObject)

{//DriverUnload

PAGED_CODE();

//Deleteourdummydeviceobject

if(DummyDeviceObject)

IoDeleteDevice(DummyDeviceObject);

//Itshouldnotbepossibleforthisdrivertobeunloadedifwedefined

//anystubs.Don'tprecludethis,though,becausetheremaybesomefuture

//mechanismthatwouldmakethissafe.

if(StubsDefined)

UndefineStubs();

}//DriverUnload

///////////////////////////////////////////////////////////////////////////////

#pragmaPAGEDCODE

VOIDRemoveDevice(INPDEVICE_OBJECTfdo)

{//RemoveDevice

PAGED_CODE();

PDEVICE_EXTENSIONpdx=(PDEVICE_EXTENSION)fdo->DeviceExtension;

ASSERT(!(pdx->flags&DUMMY_DEVICE_FLAG));//shouldn'tbepossible

NTSTATUSstatus;

if(pdx->LowerDeviceObject)

IoDetachDevice(pdx->LowerDeviceObject);

IoDeleteDevice(fdo);

}//RemoveDevice

///////////////////////////////////////////////////////////////////////////////

#pragmaINITCODE

BOOLEANIsWin98()

{//IsWin98

#ifdef_X86_

//Windows98(including2ded)supportsWDMversion1.0,whereasWin2K

//supports1.10.

return!IoIsWdmVersionAvailable(1,0x10);

#else//not_X86_

returnFALSE;

#endif//not_X86_

}//IsWin98

#pragmaLOCKEDCODE//forceinlinefunctionsintolockedcode

Samples/AppendixA/Newstub/Ifsmgr.h// IFSMGR.H -- Declarations for Installable File System Manager Calls// Copyright (C) 1996 by Walter Oney// All rights reserved

#ifndef IFSMGR_H#define IFSMGR_H

#ifdef __cplusplusextern "C" {#endif

#ifndef IFSMGR_SERVICES_ONLY#include "ifs.h"

#define IFSMGRVERSION 0x22

#endif // IFSMGR_SERVICES_ONLY

///////////////////////////////////////////////////////////////////////////////// IFSMgr services

#ifndef IFSMgr_DEVICE_ID#define IFSMgr_DEVICE_ID 0x0040#endif

#ifndef Not_VxD

#undef IFSMgr_Service#define IFSMgr_Service Declare_Service#pragma warning(disable:4003)// not enough parameters

Begin_Service_Table(IFSMgr)

IFSMgr_Service(IFSMgr_Get_Version)IFSMgr_Service(IFSMgr_RegisterMount)IFSMgr_Service(IFSMgr_RegisterNet)IFSMgr_Service(IFSMgr_RegisterMailSlot)IFSMgr_Service(IFSMgr_Attach)IFSMgr_Service(IFSMgr_Detach)IFSMgr_Service(IFSMgr_Get_NetTime)IFSMgr_Service(IFSMgr_Get_DOSTime)IFSMgr_Service(IFSMgr_SetupConnection)IFSMgr_Service(IFSMgr_DerefConnection)IFSMgr_Service(IFSMgr_ServerDOSCall)IFSMgr_Service(IFSMgr_CompleteAsync)IFSMgr_Service(IFSMgr_RegisterHeap)IFSMgr_Service(IFSMgr_GetHeap)IFSMgr_Service(IFSMgr_RetHeap)IFSMgr_Service(IFSMgr_CheckHeap)IFSMgr_Service(IFSMgr_CheckHeapItem)IFSMgr_Service(IFSMgr_FillHeapSpare)IFSMgr_Service(IFSMgr_Block)IFSMgr_Service(IFSMgr_Wakeup)IFSMgr_Service(IFSMgr_Yield)IFSMgr_Service(IFSMgr_SchedEvent)IFSMgr_Service(IFSMgr_QueueEvent)IFSMgr_Service(IFSMgr_KillEvent)IFSMgr_Service(IFSMgr_FreeIOReq)IFSMgr_Service(IFSMgr_MakeMailSlot)IFSMgr_Service(IFSMgr_DeleteMailSlot)IFSMgr_Service(IFSMgr_WriteMailSlot)IFSMgr_Service(IFSMgr_PopUp)IFSMgr_Service(IFSMgr_printf)IFSMgr_Service(IFSMgr_AssertFailed)IFSMgr_Service(IFSMgr_LogEntry)IFSMgr_Service(IFSMgr_DebugMenu)IFSMgr_Service(IFSMgr_DebugVars)IFSMgr_Service(IFSMgr_GetDebugString)IFSMgr_Service(IFSMgr_GetDebugHexNum)IFSMgr_Service(IFSMgr_NetFunction)IFSMgr_Service(IFSMgr_DoDelAllUses)IFSMgr_Service(IFSMgr_SetErrString)IFSMgr_Service(IFSMgr_GetErrString)IFSMgr_Service(IFSMgr_SetReqHook)IFSMgr_Service(IFSMgr_SetPathHook)IFSMgr_Service(IFSMgr_UseAdd)IFSMgr_Service(IFSMgr_UseDel)IFSMgr_Service(IFSMgr_InitUseAdd)IFSMgr_Service(IFSMgr_ChangeDir)IFSMgr_Service(IFSMgr_DelAllUses)IFSMgr_Service(IFSMgr_CDROM_Attach)IFSMgr_Service(IFSMgr_CDROM_Detach)IFSMgr_Service(IFSMgr_Win32DupHandle)IFSMgr_Service(IFSMgr_Ring0_FileIO)IFSMgr_Service(IFSMgr_Win32_Get_Ring0_Handle)IFSMgr_Service(IFSMgr_Get_Drive_Info)IFSMgr_Service(IFSMgr_Ring0GetDriveInfo)IFSMgr_Service(IFSMgr_BlockNoEvents)IFSMgr_Service(IFSMgr_NetToDosTime)IFSMgr_Service(IFSMgr_DosToNetTime)IFSMgr_Service(IFSMgr_DosToWin32Time)IFSMgr_Service(IFSMgr_Win32ToDosTime)IFSMgr_Service(IFSMgr_NetToWin32Time)IFSMgr_Service(IFSMgr_Win32ToNetTime)IFSMgr_Service(IFSMgr_MetaMatch)IFSMgr_Service(IFSMgr_TransMatch)IFSMgr_Service(IFSMgr_CallProvider)IFSMgr_Service(UniToBCS)IFSMgr_Service(UniToBCSPath)IFSMgr_Service(BCSToUni)IFSMgr_Service(UniToUpper)IFSMgr_Service(UniCharToOEM)IFSMgr_Service(CreateBasis)IFSMgr_Service(MatchBasisName)IFSMgr_Service(AppendBasisTail)IFSMgr_Service(FcbToShort)IFSMgr_Service(ShortToFcb)IFSMgr_Service(IFSMgr_ParsePath)IFSMgr_Service(Query_PhysLock)IFSMgr_Service(_VolFlush)IFSMgr_Service(NotifyVolumeArrival)IFSMgr_Service(NotifyVolumeRemoval)IFSMgr_Service(QueryVolumeRemoval)IFSMgr_Service(IFSMgr_FSDUnmountCFSD)IFSMgr_Service(IFSMgr_GetConversionTablePtrs)IFSMgr_Service(IFSMgr_CheckAccessConflict)IFSMgr_Service(IFSMgr_LockFile)IFSMgr_Service(IFSMgr_UnlockFile)IFSMgr_Service(IFSMgr_RemoveLocks)IFSMgr_Service(IFSMgr_CheckLocks)IFSMgr_Service(IFSMgr_CountLocks)IFSMgr_Service(IFSMgr_ReassignLockFileInst)IFSMgr_Service(IFSMgr_UnassignLockList)IFSMgr_Service(IFSMgr_MountChildVolume)IFSMgr_Service(IFSMgr_UnmountChildVolume)IFSMgr_Service(IFSMgr_SwapDrives)IFSMgr_Service(IFSMgr_FSDMapFHtoIOREQ)IFSMgr_Service(IFSMgr_FSDParsePath)IFSMgr_Service(IFSMgr_FSDAttachSFT)IFSMgr_Service(IFSMgr_GetTimeZoneBias)IFSMgr_Service(IFSMgr_PNPEvent)IFSMgr_Service(IFSMgr_RegisterCFSD)IFSMgr_Service(IFSMgr_Win32MapExtendedHandleToSFT)IFSMgr_Service(IFSMgr_DbgSetFileHandleLimit)IFSMgr_Service(IFSMgr_Win32MapSFTToExtendedHandle)IFSMgr_Service(IFSMgr_FSDGetCurrentDrive)IFSMgr_Service(IFSMgr_InstallFileSystemApiHook)IFSMgr_Service(IFSMgr_RemoveFileSystemApiHook)IFSMgr_Service(IFSMgr_RunScheduledEvents)IFSMgr_Service(IFSMgr_CheckDelResource)IFSMgr_Service(IFSMgr_Win32GetVMCurdir)IFSMgr_Service(IFSMgr_SetupFailedConnection)IFSMgr_Service(_GetMappedErr)IFSMgr_Service(ShortToLossyFcb)IFSMgr_Service(IFSMgr_GetLockState)IFSMgr_Service(BcsToBcs)IFSMgr_Service(IFSMgr_SetLoopback)IFSMgr_Service(IFSMgr_ClearLoopback)IFSMgr_Service(IFSMgr_ParseOneElement)IFSMgr_Service(BcsToBcsUpper)

End_Service_Table(IFSMgr)

#pragma warning(default:4003)

#endif // Not_VxD

#ifndef IFSMGR_SERVICES_ONLY

///////////////////////////////////////////////////////////////////////////////// Inline service function definitions:

#ifndef Not_VxD#pragma warning(disable:4035)// missing return value

#undef NAKED#define NAKED __declspec(naked)

DWORD VXDINLINE IFSMgr_Get_Version(){VxDCall(IFSMgr_Get_Version)_asm jnc okay_asm xor eax, eax_asm okay:}

#define NORMAL_FSD 0#define DEFAULT_FSD 1

int NAKED IFSMgr_RegisterCFSD(pIFSFunc fcn, UINT version, string_t* ppDeviceNames){VxDJmp(IFSMgr_RegisterCFSD)}

// Command codes in ir_flags for calls to mailslot procedure:

#define MSLOT_CREATE 0#define MSLOT_DELETE 1#define MSLOT_WRITE 2

int NAKED IFSMgr_RegisterMailSlot(pIFSFunc fcn, UINT version){VxDJmp(IFSMgr_RegisterMailSlot)}

int NAKED IFSMgr_RegisterMount(pIFSFunc fcn, UINT version, UINT defoption){VxDJmp(IFSMgr_RegisterMount)}

int NAKED IFSMgr_RegisterNet(pIFSFunc fcn, UINT version, UINT netid){VxDJmp(IFSMgr_RegisterNet)}

#define DEBUG_FENCE_ON 1

#ifdef DEBUGVOID NAKED IFSMgr_RegisterHeap(pIFSFunc fcn, UINT flag){VxDJmp(IFSMgr_RegisterHeap)}#else#define IFSMgr_RegisterHeapUser(a1,a2)#endif

PVOID NAKED IFSMgr_GetHeap(UINT size){VxDJmp(IFSMgr_GetHeap)}

VOID NAKED IFSMgr_RetHeap(PVOID p){VxDJmp(IFSMgr_RetHeap)}

#ifdef DEBUG#define CHECKHEAP(p) IFSMgr_CheckHeap(p, __FILE__, __LINE__);#define CHECKHEAPITEM(p) IFSMgr_CheckHeapItem(p, __FILE__, __LINE__);int NAKED IFSMgr_CheckHeap(PVOID pmem, char* filename, UINT line){VxDJmp(IFSMgr_CheckHeap)}int NAKED IFSMgr_CheckHeapItem(PVOID pmem, char* filename, UINT line){VxDJmp(IFSMgr_CheckHeapItem)}#else#define CHECKHEAP(p)#define CHECKHEAPITEM(p)#define IFSMgr_CheckHeap(a1, a2, a3)#define IFSMgr_CheckHeapItem(a1, a2, a3)#endif

VOID NAKED IFSMgr_FillHeapSpare(){VxDJmp(IFSMgr_FillHeapSpare)}

typedef DWORD nettime_t;// # seconds since 1/1/1970

typedef struct nettimex_t{DWORD dwSeconds;// # seconds since 1/1/1970DWORD dwMilliseconds;// milliseconds in last second} nettimex_t;

typedef struct dostimex_t{dos_time dostime;// time & data in DOS formatDWORD dwMilliseconds;// # milliseconds in last 2-sec interval} dostimex_t;

nettimex_t NAKED IFSMgr_Get_NetTimeEx(){VxDJmp(IFSMgr_Get_NetTime)}

nettime_t NAKED IFSMgr_Get_NetTime(){VxDJmp(IFSMgr_Get_NetTime)}

dostimex_t NAKED IFSMgr_Get_DOSTimeEx(){VxDJmp(IFSMgr_Get_DOSTime)}

typedef dos_time dostime_t;

dostime_t NAKED IFSMgr_Get_DOSTime(){VxDJmp(IFSMgr_Get_DOSTime)}

dostime_t NAKED IFSMgr_NetToDosTime(DWORD nettime){VxDJmp(IFSMgr_NetToDosTime)}

DWORD NAKED IFSMgr_DosToNetTime(dostime_t dostime){VxDJmp(IFSMgr_DosToNetTime)}

_FILETIME NAKED IFSMgr_DosToWin32Time(dostime_t dostime){VxDJmp(IFSMgr_DosToWin32Time)}

dostime_t NAKED IFSMgr_Win32ToDosTime(_FILETIME win32time){VxDJmp(IFSMgr_Win32ToDosTime)}

_FILETIME NAKED IFSMgr_NetToWin32Time(DWORD nettime){VxDJmp(IFSMgr_NetToWin32Time)}

DWORD NAKED IFSMgr_Win32ToNetTime(_FILETIME win32time){VxDJmp(IFSMgr_Win32ToNetTime)}

int NAKED IFSMgr_GetTimeZoneBias(){VxDJmp(IFSMgr_GetTimeZoneBias)}

VOID NAKED IFSMgr_SetupConnection(pioreq pir, UINT resopt, UINT restype){VxDJmp(IFSMgr_SetupConnection)}

VOID NAKED IFSMgr_DerefConnection(pioreq pir){VxDJmp(IFSMgr_DerefConnection)}

typedef union tagDPL32{struct DPL32_DW {DWORD DPL32_EAX;DWORD DPL32_EBX;DWORD DPL32_ECX;DWORD DPL32_EDX;DWORD DPL32_ESI;DWORD DPL32_EDI;DWORD DPL32_EBP;WORD DPL32_UID;WORD DPL32_PID;DWORD DPL32_DTA;BYTE DPL32_FLAGS;BYTE DPL32_PAD[3];};struct DPL32_W{WORD DPL32_AX, junk1;WORD DPL32_BX, junk2;WORD DPL32_CX, junk3;WORD DPL32_DX, junk4;WORD DPL32_SI, junk5;WORD DPL32_DI, junk6;WORD DPL32_BP, junk7;DWORD DPL32_PID32;};struct DPL32_B{BYTE DPL32_AL, APL32_AH;WORD junk8;BYTE DPL32_BL, APL32_BH;WORD junk9;BYTE DPL32_CL, APL32_CH;WORD junk10;BYTE DPL32_DL, APL32_DH;WORD junk11;};} DPL32, *PDPL32;

#define DPL32_USE_MASK0x03#define DPL32_USE_ANSI0#define DPL32_USE_OEM1#define DPL32_USE_UNICODE2

#define DPL32_8_3_MATCHING0x04

BOOL VXDINLINE IFSMgr_ServerDOSCall(HVM hVM, UINT fcn, PDPL32 dpl, PCRS pRegs){_asm push ebp_asm mov ebx, hVM_asm mov ecx, fcn_asm mov esi, dpl_asm mov ebp, pRegsVxDCall(IFSMgr_ServerDOSCall)_asm pop ebp_asm cmc_asm sbb eax, eax}

typedef int (_cdecl *pMSFunc)(PVOID pdata, UINT len, BYTE lana);

int NAKED IFSMgr_MakeMailSlot(pMSFunc fcn, path_t pmsname, PDWORD pmshand){VxDJmp(IFSMgr_MakeMailSlot)}

int NAKED IFSMgr_DeleteMailSlot(DWORD mshand){VxDJmp(IFSMgr_DeleteMailSlot)}

int NAKED IFSMgr_WriteMailSlot(path_t pmsname, char* pdata, WORD len, BYTE lana, string_t rname, PVOID xtra){VxDJmp(IFSMgr_WriteMailSlot)}

int NAKED IFSMgr_SetErrString(char* errstr, UINT errorcode, UINT table){VxDJmp(IFSMgr_SetErrString)}

NAKED PCHAR IFSMgr_GetErrString(UINT errorcode, UINT table){VxDJmp(IFSMgr_GetErrString)}

typedef void (__cdecl *PPREAMBLE)();

NAKED PPREAMBLE IFSMgr_SetReqHook(UINT request, PPREAMBLE preamble){VxDJmp(IFSMgr_SetReqHook)}

typedef void (__cdecl *PPATHCHECKER)();

NAKED PPATHCHECKER IFSMgr_SetPathHook(PPATHCHECKER fcn){VxDJmp(IFSMgr_SetPathHook)}

#endif // Not_VxD

typedef struct _LM_GUID {WORDguid_uid;// LM10 style user idDWORDguid_serial;// user record serial numberBYTEguid_rsvd[10];// pad to 16 bytes} _LM_GUID;

typedef struct use_info_2 {char ui2_local[9];char ui2_pad_1;char*ui2_remote;char*ui2_password;unsigned short ui2_status; short ui2_asg_type; unsigned short ui2_refcount; unsigned short ui2_usecount; unsigned short ui2_res_type; unsigned short ui2_flags; unsigned short ui2_usrclass; void* ui2_dirname; struct _LM_GUID ui2_dfs_id; } use_info_2, *puse_info_2;

#ifndef Not_VxD

int NAKED IFSMgr_UseAdd(pioreq pir, int proId, netuse_info* pinfo){VxDJmp(IFSMgr_UseAdd)}

int NAKED IFSMgr_InitUseAdd(puse_info_2 pui2, int proId, int lana){VxDJmp(IFSMgr_InitUseAdd)}

int NAKED IFSMgr_UseDel(pioreq pir, int proId, netuse_info* pinfo){VxDJmp(IFSMgr_UseDel)}

int NAKED IFSMgr_DelAllUses(int proId, int force){VxDJmp(IFSMgr_DelAllUses)}

VOID NAKED IFSMgr_DoDelAllUses(pioreq pir){VxDJmp(IFSMgr_DoDelAllUses)}

#if 0int VXDLINLINE NAKED IFSMgr_FSDMapFHtoIOREQ(pioreq pir, WORD doshandle){VxDJmp(IFSMgr_FSDMapFHtoIOREQ)}#endif

int NAKED IFSMgr_CheckDelResource(PVOID rh, int force, BOOL fDelFlag){VxDJmp(IFSMgr_CheckDelResource)}

int NAKED IFSMgr_SetupFailedConnection(pioreq pir, PDWORD pProId){VxDJmp(IFSMgr_SetupFailedConnection)}

int NAKED IFSMgr_SetLoopback(char* pszUNCPath, char* pszLocalPath){VxDJmp(IFSMgr_SetLoopback)}

int NAKED IFSMgr_ClearLoopback(char* pszUNCPath){VxDJmp(IFSMgr_ClearLoopback)}

VOID NAKED IFSMgr_Block(DWORD key){VxDJmp(IFSMgr_Block)}

VOID NAKED IFSMgr_BlockNoEvents(DWORD key){VxDJmp(IFSMgr_BlockNoEvents)}

VOID NAKED IFSMgr_Wakeup(DWORD key){VxDJmp(IFSMgr_Wakeup)}

VOID NAKED IFSMgr_Yield(){VxDJmp(IFSMgr_Yield)}

VOID NAKED IFSMgr_SchedEvent(pevent pev, DWORD time){VxDJmp(IFSMgr_SchedEvent)}

VOID NAKED IFSMgr_QueueEvent(pevent pev){VxDJmp(IFSMgr_QueueEvent)}

VOID NAKED IFSMgr_KillEvent(pevent pev){VxDJmp(IFSMgr_KillEvent)}

VOID NAKED IFSMgr_FreeIOReq(pioreq pir){VxDJmp(IFSMgr_FreeIOReq)}

VOID NAKED IFSMgr_RunScheduledEvents(){VxDJmp(IFSMgr_RunScheduledEvents)}

UINT NAKED IFSMgr_MetaMatch(string_t pUniPattern, string_t pUniName, int matchSem){VxDJmp(IFSMgr_MetaMatch)}

int NAKED IFSMgr_TransMatch(pioreq pir, srch_entry* pse, string_t pattern, _WIN32_FIND_DATA* pFindBuf){VxDJmp(IFSMgr_TransMatch)}

UINT NAKED UniToBCSPath(PBYTE pBCSPath, PathElement* pUniPath, UINT maxLength, int charSet){VxDJmp(UniToBCSPath)}

UINT NAKED UniToBCS(PBYTE pBCSPath, string_t pUniPath, UINT length, UINT maxLength, UINT charSet){VxDJmp(UniToBCS)}

UINT NAKED BCSToUni(string_t pUniStr, PBYTE pBCSStr, UINT length, int charSet){VxDJmp(BCSToUni)}

UINT NAKED BcsToBcs(PBYTE pDest, PBYTE pSrc, UINT dstCharSet, UINT srcCharSet, UINT MaxLen){VxDJmp(BcsToBcs)}

UINT NAKED BcsToBcsUpper(PBYTE pDest, PBYTE pSrc, UINT dstCharSet, UINT srcCharSet, UINT MaxLen){VxDJmp(BcsToBcsUpper)}

UINT NAKED UniCharToOEM(WORD uniChar){VxDJmp(UniCharToOEM)}

UINT NAKED UniToUpper(string_t pUniUpStr, string_t pUniStr, UINT length){VxDJmp(UniToUpper)}

UINT NAKED CreateBasis(string_t pBasisName, string_t pUniName, UINT length){VxDJmp(CreateBasis)}

int NAKED MatchBasisName(string_t pBasisName, string_t pName){VxDJmp(MatchBasisName)}

int NAKED AppendBasisTail(string_t pBasisName, int tail){VxDJmp(AppendBasisTail)}

int NAKED FcbToShort(string_t p83name, string_t pFCBName, int trailDot){VxDJmp(FcbToShort)}

int NAKED ShortToFcb(string_t pFCBName, string_t p83Name, UINT length){VxDJmp(ShortToFcb)}

int NAKED ShortToLossyFcb(string_t pFCBName, string_t p83Name, UINT length){VxDJmp(ShortToLossyFcb)}

typedef struct _CONVTABLES{DWORDct_length;PDWORDct_UniToWinAnsiTbl;PDWORDct_UniToOemTbl;PDWORDct_WinAnsiToUniTbl;PDWORDct_OemToUniTable;PDWORDct_UniToUpperDeltaTbl;PDWORDct_UniToUpperTbl;} _CONVTABLES, *_PCONVTABLES;

_PCONVTABLES NAKED IFSMgr_GetConversionTablePtrs(){VxDJmp(IFSMgr_GetConversionTablePtrs)}

int NAKED IFSMgr_ParsePath(pioreq pir){VxDJmp(IFSMgr_ParsePath)}

int NAKED IFSMgr_FSDParsePath(pioreq pir){VxDJmp(IFSMgr_FSDParsePath)}

int NAKED IFSMgr_ParseOneElement(USHORT* pe_unichars){VxDJmp(IFSMgr_ParseOneElement)}

int NAKED IFSMgr_CheckAccessConflict(int fSortCompatibleDisable, fmode_t pfmode, int (*pfn)(fmode_t*, const void*), const void* FSDCookie){VxDJmp(IFSMgr_CheckAccessConflict)}

int NAKED IFSMgr_LockFile(void** ppFSDLockListHead, DWORD LockOffset, DWORD LockLength, DWORD LockOwner, PVOID pOpenFileInstance, DWORD fLockSemantics){VxDJmp(IFSMgr_LockFile)}

int NAKED IFSMgr_UnlockFile(void** ppFSDLockListHead, DWORD LockOffset, DWORD LockLength, DWORD LockOwner, PVOID pOpenFileInstance, DWORD fLockSemantics){VxDJmp(IFSMgr_UnlockFile)}

VOID NAKED IFSMgr_RemoveLocks(void** ppFSDLockListHead, DWORD LockOwner, PVOID pOpenFileInstance){VxDJmp(IFSMgr_RemoveLocks)}

int NAKED IFSMgr_CheckLocks(PVOID pFSDLockListHead, DWORD Offset, DWORD Length, DWORD Process, PVOID pOpenFileInstance, DWORD fOperation){VxDJmp(IFSMgr_CheckLocks)}

int NAKED IFSMgr_CountLocks(PVOID pFSDLockListHead, PVOID pOpenFileInstance){VxDJmp(IFSMgr_CountLocks)}

VOID NAKED IFSMgr_UnassignLockList(PVOID pFSDLockListHead){VxDJmp(IFSMgr_UnassignLockList)}

VOID NAKED IFSMgr_ReassignLockFileInst(PVOID pFSDLockListhead, PVOID pOldOpenFileInstance, PVOID pNewOpenFileInstance){VxDJmp(IFSMgr_ReassignLockFileInst)}

VOID NAKED NotifyVolumeArrival(UINT drive){VxDJmp(NotifyVolumeArrival)}

int NAKED QueryVolumeRemoval(UINT drive, int fDialog){VxDJmp(QueryVolumeRemoval)}

VOID NAKED NotifyVolumeRemoval(UINT drive){VxDJmp(NotifyVolumeRemoval)}

int NAKED IFSMgr_PNPEvent(UINT Message, UINT Resource, UINT Flags){VxDJmp(IFSMgr_PNPEvent)}

int NAKED _VolFlush(UINT Volume, int Flags){VxDJmp(_VolFlush)}

VOID NAKED IFSMgr_CompleteAsync(pioreq pir){VxDJmp(IFSMgr_CompleteAsync)}

int VXDINLINE R0_OpenCreateFile(BOOL incontext, WORD modeflags, WORD attrib, BYTE action, BYTE flags, char* pathname, PDWORD phandle, PDWORD paction){DWORD opcode = incontext ? R0_OPENCREAT_IN_CONTEXT : R0_OPENCREATFILE;WORD result;_asm{moveax, opcodemov bx, modeflagsmov cx, attribmov dl, actionmov dh, flagsmov esi, pathname}VxDCall(IFSMgr_Ring0_FileIO)_asm{jcerrormov ebx, phandlemov [ebx], eaxmov ebx, pactionmovzx ecx, clmov [ebx], ecxxor eax, eaxerror:movresult, ax}return result;}

int VXDINLINE R0_ReadFile(BOOL incontext, DWORD handle, DWORD count, DWORD pos, PBYTE buffer, PDWORD nread){DWORD opcode = incontext ? R0_READFILE_IN_CONTEXT : R0_READFILE;WORD result;_asm{moveax, opcodemovebx, handlemov ecx, countmov edx, posmov esi, buffer}VxDCall(IFSMgr_Ring0_FileIO)_asm{jcerrormov ebx, nreadmov [ebx], ecxxor eax, eaxerror:movresult, ax}return result;}

int VXDINLINE R0_WriteFile(BOOL incontext, DWORD handle, DWORD count, DWORD pos, const BYTE* buffer, PDWORD nwritten){DWORD opcode = incontext ? R0_WRITEFILE_IN_CONTEXT : R0_WRITEFILE;WORD result;_asm{moveax, opcodemovebx, handlemov ecx, countmov edx, posmov esi, buffer}VxDCall(IFSMgr_Ring0_FileIO)_asm{jcerrormov ebx, nwrittenmov [ebx], ecxxor eax, eaxerror:mov result, ax}return result;}

int VXDINLINE R0_CloseFile(DWORD handle){_asm{moveax, R0_CLOSEFILEmov ebx, handle}VxDCall(IFSMgr_Ring0_FileIO)_asm jc error_asm xor eax, eax_asm error:_asm movzx eax, ax}

int VXDINLINE R0_GetFileSize(DWORD handle, PDWORD psize){_asm{moveax, R0_GETFILESIZEmov ebx, handle}VxDCall(IFSMgr_Ring0_FileIO)_asm{jcerrormov ebx, psizemov [ebx], eaxxoreax, eaxerror:movzx eax, ax}}

int VXDINLINE R0_FindFirstFile(WORD attrib, const char* pathname, _WIN32_FIND_DATA* fd, PDWORD phandle){_asm{moveax, R0_FINDFIRSTFILEmovesi, pathnamemov edx, fdmovcx, attrib}VxDCall(IFSMgr_Ring0_FileIO)_asm{jcerrormov ebx, phandlemov [ebx], eaxxor eax, eaxerror:movzx eax, ax}}

int VXDINLINE R0_FindNextFile(DWORD handle, _WIN32_FIND_DATA* fd){_asm{moveax, R0_FINDNEXTFILEmov ebx, handlemov edx, fd}VxDCall(IFSMgr_Ring0_FileIO)_asm jc error_asm xor eax, eax_asm error:_asm movzx eax, ax}

int VXDINLINE R0_FindClose(DWORD handle){_asm{moveax, R0_FINDCLOSEFILEmov ebx, handle}VxDCall(IFSMgr_Ring0_FileIO)_asm jc error_asm xor eax, eax_asm error:_asm movzx eax, ax}

int VXDINLINE R0_GetFileAttributes(const char* pathname, PWORD pattrib){_asm{moveax, R0_FILEATTRIBUTES or GET_ATTRIBUTESmov esi, pathname}VxDCall(IFSMgr_Ring0_FileIO)_asm{jcerrormov ebx, pattribmov word ptr [ebx], cxxor eax, eaxerror:movzx eax, ax}}

int VXDINLINE R0_SetFileAttributes(const char* pathname, WORD attrib){_asm{moveax, R0_FILEATTRIBUTES or SET_ATTRIBUTESmov cx, attribmov esi, pathname}VxDCall(IFSMgr_Ring0_FileIO)_asm jc error_asm xor eax, eax_asm error:_asm movzx eax, ax}

int VXDINLINE R0_RenameFile(const char* oldname, const char* newname){_asm{moveax, R0_RENAMEFILEmov esi, oldnamemov edx, newname}VxDCall(IFSMgr_Ring0_FileIO)_asm jc error_asm xor eax, eax_asm error:_asm movzx eax, ax}

int VXDINLINE R0_DeleteFile(const char* pathname, WORD attrib){_asm{mov eax, R0_DELETEFILEmov cx, attribmov esi, pathname}VxDCall(IFSMgr_Ring0_FileIO)_asm jc error_asm xor eax, eax_asm error:_asm movzx eax, ax}

int VXDINLINE R0_LockFile(DWORD handle, DWORD pid, DWORD dwOffset, DWORD dwLength){_asm{mov eax, R0_LOCKFILE or LOCK_REGIONmov ebx, handlemov ecx, pidmov edx, dwOffsetmov esi, dwLength}VxDCall(IFSMgr_Ring0_FileIO)_asm jc error_asm xor eax, eax_asm error:_asm movzx eax, ax}

int VXDINLINE R0_UnlockFile(DWORD handle, DWORD pid, DWORD dwOffset, DWORD dwLength){_asm{mov eax, R0_LOCKFILE or UNLOCK_REGIONmov ebx, handlemov ecx, pidmov edx, dwOffsetmov esi, dwLength}VxDCall(IFSMgr_Ring0_FileIO)_asm jc error_asm xor eax, eax_asm error:_asm movzx eax, ax}

int VXDINLINE R0_GetDiskFreeSpace(BYTE drive, PWORD pspc, PWORD pavl, PWORD psecsize, PWORD ptot){_asm{moveax, R0_GETDISKFREESPACEmov dl, drive}VxDCall(IFSMgr_Ring0_FileIO)_asm{jcerrormov esi, pspcmov word ptr [esi], ax; sectors per clustermov esi, pavlmov word ptr [esi], bx; available clustersmov esi, psecsizemov word ptr [esi], cx; bytes per sectormov esi, ptotmov word ptr [esi], dx; total clusters on diskxor eax, eaxerror:movzx eax, ax}}

int VXDINLINE R0_ReadAbsoluteDisk(BYTE drive, UINT nsectors, DWORD sector, PBYTE buffer){_asm{moval, drivemov ah, R0_READABSOLUTEDISK shr 8mov ecx, nsectorsmov edx, sectormov esi, buffer}VxDCall(IFSMgr_Ring0_FileIO)_asm jc error_asm xor eax, eax_asm error:_asm movzx eax, ax}

int VXDINLINE R0_WriteAbsoluteDisk(BYTE drive, UINT nsectors, DWORD sector, const BYTE* buffer){_asm{moval, drivemov ah, R0_WRITEABSOLUTEDISK shr 8mov ecx, nsectorsmov edx, sectormov esi, buffer}VxDCall(IFSMgr_Ring0_FileIO)_asm jc error_asm xor eax, eax_asm error:_asm movzx eax, ax}

int VXDINLINE IFSMgr_Ring0GetDriveInfo(UINT drive){_asm mov edx, driveVxDCall(IFSMgr_Ring0_FileIO)_asm{jncnoerrormov eax, -1noerror:}}

ppIFSFileHookFunc NAKED IFSMgr_InstallFileSystemApiHook(pIFSFileHookFunc fcn){VxDJmp(IFSMgr_InstallFileSystemApiHook)}

int NAKED IFSMgr_RemoveFileSystemApiHook(pIFSFileHookFunc fcn){VxDJmp(IFSMgr_RemoveFileSystemApiHook)}

int NAKED IFSMgr_CDROM_Attach(DWORD drive, struct _VRP** pvrp, int fDoMount){VxDJmp(IFSMgr_CDROM_Attach)}

int NAKED IFSMgr_CDROM_Detach(DWORD Drive, struct _VRP* vrp){VxDJmp(IFSMgr_CDROM_Detach)}

int NAKED IFSMgr_FSDUnmountCFSD(DWORD rh){VxDJmp(IFSMgr_FSDUnmountCFSD)}

int NAKED IFSMgr_MountChildVolume(struct _VRP* vrp, DWORD drive){VxDJmp(IFSMgr_MountChildVolume)}

int NAKED IFSMgr_UnmountChildVolume(struct _VRP* vrp, DWORD drive){VxDJmp(IFSMgr_UnmountChildVolume)}

int NAKED IFSMgr_SwapDrives(struct _VRP* vrp, DWORD drive1, DWORD drive2){VxDJmp(IFSMgr_SwapDrives)}

int NAKED IFSMgr_FSDGetCurrentDrive(pioreq pir){VxDJmp(IFSMgr_FSDGetCurrentDrive)}

int NAKED _GetMappedErr(UINT Function, UINT ExtErr){VxDJmp(_GetMappedErr)}

int NAKED IFSMgr_GetLockState(DWORD drive, PDWORD pLockType, PDWORD pLockFlags, PDWORD pLockOwner){VxDJmp(IFSMgr_GetLockState)}

BOOL VXDINLINE Query_PhysLock(DWORD unit){_asm mov eax, unitVxDCall(Query_PhysLock)_asm sbb eax, eax; CF set if process doesn't own volume lock, so return is -1 if unowned, 0 if owned}

VOID NAKED IFSMgr_printf(const char* pfstr, ...){VxDJmp(IFSMgr_printf)}

#ifdef DEBUG#define IFSASSERT(x) if (!(x)) IFSMgr_AssertFailed(#x, __FILE__, __LINE__)VOID NAKED IFSMgr_AssertFailed(const char* msg, const char* pfname, DWORD line){VxDJmp(IFSMgr_AssertFailed)}VOID NAKED IFSMgr_LogEntry(const char* name, DWORD info1, DWORD info2, int sdepth, DWORD mask){VxDJmp(IFSMgr_LogEntry)}DWORD NAKED IFSMgr_DebugMenu(PVOID pm){VxDJmp(IFSMgr_DebugMenu)}DWORD NAKED IFSMgr_DebugVars(){VxDJmp(IFSMgr_DebugVars)}int NAKED IFSMgr_GetDebugString(const char* prompt, char* buffer, UINT length){VxDJmp(IFSMgr_GetDebugString)}int NAKED IFSMgr_GetDebugHexNum(const char* prompt, PDWORD phexval){VxDJmp(IFSMgr_GetDebugHexNum)}DWORD NAKED IFSMgr_DbgSetFileHandleLimit(DWORD MaxHandles){VxDJmp(IFSMgr_DbgSetFileHandleLimit)}#else#define IFSASSERT(x)#define IFSMgr_Assert_Failed(a1, a2, a3)#define IFSMgr_LogEntry(a1, a2, a3, a4, a5)#define IFSMgr_DebugMenu(a1) NULL#define IFSMgr_DebugVars() NULL#define IFSMgr_GetDebugString(a1, a2, a3) 0#define IFSMgr_GetDebugHexNum(a1, a2) 0#define IFSMgr_DbgSetFileHandleLimit(a1) a1#endif

//#pragma warning(default:4035)#endif // Not_VxD

#endif // IFSMGR_SERVICES_ONLY

#ifdef __cplusplus}#endif

#endif // IFSMGR_H

Samples/AppendixA/Newstub/NonStubs.cpp

Samples/AppendixA/Newstub/NonStubs.cpp//NonStubs.cpp--Implementationsofselectedkernel-modefunctions

//Copyright(C)1999byWalterOney

//Allrightsreserved

#include"stddcls.h"

#include"driver.h"

#include"NonStubs.h"

VOIDCallbackWrapper(PIO_WORKITEMitem);

///////////////////////////////////////////////////////////////////////////////

PIO_WORKITEMAllocateWorkItem(PDEVICE_OBJECTDeviceObject)

{//AllocateWorkItem

PIO_WORKITEMitem=(PIO_WORKITEM)ExAllocatePool(NonPagedPool,sizeof(IO_WORKITEM));

item->DeviceObject=DeviceObject;

returnitem;

}//AllocateWorkItem

///////////////////////////////////////////////////////////////////////////////

VOIDCallbackWrapper(PIO_WORKITEMitem)

{//CallbackWrapper

(*item->Routine)(item->DeviceObject,item->Context);

ObDereferenceObject(item->DeviceObject);

}//CallbackWrapper

///////////////////////////////////////////////////////////////////////////////

VOIDFreeWorkItem(PIO_WORKITEMitem)

{//FreeWorkItem

ExFreePool(item);

}//FreeWorkItem

///////////////////////////////////////////////////////////////////////////////

VOIDQueueWorkItem(PIO_WORKITEMitem,PIO_WORKITEM_ROUTINERoutine,WORK_QUEUE_TYPEQueueType,PVOIDContext)

{//QueueWorkItem

ExInitializeWorkItem(item,(PWORKER_THREAD_ROUTINE)CallbackWrapper,item);

item->Context=Context;

item->Routine=Routine;

ObReferenceObject(item->DeviceObject);

ExQueueWorkItem(item,QueueType);

}//QueueWorkItem

///////////////////////////////////////////////////////////////////////////////

NTSTATUSAcquireRemoveLock(PIO_REMOVE_LOCKp,PVOIDtag,PCSTRfile,ULONGline,ULONGsize)

{//AcquireRemoveLock

LONGcount=InterlockedIncrement(&p->Common.IoCount);

ASSERT(count>0);

if(p->Common.Removed)

{//deviceisbeingremoved

if(InterlockedDecrement(&p->Common.IoCount)==0)

KeSetEvent(&p->Common.RemoveEvent,IO_NO_INCREMENT,FALSE);

returnSTATUS_DELETE_PENDING;

}//deviceisbeingremoved

#ifdefDEBUG

if(sizeDbg.HighWatermark==0||countDbg.HighWatermark);

PIO_REMOVE_LOCK_TRACKING_BLOCKt=(PIO_REMOVE_LOCK_TRACKING_BLOCK)ExAllocatePoolWithTag(NonPagedPool,

sizeof(IO_REMOVE_LOCK_TRACKING_BLOCK),p->Dbg.AllocateTag);

if(t)

{//initializetrackingblock

RtlZeroMemory(t,sizeof(IO_REMOVE_LOCK_TRACKING_BLOCK));

t->tag=tag;

t->file=file;

t->line=line;

t->locktime=Get_System_Time();

t->next=p->Dbg.Blocks;

p->Dbg.Blocks=t;

}//initializetrackingblock

else

InterlockedIncrement(&p->Dbg.LowMemoryCount);

#endif//DEBUG

returnSTATUS_SUCCESS;

}//AcquireRemoveLock

///////////////////////////////////////////////////////////////////////////////

VOIDReleaseRemoveLock(PIO_REMOVE_LOCKp,PVOIDtag,ULONGsize)

{//ReleaseRemoveLock

#ifdefDEBUG

if(size>=sizeof(IO_REMOVE_LOCK))

{//checkdebuginfo

LONGcurtime=Get_System_Time();

BOOLEANfound=FALSE;

PIO_REMOVE_LOCK_TRACKING_BLOCKt=p->Dbg.Blocks;

PIO_REMOVE_LOCK_TRACKING_BLOCKprev=NULL;

while(t)

{//foreachtrackingblock

if((LONG)p->Dbg.MaxLockedTicks&&(curtime-t->locktime)>=(LONG)p->Dbg.MaxLockedTicks)

{//lockedtoolong

KdPrint(("RemoveLockacquiredfromfile%s,line%d(tag%X)hasbeenlockedtoolong\n",t->file,t->line,t->tag));

ASSERT(FALSE);

}//lockedtoolong


if(!found&&t->tag==tag)

{//foundthetrackingblock

found=TRUE;

PIO_REMOVE_LOCK_TRACKING_BLOCKnext=t->next;

if(prev)

prev->next=next;

else

p->Dbg.Blocks=next;

ExFreePool(t);

t=next;

}//foundthetrackingblock

else

prev=t,t=t->next;

}//foreachtrackingblock

if(!found&&InterlockedDecrement(&p->Dbg.LowMemoryCount)Common.IoCount);

ASSERT(count>=0);

if(count==0)

{//devicecanberemoved

ASSERT(p->Common.Removed);

KeSetEvent(&p->Common.RemoveEvent,IO_NO_INCREMENT,FALSE);

}//devicecanberemoved

}//ReleaseRemoveLock

///////////////////////////////////////////////////////////////////////////////

VOIDReleaseRemoveLockAndWait(PIO_REMOVE_LOCKp,PVOIDtag,ULONGsize)

{//ReleaseRemoveLockAndWait

p->Common.Removed=TRUE;

InterlockedDecrement(&p->Common.IoCount);//accountforinitializationto1

ReleaseRemoveLock(p,tag,size);

KeWaitForSingleObject(&p->Common.RemoveEvent,Executive,KernelMode,FALSE,NULL);

#ifdefDEBUG

if(size>=sizeof(IO_REMOVE_LOCK))

ASSERT(p->Dbg.Blocks==NULL);

#endif//DEBUG

}//ReleaseRemoveLockAndWait

///////////////////////////////////////////////////////////////////////////////

VOIDInitializeRemoveLock(PIO_REMOVE_LOCKp,ULONGtag,ULONGmaxminutes,ULONGhwm,ULONGsize)

{//InitializeRemoveLock

RtlZeroMemory(p,size);

p->Common.IoCount=1;

KeInitializeEvent(&p->Common.RemoveEvent,NotificationEvent,FALSE);

#ifdefDEBUG

if(sizeDbg.Signature='COLR';//RLOC

p->Dbg.HighWatermark=hwm;

p->Dbg.MaxLockedTicks=(LONGLONG)(maxminutes*60*1000);

p->Dbg.AllocateTag=tag;


#endif//DEBUG

}//InitializeRemoveLock

///////////////////////////////////////////////////////////////////////////////

VOIDReuseIrp(PIRPIrp,NTSTATUSstatus)

{//ReuseIrp

UCHARflags=Irp->AllocationFlags;

CCHARnstack=Irp->StackCount;

IoInitializeIrp(Irp,IoSizeOfIrp(nstack),nstack);

Irp->AllocationFlags=flags;

Irp->IoStatus.Status=status;

}//ReuseIrp

Samples/AppendixA/Newstub/NonStubs.h// NonStubs.h -- declarations for NonStubs.cpp// Copyright (C) 1999 by Walter Oney// All rights reserved

#ifndef NONSTUBS_H#define NONSTUBS_H

typedef VOID (NTAPI *PIO_WORKITEM_ROUTINE)(PDEVICE_OBJECT DeviceObject, PVOID Context);

struct _IO_WORKITEM : public _WORK_QUEUE_ITEM {PDEVICE_OBJECT DeviceObject;PIO_WORKITEM_ROUTINE Routine;PVOID Context;};typedef struct _IO_WORKITEM IO_WORKITEM, *PIO_WORKITEM;

PIO_WORKITEM AllocateWorkItem(PDEVICE_OBJECT DeviceObject);VOID FreeWorkItem(PIO_WORKITEM item);VOID QueueWorkItem(PIO_WORKITEM pIOWorkItem, PIO_WORKITEM_ROUTINE Routine, WORK_QUEUE_TYPE QueueType, PVOID Context);

typedef struct _IO_REMOVE_LOCK_TRACKING_BLOCK {struct _IO_REMOVE_LOCK_TRACKING_BLOCK* next;// chain to next lock blockPVOID tag;// tag used at lock timeLONG locktime;// system time when lock occurredPCSTR file;// source filenameULONG line;// source line number} IO_REMOVE_LOCK_TRACKING_BLOCK, *PIO_REMOVE_LOCK_TRACKING_BLOCK;

LONG __stdcall Get_System_Time();

NTSTATUS AcquireRemoveLock(PIO_REMOVE_LOCK p, PVOID tag, PCSTR file, ULONG line, ULONG size);VOID ReleaseRemoveLock(PIO_REMOVE_LOCK p, PVOID tag, ULONG size);VOID ReleaseRemoveLockAndWait(PIO_REMOVE_LOCK p, PVOID tag, ULONG size);VOID InitializeRemoveLock(PIO_REMOVE_LOCK p, ULONG tag, ULONG maxminutes, ULONG hwm, ULONG size);

VOID ReuseIrp(PIRP Irp, NTSTATUS status);

#endif

Samples/AppendixA/Newstub/objchk_wxp_x86/i386/wdmstub.NMS

Samples/AppendixA/Newstub/objchk_wxp_x86/i386/WDMSTUB.sys

Samples/AppendixA/Newstub/stddcls.cpp

Samples/AppendixA/Newstub/stddcls.cpp//stddcls.cpp--PrecompiledheaderstubforWDMdriver

//Copyright(C)1999,2000byWalterOney

//Allrightsreserved

#include"stddcls.h"

Samples/AppendixA/Newstub/stddcls.h// stddcls.h -- Precompiled headers for WDM drivers// Copyright (C) 1999, 2000 by Walter Oney// All rights reserved

#ifdef __cplusplusextern "C" {#endif

#define _BLDR_#define _NTSYSTEM_// to suppress import declarations#include

#undef ExFreePool// suppress macro to ExFreePoolWithTag

#define WANTVXDWRAPS#define _H2INC#include #undef _H2INC#undef NULL#undef PASCAL#undef FAR#define NULL (0)#define FAR#include #include #include #include

#pragma warning(disable:4229)#include #pragma warning(default:4229)#include #include

#include #include

#include #include #include #include #include #include #include #include

#ifdef __cplusplus}#endif

#define PAGEDCODE code_seg("PAGE")#define LOCKEDCODE code_seg()#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGEDATA")#define LOCKEDDATA data_seg()#define INITDATA data_seg("INITDATA")

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))

// Override DDK definition of ASSERT so that debugger halts in the// affected code and halts even in the unchecked OS

#if DBG && defined(_X86_)#undef ASSERT#define ASSERT(e) if(!(e)){DbgPrint("Assertion failure in "\__FILE__ ", line %d: " #e "\n", __LINE__);\_asm int 3\ }#endif

Samples/AppendixA/Newstub/version.h#define VERMAJOR 5#define VERMINOR 0#define BUILD 4

#define PRODVER "5.00.004\0"

Samples/AppendixA/Newstub/wdmstub.cpp

Samples/AppendixA/Newstub/wdmstub.cpp//WDMSTUB.CPP--StubsformissingWin2KWDMservicefunctions

//Copyright(C)1998byWalterOney

//Allrightsreserved

#include"stddcls.h"

#include"driver.h"

#include"NonStubs.h"

#defineIFSMGR_SERVICES_ONLY

#include"ifsmgr.h"

CCHARcKeNumberProcessors=1;

BOOLEANbKdDebuggerEnabled=0;

BOOLEANPrecisionErrata=FALSE;

DWORDfeatures=0;

//PentiumfeatureflagsreturnedinEDXfromCPUIDwithEAX==1

#defineFEATURE_FPU0x00000001//FPUonchip

#defineFEATURE_RDTSC0x00000010//RDTSCinstructionsupported

#defineFEATURE_MACHINE_CHECK0x00000080//machinecheckexceptioncanoccur

#defineFEATURE_CMPXCHG8B0x00000100//CMPXCHG8Binstructionsupported

#defineFEATURE_MMX0x00800000//MMXinstructionssupported

#defineFEATURE_XMMI0x02000000

#defineBCS_WANSI0//ifs.hgeneratestoomanycompileerrorsifweincludeit

extern"C"NTSYSAPINTSTATUSNTAPIObReferenceObjectByName(PUNICODE_STRINGname,ULONGunknown1,

ULONGunknown2,ULONGunknown3,POBJECT_TYPEtype,

KPROCESSOR_MODEmode,ULONGunknown4,PVOID*object);

extern"C"POBJECT_TYPE*IoDriverObjectType;

///////////////////////////////////////////////////////////////////////////////

#pragmaLOCKEDCODE

//NamesoffunctionsstubbedbythisVxD.Thisisn'tthearrayweactuallypass

//toPELDR--it'sthearrayweusewhenweconstructalistoffunctions

//thataren'talreadyimplementedbyNTKERN.Thenamesmustbeinresidentstorage

//becausewedon'tcopythemwhenwebuildtheexporttable.

staticchar*names[]={

"PoRegisterSystemState",

"PoSetSystemState",

"PoUnregisterSystemState",

"IoReportTargetDeviceChangeAsynchronous",

"ExSystemTimeToLocalTime",

"ExLocalTimeToSystemTime",

"IoCreateNotificationEvent",

"IoCreateSynchronizationEvent",

"IoAllocateWorkItem",

"IoFreeWorkItem",

"IoQueueWorkItem",

"PsGetVersion",

"RtlUshortByteSwap",

"RtlUlongByteSwap",

"RtlUlonglongByteSwap",

"RtlInt64ToUnicodeString",

"KeSetTargetProcessorDpc",

"KeNumberProcessors",

"KdDebuggerEnabled",

"IoReuseIrp",

"IoRaiseInformationalHardError",

"HalTranslateBusAddress",

"ExIsProcessorFeaturePresent",

"MmGetSystemRoutineAddress",

"ZwQueryInformationFile",

"ZwSetInformationFile",

"ZwQueryDefaultLocale",

"ExFreePoolWithTag",

"ZwLoadDriver",

"ZwUnloadDriver",

"SeSinglePrivilegeCheck",

"IoSetCompletionRoutineEx",

};

//AsofSP-9,we'reusingC11withtheXpoptions.Stringconstantsthereforeend

//upinthereferencingcodesegment,butweneedtohave*this*constantpersist:

staticchar*ntoskrnl="ntoskrnl.exe";

staticchar*remlocknames[]={

"IoAcquireRemoveLockEx",

"IoReleaseRemoveLockEx",

"IoReleaseRemoveLockAndWaitEx",

"IoInitializeRemoveLockEx",

};

//TheWin98implementationofKeEnterCriticalRegionincorrectlyraisestheIRQLto

//APC_LEVEL,sowe'llstubitnomatterwhat

staticchar*critnames[]={

"KeEnterCriticalRegion",

"KeLeaveCriticalRegion",

};

//MacrosaddedinXpDDK:

#undefRtlUshortByteSwap

#undefRtlUlongByteSwap

#undefRtlUlonglongByteSwap

USHORT

FASTCALL

RtlUshortByteSwap(

INUSHORTSource

);

ULONG

FASTCALL

RtlUlongByteSwap(

INULONGSource

);

ULONGLONG

FASTCALL

RtlUlonglongByteSwap(

INULONGLONGSource

);

NTSTATUSZwLoadDriver(PUNICODE_STRING);

NTSTATUSZwUnloadDriver(PUNICODE_STRING);

#pragmawarning(disable:4273)//inconsistentdlllinkage

//Addressesofstubfunctions(mustlineupwithnamesarray)

NTSTATUSZwQueryDefaultLocale(BOOLEANthread,LCID*plocale);

staticPFNaddresses[]={

(PFN)PoRegisterSystemState,

(PFN)PoSetSystemState,

(PFN)PoUnregisterSystemState,

(PFN)IoReportTargetDeviceChangeAsynchronous,

(PFN)ExSystemTimeToLocalTime,

(PFN)ExLocalTimeToSystemTime,

(PFN)IoCreateNotificationEvent,

(PFN)IoCreateSynchronizationEvent,

(PFN)IoAllocateWorkItem,

(PFN)IoFreeWorkItem,

(PFN)IoQueueWorkItem,

(PFN)PsGetVersion,

(PFN)RtlUshortByteSwap,

(PFN)RtlUlongByteSwap,

(PFN)RtlUlonglongByteSwap,

(PFN)RtlInt64ToUnicodeString,

(PFN)KeSetTargetProcessorDpc,

(PFN)&cKeNumberProcessors,

(PFN)&bKdDebuggerEnabled,

(PFN)IoReuseIrp,

(PFN)IoRaiseInformationalHardError,

(PFN)HalTranslateBusAddress,

(PFN)ExIsProcessorFeaturePresent,

(PFN)MmGetSystemRoutineAddress,

(PFN)ZwQueryInformationFile,

(PFN)ZwSetInformationFile,

(PFN)ZwQueryDefaultLocale,

(PFN)ExFreePoolWithTag,

(PFN)ZwLoadDriver,

(PFN)ZwUnloadDriver,

(PFN)SeSinglePrivilegeCheck,

(PFN)IoSetCompletionRoutineEx,

};

staticPFNremlockaddresses[]={

(PFN)IoAcquireRemoveLockEx,

(PFN)IoReleaseRemoveLockEx,

(PFN)IoReleaseRemoveLockAndWaitEx,

(PFN)IoInitializeRemoveLockEx,

};

staticPFNcritaddresses[]={

(PFN)KeEnterCriticalRegion,

(PFN)KeLeaveCriticalRegion,

};

__int64GetZoneBias();

DWORDbuildnum;

HPEEXPORTTABLEhExportTable=0;

char**stubnames;//namesoffunctionswestubbed

PFN*stubaddresses;//addressesofthestubfunctions

WORD*ordinals;//ordinaltabletocorrelatetheothertwotables

LCIDlocale;//defaultlocale

LCIDGetSystemLocale();

DWORDatox(char*s);

NTSTATUSCompletionRoutineWrapper(PDEVICE_OBJECTfdo,PIRPIrp,PCOMPLETION_CONTEXTctx);

///////////////////////////////////////////////////////////////////////////////

#pragmawarning(disable:4035)

UINT__declspec(naked)__cdeclUniToBCS(PBYTEpBCSPath,WCHAR*pUniPath,UINTlength,UINTmaxLength,UINTcharSet)

{

VxDJmp(UniToBCS)

}

#pragmawarning(default:4035)

///////////////////////////////////////////////////////////////////////////////

#pragmaINITCODE

#pragmawarning(disable:4035)

BOOLEANTest_Debug_Installed()

{

VMMCall(Test_Debug_Installed)

_asmsetnzal

}

#pragmawarning(default:4035)

extern"C"ULONG_fltused=0;

//FlagsinCR0:

#defineCR0_PG0x80000000//paging

#defineCR0_ET0x00000010//extensiontype(80387)

#defineCR0_TS0x00000008//taskswitched

#defineCR0_EM0x00000004//emulatemathcoprocessor

#defineCR0_MP0x00000002//mathpresent

#defineCR0_PE0x00000001//protectionenable

#defineCR0_CD0x40000000//cachedisable

#defineCR0_NW0x20000000//notwrite-through

#defineCR0_AM0x00040000//alignmentmask

#defineCR0_WP0x00010000//writeprotect

#defineCR0_NE0x00000020//numericerror

BOOLCheckPrecisionErrata()

{//CheckPrecisionErrata

staticdoubleDividend=4195835.0;

staticdoubleDivisor=3145727.0;

BOOLresult=FALSE;

_asm

{

pushfd;saveflags

cli

moveax,cr0;makesureflagsarethewayweneedthem

movecx,eax

andeax,not(CR0_TSorCR0_MPorCR0_EM)

movcr0,eax

fninit;initializecoprocessor

fldDividend;performdivisiontoshowupprecisionerrata

fdivDivisor

fmulDivisor

fco