|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: wmi.c
//
//--------------------------------------------------------------------------
#include "pch.h"
#include <wmistr.h>
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGEPARWMI0, PptWmiInitWmi)
#pragma alloc_text(PAGEPARWMI0, PptWmiQueryWmiRegInfo)
#pragma alloc_text(PAGEPARWMI0, PptWmiQueryWmiDataBlock)
#endif
//
// Number of WMI GUIDs that we support
//
#define PPT_WMI_PDO_GUID_COUNT 1
//
// Index of GUID PptWmiAllocFreeCountsGuid in the array of supported WMI GUIDs
//
#define PPT_WMI_ALLOC_FREE_COUNTS_GUID_INDEX 0
//
// defined in wmidata.h:
//
// // {4BBB69EA-6853-11d2-8ECE-00C04F8EF481}
// #define PARPORT_WMI_ALLOCATE_FREE_COUNTS_GUID {0x4bbb69ea, 0x6853, 0x11d2, 0x8e, 0xce, 0x0, 0xc0, 0x4f, 0x8e, 0xf4, 0x81}
//
// typedef struct _PARPORT_WMI_ALLOC_FREE_COUNTS {
// ULONG PortAllocates; // number of Port Allocate requests granted
// ULONG PortFrees; // number of Port Free requests granted
// } PARPORT_WMI_ALLOC_FREE_COUNTS, *PPARPORT_WMI_ALLOC_FREE_COUNTS;
//
//
// Define the (only at the moment) WMI GUID that we support
//
GUID PptWmiAllocFreeCountsGuid = PARPORT_WMI_ALLOCATE_FREE_COUNTS_GUID;
//
// Array of WMI GUIDs supported by driver
//
WMIGUIDREGINFO PptWmiGuidList[ PPT_WMI_PDO_GUID_COUNT ] = { { &PptWmiAllocFreeCountsGuid, 1, 0 } };
//
// Initialize WMI Context that we pass to WMILIB during the handling of
// IRP_MJ_SYSTEM_CONTROL. This context lives in our device extension
//
// Register w/WMI that we are able to process WMI IRPs
//
NTSTATUS PptWmiInitWmi(PDEVICE_OBJECT DeviceObject) { PFDO_EXTENSION devExt = DeviceObject->DeviceExtension; PWMILIB_CONTEXT wmiContext = &devExt->WmiLibContext;
PAGED_CODE();
wmiContext->GuidCount = sizeof(PptWmiGuidList) / sizeof(WMIGUIDREGINFO); wmiContext->GuidList = PptWmiGuidList;
wmiContext->QueryWmiRegInfo = PptWmiQueryWmiRegInfo; // required
wmiContext->QueryWmiDataBlock = PptWmiQueryWmiDataBlock; // required
wmiContext->SetWmiDataBlock = NULL; // optional
wmiContext->SetWmiDataItem = NULL; // optional
wmiContext->ExecuteWmiMethod = NULL; // optional
wmiContext->WmiFunctionControl = NULL; // optional
// Tell WMI that we can now accept WMI IRPs
return IoWMIRegistrationControl( DeviceObject, WMIREG_ACTION_REGISTER ); }
NTSTATUS //
// This is the dispatch routine for IRP_MJ_SYSTEM_CONTROL IRPs.
//
// We call WMILIB to process the IRP for us. WMILIB returns a disposition
// that tells us what to do with the IRP.
//
PptFdoSystemControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { SYSCTL_IRP_DISPOSITION disposition; NTSTATUS status; PFDO_EXTENSION pDevExt = (PFDO_EXTENSION)DeviceObject->DeviceExtension;
PAGED_CODE();
status = WmiSystemControl( &pDevExt->WmiLibContext, DeviceObject, Irp, &disposition); switch(disposition) { case IrpProcessed:
//
// This irp has been processed and may be completed or pending.
//
break; case IrpNotCompleted: //
// This irp has not been completed, but has been fully processed.
// we will complete it now
//
P4CompleteRequest( Irp, Irp->IoStatus.Status, Irp->IoStatus.Information ); break; case IrpForward: case IrpNotWmi: //
// This irp is either not a WMI irp or is a WMI irp targetted
// at a device lower in the stack.
//
IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pDevExt->ParentDeviceObject, Irp); break; default:
//
// We really should never get here, but if we do just forward....
//
ASSERT(FALSE); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pDevExt->ParentDeviceObject, Irp); break; } return status;
}
//
// This is our callback routine that WMI calls when it wants to find out
// information about the data blocks and/or events that the device provides.
//
NTSTATUS PptWmiQueryWmiRegInfo( IN PDEVICE_OBJECT PDevObj, OUT PULONG PRegFlags, OUT PUNICODE_STRING PInstanceName, OUT PUNICODE_STRING *PRegistryPath, OUT PUNICODE_STRING MofResourceName, OUT PDEVICE_OBJECT *Pdo ) { PFDO_EXTENSION devExt = PDevObj->DeviceExtension;
UNREFERENCED_PARAMETER( PInstanceName ); UNREFERENCED_PARAMETER( MofResourceName );
PAGED_CODE();
DD((PCE)devExt,DDT,"wmi::PptWmiQueryWmiRegInfo\n"); *PRegFlags = WMIREG_FLAG_INSTANCE_PDO; *PRegistryPath = &RegistryPath; *Pdo = devExt->PhysicalDeviceObject; return STATUS_SUCCESS; }
//
// This is our callback routine that WMI calls to query a data block
//
NTSTATUS PptWmiQueryWmiDataBlock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG InstanceIndex, IN ULONG InstanceCount, IN OUT PULONG InstanceLengthArray, IN ULONG OutBufferSize, OUT PUCHAR Buffer ) { NTSTATUS status; ULONG size = sizeof(PARPORT_WMI_ALLOC_FREE_COUNTS); PFDO_EXTENSION devExt = DeviceObject->DeviceExtension;
PAGED_CODE();
//
// Only ever registers 1 instance per guid
//
#if DBG
ASSERT(InstanceIndex == 0 && InstanceCount == 1); #else
UNREFERENCED_PARAMETER( InstanceCount ); UNREFERENCED_PARAMETER( InstanceIndex ); #endif
switch (GuidIndex) { case PPT_WMI_ALLOC_FREE_COUNTS_GUID_INDEX:
//
// Request is for ParPort Alloc and Free Counts
//
// If caller's buffer is large enough then return the info, otherwise
// tell the caller how large of a buffer is required so they can
// call us again with a buffer of sufficient size.
//
if (OutBufferSize < size) { status = STATUS_BUFFER_TOO_SMALL; break; } *( (PPARPORT_WMI_ALLOC_FREE_COUNTS)Buffer ) = devExt->WmiPortAllocFreeCounts; *InstanceLengthArray = size; status = STATUS_SUCCESS; break;
default:
//
// Index value larger than our largest supported - invalid request
//
status = STATUS_WMI_GUID_NOT_FOUND; break; }
status = WmiCompleteRequest( DeviceObject, Irp, status, size, IO_NO_INCREMENT );
return status; }
|