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


// Windows Management Instrumentation handlers for wmi42 driver 
// Copyright (C) 1999 by Walter Oney 
// All rights reserved 
 
#include "stddcls.h" 
#include  
#include "driver.h" 
 
#include  
#include  
#include "guids.h" 
 
NTSTATUS QueryRegInfo(PDEVICE_OBJECT fdo, PULONG flags, PUNICODE_STRING instname, PUNICODE_STRING* regpath, PUNICODE_STRING resname, PDEVICE_OBJECT* pdo); 
NTSTATUS QueryDataBlock(PDEVICE_OBJECT fdo, PIRP Irp, ULONG guidindex, ULONG instindex, ULONG instcount, PULONG instlength, ULONG bufsize, PUCHAR buffer); 
NTSTATUS SetDataBlock(PDEVICE_OBJECT fdo, PIRP Irp, ULONG guidindex, ULONG instindex, ULONG bufsize, PUCHAR buffer); 
NTSTATUS SetDataItem(PDEVICE_OBJECT fdo, PIRP Irp, ULONG guidindex, ULONG instindex, ULONG id, ULONG bufsize, PUCHAR buffer); 
NTSTATUS ExecuteMethod(PDEVICE_OBJECT fdo, PIRP Irp, ULONG guidindex, ULONG instindex, ULONG id, ULONG cbInbuf, ULONG cbOutbuf, PUCHAR buffer); 
NTSTATUS FunctionControl(PDEVICE_OBJECT fdo, PIRP Irp, ULONG guidindex, WMIENABLEDISABLECONTROL fcn, BOOLEAN enable); 
 
WMIGUIDREGINFO guidlist[] = { 
	{&GUID_WMI42_SCHEMA, 1, WMIREG_FLAG_INSTANCE_PDO}, 
	}; 
 
WMILIB_CONTEXT libinfo = { 
	arraysize(guidlist),		// GuidCount 
	guidlist,					// GuidList 
	QueryRegInfo, 
	QueryDataBlock, 
	SetDataBlock, 
	SetDataItem, 
	ExecuteMethod, 
	FunctionControl, 
	}; 
									   
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
NTSTATUS DispatchWmi(IN PDEVICE_OBJECT fdo, IN PIRP Irp) 
	{							// DispatchWmi 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
	NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); 
	if (!NT_SUCCESS(status)) 
		return CompleteRequest(Irp, status, 0); 
 
#if DBG 
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); 
	ULONG fcn = stack->MinorFunction; 
 
	static char* fcnname[] = { 
		"IRP_MN_QUERY_ALL_DATA", 
		"IRP_MN_QUERY_SINGLE_INSTANCE", 
		"IRP_MN_CHANGE_SINGLE_INSTANCE", 
		"IRP_MN_CHANGE_SINGLE_ITEM", 
		"IRP_MN_ENABLE_EVENTS", 
		"IRP_MN_DISABLE_EVENTS", 
		"IRP_MN_ENABLE_COLLECTION", 
		"IRP_MN_DISABLE_COLLECTION", 
		"IRP_MN_REGINFO", 
		"IRP_MN_EXECUTE_METHOD", 
		}; 
 
	KdPrint((DRIVERNAME " - WMI Request (%s)\n", fcnname[fcn])); 
#endif // DBG 
 
	// Delegate processing to the WMILIB helper library (only available in Win2K) 
 
	ASSERT(!win98); 
 
	SYSCTL_IRP_DISPOSITION disposition; 
	status = WmiSystemControl(&libinfo, fdo, Irp, &disposition); 
 
	switch (disposition) 
		{						// finish handling IRP 
 
	case IrpProcessed: 
		break; 
 
	case IrpNotCompleted: 
		IoCompleteRequest(Irp, IO_NO_INCREMENT); 
		break; 
 
	default: 
	case IrpNotWmi: 
		ASSERT(FALSE); 
 
	case IrpForward: 
		IoSkipCurrentIrpStackLocation(Irp); 
		status = IoCallDriver(pdx->LowerDeviceObject, Irp); 
		break; 
		}						// finish handling IRP 
 
	IoReleaseRemoveLock(&pdx->RemoveLock, Irp); 
	return status; 
	}							// DispatchWmi 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
void WmiInitialize(PDEVICE_OBJECT fdo) 
	{							// WmiInitialize 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
	NTSTATUS status = IoWMIRegistrationControl(fdo, WMIREG_ACTION_REGISTER); 
	if (!NT_SUCCESS(status)) 
		KdPrint((DRIVERNAME " - IoWMIRegistrationControl failed - %X\n", status)); 
	pdx->TheAnswer = 42;		// as always, the answer 
	}							// WmiInitialize 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
