You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
6.7 KiB
238 lines
6.7 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// 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;
|
|
}
|