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

📄 wdmstub.cpp

📁 programming windows driver mode源代码
💻 CPP
字号:
// WDMSTUB.CPP -- Stubs for missing Win2K WDM service functions
// Copyright (C) 1998 by Walter Oney
// All rights reserved

#include "stdvxd.h"
#include "NonStubs.h"

CCHAR cKeNumberProcessors = 1;
BOOLEAN bKdDebuggerEnabled = 0;

///////////////////////////////////////////////////////////////////////////////
// From NTDDK.H (missing from beta-3 DDK?)

NTKERNELAPI PIO_WORKITEM NTAPI IoAllocateWorkItem(PDEVICE_OBJECT DeviceObject);
NTKERNELAPI VOID NTAPI IoFreeWorkItem(PIO_WORKITEM item);
NTKERNELAPI VOID NTAPI IoQueueWorkItem(PIO_WORKITEM pIOWorkItem, PIO_WORKITEM_ROUTINE Routine, WORK_QUEUE_TYPE QueueType, PVOID Context);

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

#pragma VxD_LOCKED_CODE_SEG

// 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",
	"KeEnterCritcalRegion",
	"KeLeaveCriticalRegion",
	"KeSetTargetProcessorDpc",
	"KeNumberProcessors",
	"KdDebuggerEnabled",
	"IoReuseIrp",
	};

static char* remlocknames[] = {
	"IoAcquireRemoveLockEx",
	"IoReleaseRemoveLockEx",
	"IoReleaseRemoveLockAndWaitEx",
	"IoInitializeRemoveLockEx",
	};

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

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) KeEnterCriticalRegion,
	(PFN) KeLeaveCriticalRegion,
	(PFN) KeSetTargetProcessorDpc,
	(PFN) &cKeNumberProcessors,
	(PFN) &bKdDebuggerEnabled,
	(PFN) IoReuseIrp,
	};

static PFN remlockaddresses[] = {
	(PFN) IoAcquireRemoveLockEx,
	(PFN) IoReleaseRemoveLockEx,
	(PFN) IoReleaseRemoveLockAndWaitEx,
	(PFN) IoInitializeRemoveLockEx,
	};

__int64 GetZoneBias();
DWORD buildnum;

HPEEXPORTTABLE hExportTable = 0;

///////////////////////////////////////////////////////////////////////////////
// Declarations of kernel-mode routines must be compiled without a __declspec(dllimport)
// directive, which precludes using WDMVXD.LIB to resolve references within this
// source module. Hence, we define our own implementation of these functions:

#pragma warning(disable:4035)

NTKERNELAPI KIRQL NTAPI KeGetCurrentIrql()
	{
	VMMCall(ObsoleteKeGetCurrentIrql);
	}

#pragma warning(default:4035)

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

#pragma VxD_INIT_CODE_SEG

#pragma warning(disable:4035)

DWORD Convert_Decimal_String(char*& s)
	{
	_asm mov esi, s
	_asm mov edx, [esi]
	VMMCall(Convert_Decimal_String)
	_asm mov [esi], edx
	}

BOOLEAN Test_Debug_Installed()
	{
	VMMCall(Test_Debug_Installed)
	_asm setnz al
	}

#pragma warning(default:4035)

