⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wdmstub.cpp

📁 Programming the Microsoft Windows driver model.2nd 随书光盘。内有很多作者送的实用工具和随书源码。WDM编程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// WDMSTUB.CPP -- Stubs for missing Win2K WDM service functions

// Copyright (C) 1998 by Walter Oney

// All rights reserved



#include "stddcls.h"

#include "driver.h"

#include "NonStubs.h"



#define IFSMGR_SERVICES_ONLY

#include "ifsmgr.h"



CCHAR cKeNumberProcessors = 1;

BOOLEAN bKdDebuggerEnabled = 0;



BOOLEAN PrecisionErrata = FALSE;

DWORD features = 0;



// Pentium feature flags returned in EDX from CPUID with EAX == 1



#define FEATURE_FPU				0x00000001		// FPU on chip

#define FEATURE_RDTSC			0x00000010		// RDTSC instruction supported

#define FEATURE_MACHINE_CHECK	0x00000080		// machine check exception can occur

#define FEATURE_CMPXCHG8B		0x00000100		// CMPXCHG8B instruction supported

#define FEATURE_MMX				0x00800000		// MMX instructions supported

#define FEATURE_XMMI			0x02000000



#define BCS_WANSI	0					// ifs.h generates too many compile errors if we include it



extern "C" NTSYSAPI NTSTATUS NTAPI ObReferenceObjectByName(PUNICODE_STRING name, ULONG unknown1,

    ULONG unknown2, ULONG unknown3, POBJECT_TYPE type,

    KPROCESSOR_MODE mode, ULONG unknown4, PVOID *object);

extern "C" POBJECT_TYPE* IoDriverObjectType;



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



#pragma LOCKEDCODE



// Names of functions stubbed by this VxD. This isn't the array we actually pass

// to PELDR -- it's the array we use when we construct a list of functions

// that aren't already implemented by NTKERN. The names must be in resident storage

// because we don't copy them when we build the export table.



static char* 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",

	};



// As of SP-9, we're using C11 with the Xp options. String constants therefore end

// up in the referencing code segment, but we need to have *this* constant persist:



static char* ntoskrnl = "ntoskrnl.exe";



static char* remlocknames[] = {

	"IoAcquireRemoveLockEx",

	"IoReleaseRemoveLockEx",

	"IoReleaseRemoveLockAndWaitEx",

	"IoInitializeRemoveLockEx",

	};



// The Win98 implementation of KeEnterCriticalRegion incorrectly raises the IRQL to

// APC_LEVEL, so we'll stub it no matter what



static char* critnames[] = {

	"KeEnterCriticalRegion",

	"KeLeaveCriticalRegion",

	};



// Macros added in Xp DDK:



#undef RtlUshortByteSwap

#undef RtlUlongByteSwap

#undef RtlUlonglongByteSwap



USHORT

FASTCALL

RtlUshortByteSwap(

    IN USHORT Source

    );



ULONG

FASTCALL

RtlUlongByteSwap(

    IN ULONG Source

    );



ULONGLONG

FASTCALL

RtlUlonglongByteSwap(

    IN ULONGLONG Source

    );



NTSTATUS ZwLoadDriver(PUNICODE_STRING);

NTSTATUS ZwUnloadDriver(PUNICODE_STRING);



#pragma warning(disable:4273)	// inconsistent dll linkage



// Addresses of stub functions (must line up with names array)



NTSTATUS ZwQueryDefaultLocale(BOOLEAN thread, LCID* plocale);