void WmiTerminate(PDEVICE_OBJECT fdo) 
	{							// WmiTerminate 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
	IoWMIRegistrationControl(fdo, WMIREG_ACTION_DEREGISTER); 
	}							// WmiTerminate 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
NTSTATUS QueryRegInfo(PDEVICE_OBJECT fdo, PULONG flags, PUNICODE_STRING instname,  
	PUNICODE_STRING* regpath, PUNICODE_STRING resname, PDEVICE_OBJECT* pdo) 
	{							// QueryRegInfo 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
	*flags = WMIREG_FLAG_INSTANCE_PDO; // use static instance names based on PDO's name 
	*regpath = &servkey; 
	RtlInitUnicodeString(resname, L"MofResource"); 
	*pdo = pdx->Pdo; 
	return STATUS_SUCCESS; 
	}							// QueryRegInfo 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
NTSTATUS QueryDataBlock(PDEVICE_OBJECT fdo, PIRP Irp, ULONG guidindex,  
	ULONG instindex, ULONG instcount, PULONG instlength, ULONG bufsize, PUCHAR buffer) 
	{							// QueryDataBlock 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
 
	// WMILIB is supposed to check whether we support the GUID, so the index ought 
	// never to be out of bounds. Also, we should never be asked for more than 
	// just instance zero. 
 
	ASSERT(guidindex < arraysize(guidlist)); 
	ASSERT(instindex == 0); 
	ASSERT(instcount == 1); 
 
	// If no instance length array has been supplied, complete the IRP with the 
	// buffer size which would be required 
 
	if (!instlength || bufsize < sizeof(ULONG)) 
		return WmiCompleteRequest(fdo, Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG), IO_NO_INCREMENT); 
 
	PULONG pvalue = (PULONG) buffer; 
	*pvalue = pdx->TheAnswer; 
	instlength[0] = sizeof(ULONG); 
 
	return WmiCompleteRequest(fdo, Irp, STATUS_SUCCESS, sizeof(ULONG), IO_NO_INCREMENT); 
	}							// QueryDataBlock 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
NTSTATUS SetDataBlock(PDEVICE_OBJECT fdo, PIRP Irp, ULONG guidindex, ULONG instindex, ULONG bufsize, PUCHAR buffer) 
	{							// SetDataBlock 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
	NTSTATUS status; 
	ASSERT(guidindex == 0); 
	ASSERT(instindex == 0); 
	ULONG info; 
 
	if (bufsize == sizeof(ULONG)) 
		{						// correct buffer length	 
		pdx->TheAnswer = *(PULONG) buffer; 
		status = STATUS_SUCCESS; 
		info = sizeof(ULONG); 
		}						// correct buffer length 
	else 
		status = STATUS_INFO_LENGTH_MISMATCH, info = 0; 
 
	return WmiCompleteRequest(fdo, Irp, status, info, IO_NO_INCREMENT); 
	}							// SetDataBlock 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
NTSTATUS SetDataItem(PDEVICE_OBJECT fdo, PIRP Irp, ULONG guidindex, ULONG instindex, ULONG id, ULONG bufsize, PUCHAR buffer) 
	{							// SetDataItem 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; 
	NTSTATUS status; 
	ASSERT(guidindex == 0); 
	ASSERT(instindex == 0); 
	ASSERT(id == 0); 
	ULONG info; 
 
	if (bufsize == sizeof(ULONG)) 
		{						// correct buffer length	 
		pdx->TheAnswer = *(PULONG) buffer; 
		status = STATUS_SUCCESS; 
		info = sizeof(ULONG); 
		}						// correct buffer length 
	else 
		status = STATUS_INFO_LENGTH_MISMATCH, info = 0; 
 
	return WmiCompleteRequest(fdo, Irp, status, info, IO_NO_INCREMENT); 
	}							// SetDataItem 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
NTSTATUS ExecuteMethod(PDEVICE_OBJECT fdo, PIRP Irp, ULONG guidindex, ULONG instindex, ULONG id, ULONG cbInbuf, ULONG cbOutbuf, PUCHAR buffer) 
	{							// ExecuteMethod 
	return WmiCompleteRequest(fdo, Irp, STATUS_INVALID_DEVICE_REQUEST, 0, IO_NO_INCREMENT); 
	}							// ExecuteMethod 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma PAGEDCODE 
 
NTSTATUS FunctionControl(PDEVICE_OBJECT fdo, PIRP Irp, ULONG guidindex, WMIENABLEDISABLECONTROL fcn, BOOLEAN enable) 
	{							// FunctionControl 
	return WmiCompleteRequest(fdo, Irp, STATUS_SUCCESS, 0, IO_NO_INCREMENT); 
	}							// FunctionControl