SYSCTL BOOL __cdecl OnDeviceInit(DWORD dwRefData)
	{							// OnDeviceInit

	// 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.

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

	PFN* stubaddresses = (PFN*) _HeapAllocate(sizeof(addresses) + sizeof(remlockaddresses), HEAPZEROINIT);
	if (!stubaddresses)
		{
		_HeapFree(stubnames, 0);
		return FALSE;
		}

	WORD* ordinals = (WORD*) _HeapAllocate((arraysize(names) + arraysize(remlocknames)) * 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.exe", names[i], NULL) == 0)
			{					// stub this function
			Debug_Printf("WDMSTUB - Stubbing %s\n", names[i]);
			stubnames[istub] = names[i];
			ordinals[istub] = istub;
			stubaddresses[istub] = addresses[i];
			++istub;
			}					// stub this function
		else
			Debug_Printf("WDMSTUB - %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.exe", "IoReleaseRemoveLockAndWaitEx", NULL) == 0)
		{						// stub remove lock functions
		Debug_Printf("WDMSTUB - Stubbing all remove lock functions\n");
		for (i = 0; i < arraysize(remlocknames); ++i)
			{					// for each remove lock function
			stubnames[istub] = remlocknames[i];
			ordinals[istub] = istub;
			stubaddresses[istub] = remlockaddresses[i];
			++istub;
			}					// for each remove lock function
		}						// stub remove lock functions
	else
		Debug_Printf("WDMBSTUB - Not stubbing remove lock functions\n");

	// Create an export table to provide for these functions

	if (_PELDR_AddExportTable(&hExportTable, "ntoskrnl.exe", istub,
		istub, 0, (PVOID*) stubnames, ordinals, stubaddresses, NULL) != 0)
		{						// can't define exports
		Debug_Printf("WDMSTUB -- 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;
			Convert_Decimal_String(p);	// major version number
			if (*p == '.')
				++p;
			Convert_Decimal_String(p);	// minor version number
			if (*p == '.')
				++p;
			buildnum = Convert_Decimal_String(p);	// build number
			}					// parse value
		_RegCloseKey(hkey);
		}						// get value

	return TRUE;
	}							// OnDeviceInit

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

#pragma VxD_LOCKED_CODE_SEG

PVOID PoRegisterSystemState(PVOID hstate, ULONG flags)
	{							// PoRegisterSystemState
	ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
	Debug_Printf("PoRegisterSystemState(%8.8lX, %8.8lX)\n", hstate, flags);
	return NULL;
	}							// PoRegisterSystemState

VOID PoSetSystemState(ULONG flags)
	{							// PoSetSystemState
	ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
	Debug_Printf("PoSetSystemState(%8.8lX)\n", flags);
	}							// PoSetSystemState

VOID PoUnregisterSystemState(PVOID hstate)
	{							// PoUnregisterSystemState
	ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
	Debug_Printf("PoUnregisterSystemState(%8.8lX)\n", hstate);
	}							// PoUnregisterSystemState

NTSTATUS IoReportTargetDeviceChangeAsynchronous(PDEVICE_OBJECT pdo, PVOID NfyStruct, PDEVICE_CHANGE_COMPLETE_CALLBACK Callback, PVOID Context)
	{							// IoReportTargetDeviceChangeAsynchronous
	ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
	Debug_Printf("IoReportTargetDeviceChangeAsynchronous(%8.8lX)\n", pdo);
	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);
	Debug_Printf("IoCreateNotificationEvent %ws\n", EventName->Buffer);
	return NULL;
	}							// IoCreateNotificationEvent

PKEVENT IoCreateSynchronizationEvent(PUNICODE_STRING EventName, PHANDLE EventHandle)
	{							// IoCreateSynchronizationEvent
	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
	Debug_Printf("IoCreateSynchronizationEvent %ws\n", EventName->Buffer);
	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
	#undef Get_VMM_Version
	USHORT version;
	ULONG dbgver;
	VMMCall(Get_VMM_Version);
	_asm mov version, ax
	_asm mov dbgver, ecx

	if (MajorVersion)
		*MajorVersion = version >> 8;
	if (MinorVersion)
		*MinorVersion = version & 255;
	if (BuildNumber)
		*BuildNumber = buildnum;
	if (spnum)
		spnum->Length = 0;

	return dbgver != 0;
	}							// PsGetVersion

NTSTATUS IoAcquireRemoveLockEx(PIO_REMOVE_LOCK p, PVOID tag, PCSTR file, ULONG line, ULONG size)
	{							// IoAcquireRemoveLockEx
	ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
	return AcquireRemoveLock(p, tag, file, line, size);
	}							// IoAcquireRemoveLockEx