static PFN addresses[] = {

	(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,

	};



static PFN remlockaddresses[] = {

	(PFN) IoAcquireRemoveLockEx,

	(PFN) IoReleaseRemoveLockEx,

	(PFN) IoReleaseRemoveLockAndWaitEx,

	(PFN) IoInitializeRemoveLockEx,

	};



static PFN critaddresses[] = {

	(PFN) KeEnterCriticalRegion,

	(PFN) KeLeaveCriticalRegion,

	};



__int64 GetZoneBias();

DWORD buildnum;



HPEEXPORTTABLE hExportTable = 0;

char** stubnames;				// names of functions we stubbed

PFN* stubaddresses;				// addresses of the stub functions

WORD* ordinals;					// ordinal table to correlate the other two tables



LCID locale;					// default locale

LCID GetSystemLocale();

DWORD atox(char* s);



NTSTATUS CompletionRoutineWrapper(PDEVICE_OBJECT fdo, PIRP Irp, PCOMPLETION_CONTEXT ctx);



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



#pragma warning(disable:4035)



UINT __declspec(naked) __cdecl UniToBCS(PBYTE pBCSPath, WCHAR* pUniPath, UINT length, UINT maxLength, UINT charSet)

	{

	VxDJmp(UniToBCS)

	}



#pragma warning(default:4035)



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



#pragma INITCODE



#pragma warning(disable:4035)



BOOLEAN Test_Debug_Installed()

	{

	VMMCall(Test_Debug_Installed)

	_asm setnz al

	}



#pragma warning(default:4035)



extern "C" ULONG _fltused = 0;



// Flags in CR0:



#define CR0_PG  0x80000000          // paging

#define CR0_ET  0x00000010          // extension type (80387)

#define CR0_TS  0x00000008          // task switched

#define CR0_EM  0x00000004          // emulate math coprocessor

#define CR0_MP  0x00000002          // math present

#define CR0_PE  0x00000001          // protection enable

#define CR0_CD  0x40000000          // cache disable

#define CR0_NW  0x20000000          // not write-through

#define CR0_AM  0x00040000          // alignment mask

#define CR0_WP  0x00010000          // write protect

#define CR0_NE  0x00000020          // numeric error



BOOL CheckPrecisionErrata()

	{							// CheckPrecisionErrata

	static double Dividend = 4195835.0;

	static double Divisor = 3145727.0;

	BOOL result = FALSE;



	_asm

		{

		pushfd					; save flags

		cli

		mov eax, cr0			; make sure flags are the way we need them

		mov	ecx, eax

		and eax, not (CR0_TS or CR0_MP or CR0_EM)

		mov cr0, eax



		fninit					; initialize coprocessor

		fld Dividend			; perform division to show up precision errata

		fdiv Divisor

		fmul Divisor

		fcomp Dividend

		fstsw ax				; capture floating point status

		sahf



		jc  noproblem

		jz  noproblem

		mov result, 1

	

	noproblem:

		mov cr0, ecx			; restore CR0

		popfd					; restore flags (including enable state)

		}



	return result;

	}							// CheckPrecisionErrata



BOOLEAN DefineStubs()

	{							// DefineStubs



	// Construct the name, ordinal, and address tables for functions we're going

	// to stub. In various releases of Windows 98 and Millenium, some or all of

	// these functions will be supported by the operating system, and we don't

	// want to preempt the standard implementation.



	stubnames = (char**) _HeapAllocate(sizeof(names) + sizeof(remlocknames), HEAPZEROINIT); // largest we might ever need

	if (!stubnames)

		return FALSE;



	stubaddresses = (PFN*) _HeapAllocate(sizeof(addresses) + sizeof(remlockaddresses) + sizeof(critaddresses), HEAPZEROINIT);

	if (!stubaddresses)

		{

		_HeapFree(stubnames, 0);

		return FALSE;

		}



	ordinals = (WORD*) _HeapAllocate((arraysize(names) + arraysize(remlocknames) + arraysize(critnames)) * sizeof(WORD), HEAPZEROINIT);

	if (!ordinals)

		{

		_HeapFree(stubaddresses, 0);

		_HeapFree(stubnames, 0);

		return FALSE;

		}



	int i, istub;

	for (i = 0, istub = 0; i < arraysize(names); ++i)

		{						// for each possible stub

		if (_PELDR_GetProcAddress((HPEMODULE) ntoskrnl, names[i], NULL) == 0)

			{					// stub this function

			KdPrint((DRIVERNAME " - Stubbing %s\n", names[i]));

			stubnames[istub] = names[i];

			ordinals[istub] = (WORD) istub;

			stubaddresses[istub] = addresses[i];

			++istub;

			}					// stub this function

		else

			KdPrint((DRIVERNAME " - %s already implemented - not stubbing it\n", names[i]));

		}						// for each possible stub



	// We have a special problem with the remove lock functions, in that Win98SE leaves out

	// just IoRemoveLockAndWaitEx. We'll stub all of them if we find this function missing.



	if (_PELDR_GetProcAddress((HPEMODULE) ntoskrnl, "IoReleaseRemoveLockAndWaitEx", NULL) == 0)

		{						// stub remove lock functions

		KdPrint((DRIVERNAME " - Stubbing all remove lock functions\n"));

		for (i = 0; i < arraysize(remlocknames); ++i)

			{					// for each remove lock function

			stubnames[istub] = remlocknames[i];

			ordinals[istub] = (WORD) istub;

			stubaddresses[istub] = remlockaddresses[i];

			++istub;

			}					// for each remove lock function

		}						// stub remove lock functions

	else

		KdPrint((DRIVERNAME " - Not stubbing remove lock functions\n"));



	// Always replace the critical region functions to avoid having the IRQL raised



	for (i = 0; i < arraysize(critnames); ++i)

		{						// for each critical region function

		KdPrint((DRIVERNAME " - Stubbing %s\n", critnames[i]));

		stubnames[istub] = critnames[i];

		ordinals[istub] = (WORD) istub;

		stubaddresses[istub] = critaddresses[i];

		++istub;

		}						// for each critical region function



	// Create an export table to provide for these functions



	if (_PELDR_AddExportTable(&hExportTable, ntoskrnl, istub,

		istub, 0, (PVOID*) stubnames, ordinals, stubaddresses, NULL) != 0)

		{						// can't define exports

		KdPrint((DRIVERNAME " -- Unable to define export table\n"));

		_HeapFree(ordinals, 0);

		_HeapFree(stubaddresses, 0);

		_HeapFree(stubnames, 0);

		return FALSE;

		}						// can't define exports



	// See if debugger running



	bKdDebuggerEnabled = Test_Debug_Installed();



	// Get build number from HKLM\Software\Microsoft\Windows\CurrentVersion[VersionNumber]



	VMMHKEY hkey;

	if (_RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, &hkey) == 0)

		{						// get value

		char value[64];

		DWORD size = sizeof(value);

		if (_RegQueryValueEx(hkey, "VersionNumber", NULL, NULL, (PBYTE) value, &size) == 0)

			{					// parse value

			char* p = value;

			atoi(p);	// major version number

			if (*p == '.')

				++p;

			atoi(p);	// minor version number

			if (*p == '.')

				++p;

			buildnum = atoi(p);	// build number

			}					// parse value

		_RegCloseKey(hkey);

		}						// get value



	// Determine CPU feature flags



	DWORD machineinfo;

	#undef Get_Machine_Info

	VMMCall(Get_Machine_Info)

	_asm mov machineinfo, ebx	; capture machine type flags

	if (machineinfo & GMIF_CPUID)

		{						// cpuid supported

		_asm mov eax, 1			; EAX = 1 => request for feature flags

		_asm cpuid

		_asm mov features, edx	; save feature flags

		}						// cpuid supported



	if (features & FEATURE_FPU)

		PrecisionErrata = (BOOLEAN) CheckPrecisionErrata();



	// Determine the default locale for ZwQueryDefaultLocale



	locale = GetSystemLocale();



	return TRUE;

	}							// DefineStubs



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



