Leaked source code of windows server 2003
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

//+-------------------------------------------------------------------------
//
// 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;
}