VOID IoReleaseRemoveLockEx(PIO_REMOVE_LOCK p, PVOID tag, ULONG size)
	{							// IoReleaseRemoveLockEx
	ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
	ReleaseRemoveLock(p, tag, size);
	}							// IoReleaseRemoveLockEx

VOID IoReleaseRemoveLockAndWaitEx(PIO_REMOVE_LOCK p, PVOID tag, ULONG size)
	{							// IoReleaseRemoveLockAndWaitEx
	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
	ReleaseRemoveLockAndWait(p, tag, size);
	}							// IoReleaseRemoveLockAndWaitEx

VOID IoInitializeRemoveLockEx(PIO_REMOVE_LOCK p, ULONG tag, ULONG maxminutes, ULONG hwm, ULONG size)
	{							// IoInitializeRemoveLockEx
	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
	InitializeRemoveLock(p, tag, maxminutes, hwm, size);
	}							// IoInitializeRemoveLockEx

#pragma warning(disable:4035)

USHORT FASTCALL RtlUshortByteSwap(USHORT source)
	{							// RtlUshortByteSwap
	_asm movzx eax, cx
	_asm xchg ah, al
	}							// RtlUshortByteSwap

ULONG FASTCALL RtlUlongByteSwap(ULONG source)
	{							// RtlUlongByteSwap
	_asm mov eax, ecx
	_asm bswap eax
	}							// RtlUlongByteSwap

ULONGLONG FASTCALL RtlUlonglongByteSwap(ULONGLONG source)
	{							// RtlUlonglongByteSwap
	_asm mov eax, ecx
	_asm xchg eax, edx
	_asm bswap eax
	_asm bswap edx
	}							// RtlUlonglongByteSwap

#pragma warning(default:4035)

NTSTATUS RtlInt64ToUnicodeString(ULONGLONG value, ULONG base, PUNICODE_STRING string)
	{							// RtlInt64ToUnicodeString
	return STATUS_NOT_IMPLEMENTED;
	}							// RtlInt64ToUnicodeString

VOID KeEnterCriticalRegion()
	{							// KeEnterCriticalRegion
	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
	KfRaiseIrql(APC_LEVEL);
	}							// KeEnterCriticalRegion

VOID KeLeaveCriticalRegion()
	{							// KeLeaveCriticalRegion
	ASSERT(KeGetCurrentIrql() == APC_LEVEL);
	KfLowerIrql(PASSIVE_LEVEL);
	}							// KeLeaveCriticalRegion

VOID KeSetTargetProcessorDpc(PRKDPC dpc, CCHAR number)
	{							// KeSetTargetProcessorDpc
	}							// KeSetTargetProcessorDpc

VOID KeSetImportanceDpc(PRKDPC dpc, KDPC_IMPORTANCE importance)
	{							// KeSetImportanceDpc
	}							// KeSetImportanceDpc

VOID IoReuseIrp(PIRP Irp, NTSTATUS status)
	{							// IoReuseIrp
	ReuseIrp(Irp, status);
	}							// IoReuseIrp

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

__int64 GetZoneBias()
	{							// GetZoneBias
	DWORD hkey;
	if (_RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_TIMEZONE, &hkey) != 0)
		return 0;

	__int64 bias;
	DWORD actbias;
	DWORD size = sizeof(actbias);

	if (_RegQueryValueEx(hkey, REGSTR_VAL_TZACTBIAS, NULL, NULL, &actbias, &size) == 0)
		{						// compute 100-ns bias
		actbias *= 3600;
		_asm mov eax, actbias
		_asm mov ecx, 10000000
		_asm mul ecx
		_asm mov dword ptr bias, eax
		_asm mov dword ptr bias+4, edx

		}						// compute 100-ns bias
	else
		bias = 0;

	_RegCloseKey(hkey);
	return bias;
	}							// GetZoneBias

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

#pragma warning(disable:4035)

LONG __stdcall Get_System_Time()
	{							// Get_System_Time
	VMMCall(Get_System_Time)
	}							// Get_System_Time

⌨️ 快捷键说明

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