mirror of https://github.com/tongzx/nt5src
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.
284 lines
8.4 KiB
284 lines
8.4 KiB
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1998 - 1998
|
|
|
|
Module Name:
|
|
|
|
wmi.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the code that handles the wmi IRPs for
|
|
parallel driver PDOs and PODOs.
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History :
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
#include <wmistr.h>
|
|
#include "wmipdo.h"
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(PAGEPARWMI0, ParWmiPdoInitWmi)
|
|
#pragma alloc_text(PAGEPARWMI0, ParWmiPdoSystemControlDispatch)
|
|
#pragma alloc_text(PAGEPARWMI0, ParWmiPdoQueryWmiRegInfo)
|
|
#pragma alloc_text(PAGEPARWMI0, ParWmiPdoQueryWmiDataBlock)
|
|
#endif
|
|
|
|
#define PAR_WMI_PDO_GUID_COUNT 1
|
|
#define PAR_WMI_BYTES_TRANSFERRED_GUID_INDEX 0
|
|
|
|
GUID ParWmiPdoBytesTransferredGuid = PARALLEL_WMI_BYTES_TRANSFERRED_GUID;
|
|
|
|
WMIGUIDREGINFO ParWmiPdoGuidList[ PAR_WMI_PDO_GUID_COUNT ] =
|
|
{
|
|
{ &ParWmiPdoBytesTransferredGuid, 1, 0 }
|
|
};
|
|
|
|
|
|
NTSTATUS
|
|
ParWmiPdoInitWmi(PDEVICE_OBJECT DeviceObject)
|
|
{
|
|
PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
|
|
PWMILIB_CONTEXT wmiContext = &devExt->WmiLibContext;
|
|
|
|
PAGED_CODE();
|
|
|
|
wmiContext->GuidCount = sizeof(ParWmiPdoGuidList) / sizeof(WMIGUIDREGINFO);
|
|
wmiContext->GuidList = ParWmiPdoGuidList;
|
|
|
|
wmiContext->QueryWmiRegInfo = ParWmiPdoQueryWmiRegInfo;
|
|
wmiContext->QueryWmiDataBlock = ParWmiPdoQueryWmiDataBlock;
|
|
wmiContext->SetWmiDataBlock = NULL;
|
|
wmiContext->SetWmiDataItem = NULL;
|
|
wmiContext->ExecuteWmiMethod = NULL;
|
|
wmiContext->WmiFunctionControl = NULL;
|
|
|
|
return ParWMIRegistrationControl( DeviceObject, WMIREG_ACTION_REGISTER );
|
|
}
|
|
|
|
NTSTATUS
|
|
ParWmiPdoSystemControlDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
|
{
|
|
SYSCTL_IRP_DISPOSITION disposition;
|
|
NTSTATUS status;
|
|
PDEVICE_EXTENSION pDevExt = (PDEVICE_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
|
|
//
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
break;
|
|
|
|
case IrpForward:
|
|
case IrpNotWmi:
|
|
default:
|
|
|
|
//
|
|
// This irp is either not a WMI irp or is a WMI irp targetted
|
|
// at a device lower in the stack.
|
|
//
|
|
// If this was an FDO we would pass the IRP down the stack, but
|
|
// this is a PDO (or PODO) so there no one below us in the
|
|
// stack.
|
|
//
|
|
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
status = STATUS_INVALID_DEVICE_REQUEST;
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
break;
|
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
NTSTATUS
|
|
ParWmiPdoQueryWmiRegInfo(
|
|
IN PDEVICE_OBJECT PDevObj,
|
|
OUT PULONG PRegFlags,
|
|
OUT PUNICODE_STRING PInstanceName,
|
|
OUT PUNICODE_STRING *PRegistryPath,
|
|
OUT PUNICODE_STRING MofResourceName,
|
|
OUT PDEVICE_OBJECT *Pdo
|
|
)
|
|
{
|
|
PDEVICE_EXTENSION devExt = (PDEVICE_EXTENSION)PDevObj->DeviceExtension;
|
|
|
|
PAGED_CODE();
|
|
|
|
if( ParIsPodo(PDevObj) ) {
|
|
// This is a PODO
|
|
PWSTR buffer = ExAllocatePool(PagedPool, devExt->SymbolicLinkName.MaximumLength);
|
|
ParDumpV( ("wmipdo::ParWmiPdoQueryWmiRegInfo: PODO - %wZ\n", &devExt->SymbolicLinkName) );
|
|
if( !buffer ) {
|
|
PInstanceName->Length = 0;
|
|
PInstanceName->MaximumLength = 0;
|
|
PInstanceName->Buffer = NULL;
|
|
} else {
|
|
PInstanceName->Length = 0;
|
|
PInstanceName->MaximumLength = devExt->SymbolicLinkName.MaximumLength;
|
|
PInstanceName->Buffer = buffer;
|
|
*PRegFlags = WMIREG_FLAG_INSTANCE_BASENAME;
|
|
RtlCopyUnicodeString( PInstanceName, &devExt->SymbolicLinkName );
|
|
}
|
|
*PRegistryPath = &RegistryPath;
|
|
} else {
|
|
// this is a PDO
|
|
ParDumpV( ("wmipdo::ParWmiPdoQueryWmiRegInfo: PDO - %x\n", PDevObj) );
|
|
*PRegFlags = WMIREG_FLAG_INSTANCE_PDO;
|
|
*PRegistryPath = &RegistryPath;
|
|
*Pdo = PDevObj;
|
|
}
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
ParWmiPdoQueryWmiDataBlock(
|
|
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(PARALLEL_WMI_LOG_INFO);
|
|
PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// Only ever registers 1 instance per guid
|
|
//
|
|
ASSERT(InstanceIndex == 0 && InstanceCount == 1);
|
|
|
|
switch (GuidIndex) {
|
|
case PAR_WMI_BYTES_TRANSFERRED_GUID_INDEX:
|
|
|
|
//
|
|
// Request is for Bytes Transferred
|
|
//
|
|
if (OutBufferSize < size) {
|
|
status = STATUS_BUFFER_TOO_SMALL;
|
|
break;
|
|
}
|
|
*( (PPARALLEL_WMI_LOG_INFO)Buffer ) = devExt->log;
|
|
*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;
|
|
}
|
|
|
|
NTSTATUS
|
|
ParWMIRegistrationControl(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN ULONG Action
|
|
)
|
|
/*+
|
|
|
|
Wrapper function for IoWMIRegistrationControl that uses Device
|
|
Extension variable WmiRegistrationCount to prevent device from
|
|
registering more than once or from unregistering if not
|
|
registered.
|
|
|
|
-*/
|
|
{
|
|
PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
|
|
NTSTATUS status;
|
|
LONG count;
|
|
|
|
ParDumpV( ("wmipdo::ParWMIRegistrationControl: enter - %wZ\n", &devExt->SymbolicLinkName) );
|
|
|
|
switch( Action ) {
|
|
|
|
case WMIREG_ACTION_REGISTER :
|
|
|
|
//
|
|
// Verify that we don't register more than once
|
|
//
|
|
count = InterlockedIncrement(&devExt->WmiRegistrationCount);
|
|
if( count == 1 ) {
|
|
status = IoWMIRegistrationControl(DeviceObject, Action);
|
|
if( !NT_SUCCESS(status) ) {
|
|
ParDumpV( ("wmipdo::ParWMIRegistrationControl: REGISTER - FAIL\n") );
|
|
// registration failed - back out the increment
|
|
InterlockedDecrement(&devExt->WmiRegistrationCount);
|
|
} else {
|
|
ParDumpV( ("wmipdo::ParWMIRegistrationControl: REGISTER - SUCCEED\n") );
|
|
}
|
|
} else {
|
|
ParDumpV( ("wmipdo::ParWMIRegistrationControl: REGISTER - ABORT - already REGISTERed\n") );
|
|
// back out the increment
|
|
InterlockedDecrement(&devExt->WmiRegistrationCount);
|
|
status = STATUS_UNSUCCESSFUL;
|
|
// ASSERTMSG( "Already registered for WMI registration, fail registration", FALSE );
|
|
}
|
|
break;
|
|
|
|
case WMIREG_ACTION_DEREGISTER :
|
|
|
|
//
|
|
// verify that we don't unregister if we are not registered
|
|
//
|
|
count = InterlockedDecrement(&devExt->WmiRegistrationCount);
|
|
if( count == 0 ) {
|
|
status = IoWMIRegistrationControl(DeviceObject, Action);
|
|
if( !NT_SUCCESS(status) ) {
|
|
ParDumpV( ("wmipdo::ParWMIRegistrationControl: DEREGISTER - FAIL\n") );
|
|
// unregistration failed?
|
|
// ASSERTMSG( "WMI unregistration failed?", FALSE );
|
|
InterlockedIncrement(&devExt->WmiRegistrationCount);
|
|
} else {
|
|
ParDumpV( ("wmipdo::ParWMIRegistrationControl: DEREGISTER - SUCCEED\n") );
|
|
}
|
|
} else {
|
|
ParDumpV( ("wmipdo::ParWMIRegistrationControl: DEREGISTER - ABORT - not registered\n") );
|
|
// unregistration failed - back out the decrement
|
|
InterlockedIncrement(&devExt->WmiRegistrationCount);
|
|
status = STATUS_UNSUCCESSFUL;
|
|
// ASSERTMSG( "Not registered for WMI, fail unregister", FALSE );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
// unrecognized action
|
|
status = STATUS_UNSUCCESSFUL;
|
|
ASSERTMSG("wmipdo::ParWMIRegistrationControl: Unrecognized WMI registration Action \n",FALSE);
|
|
}
|
|
|
|
return status;
|
|
}
|