www.pudn.com > Microsoft Windows驱动程序模型设计 源代码.zip > DriverEntry.cpp


// Main program for wmi42 driver 
// Copyright (C) 1999 by Walter Oney 
// All rights reserved 
 
#include "stddcls.h" 
#include "driver.h" 
 
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo); 
VOID DriverUnload(IN PDRIVER_OBJECT fdo); 
 
BOOLEAN win98 = FALSE; 
 
UNICODE_STRING servkey; 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma INITCODE 
 
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, 
	IN PUNICODE_STRING RegistryPath) 
	{							// DriverEntry 
	KdPrint((DRIVERNAME " - Entering DriverEntry: DriverObject %8.8lX\n", DriverObject)); 
 
	// Insist that OS support at least the WDM level of the DDK we use 
 
	if (!IoIsWdmVersionAvailable(1, 0)) 
		{ 
		KdPrint((DRIVERNAME " - Expected version of WDM (%d.%2.2d) not available\n", 1, 0)); 
		return STATUS_UNSUCCESSFUL; 
		} 
 
	// See if we're running under Win98 or NT: 
 
	win98 = IsWin98(); 
 
#if DBG 
	if (win98) 
		KdPrint((DRIVERNAME " - Running under Windows 98\n")); 
	else 
		KdPrint((DRIVERNAME " - Running under NT\n")); 
#endif 
 
	// Save the name of the service key 
 
	servkey.Buffer = (PWSTR) ExAllocatePool(PagedPool, RegistryPath->Length + sizeof(WCHAR)); 
	if (!servkey.Buffer) 
		{ 
		KdPrint((DRIVERNAME " - Unable to allocate %d bytes for copy of service key name\n", RegistryPath->Length + sizeof(WCHAR))); 
		return STATUS_INSUFFICIENT_RESOURCES; 
		} 
	servkey.MaximumLength = RegistryPath->Length + sizeof(WCHAR); 
	RtlCopyUnicodeString(&servkey, RegistryPath); 
 
	// Initialize function pointers 
 
	DriverObject->DriverUnload = DriverUnload; 
	DriverObject->DriverExtension->AddDevice = AddDevice; 
 
	DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower; 
	DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DispatchWmi; 
	DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp; 
	 
	return STATUS_SUCCESS; 
	}							// DriverEntry 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) 
	{							// DriverUnload 
	PAGED_CODE(); 
	KdPrint((DRIVERNAME " - Entering DriverUnload: DriverObject %8.8lX\n", DriverObject)); 
	RtlFreeUnicodeString(&servkey); 
	}							// DriverUnload 
 
/////////////////////////////////////////////////////////////////////////////// 
 
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo) 
	{							// AddDevice 
	PAGED_CODE(); 
	KdPrint((DRIVERNAME " - Entering AddDevice: DriverObject %8.8lX, pdo %8.8lX\n", DriverObject, pdo)); 
 
	NTSTATUS status; 
 
	// Create a functional device object to represent the hardware we're managing. 
 
	PDEVICE_OBJECT fdo; 
	 
	ULONG dxsize = (sizeof(DEVICE_EXTENSION) + 7) & ~7; 
	ULONG xsize = dxsize + GetSizeofGenericExtension(); 
	 
	UNICODE_STRING devname; 
	RtlInitUnicodeString(&devname, L"\\DosDevices\\WMI42"); 
 
	status = IoCreateDevice(DriverObject, xsize, &devname, 
		FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &fdo); 
	if (!NT_SUCCESS(status)) 
		{						// can't create device object 
		KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status)); 
		return status; 
		}						// can't create device object 
	 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
 
	// From this point forward, any error will have side effects that need to 
	// be cleaned up. Using a try-finally block allows us to modify the program 
	// easily without losing track of the side effects. 
 
	__try 
		{						// finish initialization 
		pdx->DeviceObject = fdo; 
		pdx->Pdo = pdo; 
 
		// Make a copy of the device name 
 
		pdx->devname.Buffer = (PWCHAR) ExAllocatePool(NonPagedPool, devname.MaximumLength); 
		if (!pdx->devname.Buffer) 
			{					// can't allocate buffer 
			status = STATUS_INSUFFICIENT_RESOURCES; 
			KdPrint((DRIVERNAME " - Unable to allocate %d bytes for copy of name\n", devname.MaximumLength)); 
			__leave; 
			}					// can't allocate buffer 
		pdx->devname.MaximumLength = devname.MaximumLength; 
		RtlCopyUnicodeString(&pdx->devname, &devname); 
 
		// Link our device object into the stack leading to the PDO 
		 
		pdx->LowerDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo); 
		if (!pdx->LowerDeviceObject) 
			{					// can't attach								  
			KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n")); 
			status = STATUS_DEVICE_REMOVED; 
			__leave; 
			}					// can't attach 
 
		// Initialize to use the GENERIC.SYS library 
 
		pdx->pgx = (PGENERIC_EXTENSION) ((PUCHAR) pdx + dxsize); 
 
		GENERIC_INIT_STRUCT gis = {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 " - InitializeGenericExtension failed - %X\n", status)); 
			__leave; 
			} 
 
		// Clear the "initializing" flag so that we can get IRPs 
 
		fdo->Flags &= ~DO_DEVICE_INITIALIZING; 
 
		// Register our willingness to handle WMI requests 
 
		WmiInitialize(fdo); 
		}						// finish initialization 
	__finally 
		{						// cleanup side effects 
		if (!NT_SUCCESS(status)) 
			{					// need to cleanup 
			if (pdx->devname.Buffer) 
				RtlFreeUnicodeString(&pdx->devname); 
			if (pdx->LowerDeviceObject) 
				IoDetachDevice(pdx->LowerDeviceObject); 
			IoDeleteDevice(fdo); 
			}					// need to cleanup 
		}						// cleanup side effects 
 
	return status; 
	}							// AddDevice 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma LOCKEDCODE 
 
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG_PTR info) 
	{							// CompleteRequest 
	Irp->IoStatus.Status = status; 
	Irp->IoStatus.Information = info; 
	IoCompleteRequest(Irp, IO_NO_INCREMENT); 
	return status; 
	}							// CompleteRequest 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
NTSTATUS DispatchPnp(PDEVICE_OBJECT fdo, PIRP Irp) 
	{							// DispatchPnp 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
	return GenericDispatchPnp(pdx->pgx, Irp); 
	}							// DispatchPnp 
 
NTSTATUS DispatchPower(PDEVICE_OBJECT fdo, PIRP Irp) 
	{							// DispatchPower 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
	return GenericDispatchPower(pdx->pgx, Irp); 
	}							// DispatchPower 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
VOID RemoveDevice(IN PDEVICE_OBJECT fdo) 
	{							// RemoveDevice 
	PAGED_CODE(); 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
	NTSTATUS status; 
 
	WmiTerminate(fdo); 
	RtlFreeUnicodeString(&pdx->devname); 
 
	if (pdx->LowerDeviceObject) 
		IoDetachDevice(pdx->LowerDeviceObject); 
 
	IoDeleteDevice(fdo); 
	}							// RemoveDevice 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#if DBG && defined(_X86_) 
#pragma LOCKEDCODE 
 
extern "C" void __declspec(naked) __cdecl _chkesp() 
	{ 
	_asm je okay 
	ASSERT(!DRIVERNAME " - Stack pointer mismatch!"); 
okay: 
	_asm ret 
	} 
 
#endif // DBG