#pragma PAGEDCODE



VOID UndefineStubs()

	{							// UndefineStubs

	_PELDR_RemoveExportTable(hExportTable, NULL);

	_HeapFree(ordinals, 0);

	_HeapFree(stubaddresses, 0);

	_HeapFree(stubnames, 0);

	}							// UndefineStubs



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



#pragma LOCKEDCODE



PVOID PoRegisterSystemState(PVOID hstate, ULONG flags)

	{							// PoRegisterSystemState

	ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);

	return NULL;

	}							// PoRegisterSystemState



VOID PoSetSystemState(ULONG flags)

	{							// PoSetSystemState

	ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

	}							// PoSetSystemState



VOID PoUnregisterSystemState(PVOID hstate)

	{							// PoUnregisterSystemState

	ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);

	}							// PoUnregisterSystemState



NTSTATUS IoReportTargetDeviceChangeAsynchronous(PDEVICE_OBJECT pdo, PVOID NfyStruct, PDEVICE_CHANGE_COMPLETE_CALLBACK Callback, PVOID Context)

	{							// IoReportTargetDeviceChangeAsynchronous

	ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

	return STATUS_NOT_IMPLEMENTED;

	}							// IoReportTargetDeviceChangeAsynchronous



VOID ExSystemTimeToLocalTime(PLARGE_INTEGER systime, PLARGE_INTEGER localtime)

	{							// ExSystemTimeToLocalTime

	localtime->QuadPart = systime->QuadPart - GetZoneBias();

	}							// ExSystemTimeToLocalTime



VOID ExLocalTimeToSystemTime(PLARGE_INTEGER localtime, PLARGE_INTEGER systime)

	{							// ExLocalTimeToSystemTime

	systime->QuadPart = localtime->QuadPart + GetZoneBias();

	}							// ExLocalTimeToSystemTime



PKEVENT IoCreateNotificationEvent(PUNICODE_STRING EventName, PHANDLE EventHandle)

	{							// IoCreateNotificationEvent

	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	return NULL;

	}							// IoCreateNotificationEvent



PKEVENT IoCreateSynchronizationEvent(PUNICODE_STRING EventName, PHANDLE EventHandle)

	{							// IoCreateSynchronizationEvent

	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	return NULL;

	}							// IoCreateSynchronizationEvent



PIO_WORKITEM IoAllocateWorkItem(PDEVICE_OBJECT DeviceObject)

	{							// IoAllocateWorkItem

	return AllocateWorkItem(DeviceObject);

	}							// IoAllocateWorkItem



VOID IoFreeWorkItem(PIO_WORKITEM item)

	{							// IoFreeWorkItem

	FreeWorkItem(item);

	}							// IoFreeWorkItem



VOID IoQueueWorkItem(PIO_WORKITEM item, PIO_WORKITEM_ROUTINE Routine, WORK_QUEUE_TYPE QueueType, PVOID Context)

	{							// IoQueueWorkItem

	QueueWorkItem(item, Routine, QueueType, Context);

	}							// IoQueueWorkItem



BOOLEAN PsGetVersion(PULONG MajorVersion, PULONG MinorVersion, PULONG BuildNumber, PUNICODE_STRING spnum)

	{							// PsGetVersion

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -