ReactOS 0.4.15-dev-7942-gd23573b
FxWmiIrpHandler Class Reference

#include <fxwmiirphandler.hpp>

Inheritance diagram for FxWmiIrpHandler:
Collaboration diagram for FxWmiIrpHandler:

Public Member Functions

 FxWmiIrpHandler (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device, __in WDFTYPE Type=FX_TYPE_WMI_IRP_HANDLER)
 
 ~FxWmiIrpHandler ()
 
_Must_inspect_result_ NTSTATUS PostCreateDeviceInitialize (VOID)
 
_Must_inspect_result_ NTSTATUS HandleWmiTraceRequest (__in PIRP Irp, __in FxTraceInfo *Info)
 
virtual _Must_inspect_result_ NTSTATUS Dispatch (__in PIRP Irp)
 
_Must_inspect_result_ NTSTATUS Register (VOID)
 
VOID Deregister (VOID)
 
VOID Cleanup (VOID)
 
VOID ResetStateForPdoRestart (VOID)
 
_Must_inspect_result_ NTSTATUS AddProvider (__in FxWmiProvider *Provider, __out_opt PBOOLEAN Update=NULL)
 
_Must_inspect_result_ NTSTATUS AddPowerPolicyProviderAndInstance (__in PWDF_WMI_PROVIDER_CONFIG ProviderConfig, __in FxWmiInstanceInternalCallbacks *Callbacks, __inout FxWmiInstanceInternal **Instance)
 
- Public Member Functions inherited from FxPackage
 FxPackage (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device, __in WDFTYPE Type)
 
virtual NTSTATUS Dispatch (__in MdIrp Irp)=0
 
__inline CfxDeviceGetDevice (VOID)
 
 DECLARE_INTERNAL_NEW_OPERATOR ()
 
- Public Member Functions inherited from FxNonPagedObject
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
 FxNonPagedObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
virtual ~FxNonPagedObject (VOID)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_maxIRQL(DISPATCH_LEVEL) __drv_setsIRQL(DISPATCH_LEVEL) VOID Lock(__out __drv_deref(__drv_savesIRQL) PKIRQL PreviousIrql)
 
 _Releases_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID Unlock(__in __drv_restoresIRQL KIRQL PreviousIrql)
 
 _Acquires_lock_ (this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) VOID LockAtDispatch(VOID)
 
 _Requires_lock_held_ (this->m_NPLock.m_Lock) _Releases_lock_(this -> m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID UnlockFromDispatch(VOID)
 
- Public Member Functions inherited from FxObject
PVOID GetCOMWrapper ()
 
void SetCOMWrapper (__drv_aliasesMem PVOID Wrapper)
 
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
 
virtual ~FxObject (VOID)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType Type)
 
PVOID __inline operator new (__in size_t Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __in USHORT ExtraSize=0)
 
VOID operator delete (__in PVOID Memory)
 
VOID SetNoContextHeader (VOID)
 
PVOID __inline GetObjectHandle (VOID)
 
__inline FxContextHeaderGetContextHeader (VOID)
 
__inline PFX_DRIVER_GLOBALS GetDriverGlobals (VOID)
 
WDFTYPE GetType (VOID)
 
USHORT GetObjectSize (VOID)
 
LONG GetRefCnt (VOID)
 
FxTagTrackerGetTagTracker (VOID)
 
CfxDeviceGetDevice (VOID)
 
CfxDeviceBaseGetDeviceBase (VOID)
 
VOID SetDeviceBase (__in CfxDeviceBase *DeviceBase)
 
__inline VOID CallCleanup (VOID)
 
ULONG __inline AddRef (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG Release (__in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG AddRefOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual ULONG ReleaseOverride (__in WDFOBJECT_OFFSET Offset, __in_opt PVOID Tag=NULL, __in LONG Line=0, __in_opt PSTR File=NULL)
 
virtual _Must_inspect_result_ NTSTATUS QueryInterface (__in FxQueryInterfaceParams *Params)
 
VOID MarkTraceState (VOID)
 
BOOLEAN __inline IsTraceState (VOID)
 
VOID __inline TraceDroppedEvent (__in FxObjectDroppedEvent Event)
 
VOID MarkPassiveDispose (__in FxObjectLockState State=ObjectLock)
 
VOID MarkPassiveCallbacks (__in FxObjectLockState State=ObjectLock)
 
VOID MarkForceDisposeThread (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsPassiveCallbacks (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsPassiveDispose (__in BOOLEAN AcquireLock=TRUE)
 
BOOLEAN IsForceDisposeThread (__in BOOLEAN AcquireLock=TRUE)
 
VOID MarkCommitted (VOID)
 
BOOLEAN IsCommitted (VOID)
 
VOID MarkDisposeOverride (__in FxObjectLockState State=ObjectLock)
 
VOID MarkNoDeleteDDI (__in FxObjectLockState State=ObjectLock)
 
BOOLEAN IsNoDeleteDDI (VOID)
 
_Must_inspect_result_ NTSTATUS Commit (__in_opt PWDF_OBJECT_ATTRIBUTES Attributes, __out_opt WDFOBJECT *ObjectHandle, __in_opt FxObject *Parent=NULL, __in BOOLEAN AssignDriverAsDefaultParent=TRUE)
 
VOID DeleteFromFailedCreate (VOID)
 
VOID ClearEvtCallbacks (VOID)
 
BOOLEAN EarlyDispose (VOID)
 
virtual VOID DeleteObject (VOID)
 
virtual BOOLEAN Dispose (VOID)
 
_Must_inspect_result_ NTSTATUS AssignParentObject (__in FxObject *ParentObject)
 
_Must_inspect_result_ NTSTATUS AddContext (__in FxContextHeader *Header, __in PVOID *Context, __in PWDF_OBJECT_ATTRIBUTES Attributes)
 
_Must_inspect_result_ NTSTATUS RemoveParentAssignment (VOID)
 
_Must_inspect_result_ FxObjectGetParentObjectReferenced (__in PVOID Tag)
 
BOOLEAN IsDisposed (VOID)
 

Protected Types

enum  WmiRegisteredState { WmiUnregistered = 0 , WmiRegistered , WmiDeregistered , WmiCleanedUp }
 

Protected Member Functions

_Must_inspect_result_ NTSTATUS AddProviderLocked (__in FxWmiProvider *Provider, __in KIRQL Irql, __out_opt PBOOLEAN Update=NULL)
 
VOID RemoveProvider (__in FxWmiProvider *Provider)
 
VOID RemoveProviderLocked (__in FxWmiProvider *Provider)
 
_Must_inspect_result_ FxWmiProviderFindProviderLocked (__in LPGUID Guid)
 
_Must_inspect_result_ FxWmiProviderFindProviderReferenced (__in LPGUID Guid, __in PVOID Tag)
 
- Protected Member Functions inherited from FxObject
 FxObject (__in WDFTYPE Type, __in USHORT Size, __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObjectType ObjectType)
 
FxObjectDebugExtensionGetDebugExtension (VOID)
 
BOOLEAN IsDebug (VOID)
 
VOID AllocateTagTracker (__in WDFTYPE Type)
 
virtual VOID SelfDestruct (VOID)
 
PVOID __inline GetObjectHandleUnchecked (VOID)
 
VOID __inline DestroyChildren (VOID)
 
VOID DeleteEarlyDisposedObject (VOID)
 

Static Protected Member Functions

static VOID CheckAssumptions (VOID)
 
- Static Protected Member Functions inherited from FxObject
static PVOID _GetBase (__in FxObject *Object)
 

Protected Attributes

LIST_ENTRY m_ProvidersListHead
 
ULONG m_NumProviders
 
WmiRegisteredState m_RegisteredState
 
PIO_WORKITEM m_WorkItem
 
LONG m_UpdateCount
 
FxCREvent m_UpdateEvent
 
PKEVENT m_WorkItemEvent
 
BOOLEAN m_WorkItemQueued
 
- Protected Attributes inherited from FxObject
union {
   CfxDeviceBase *   m_DeviceBase
 
   CfxDevice *   m_Device
 
}; 
 

Static Protected Attributes

static const FxWmiMinorEntry m_WmiDispatchTable []
 

Private Member Functions

VOID CompleteWmiQueryAllDataRequest (__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
 
VOID CompleteWmiQuerySingleInstanceRequest (__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
 
VOID CompleteWmiExecuteMethodRequest (__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
 
_Must_inspect_result_ NTSTATUS CompleteWmiRequest (__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
 
BOOLEAN DeferUpdateLocked (__in KIRQL OldIrql)
 
VOID UpdateGuids (VOID)
 
VOID IncrementUpdateCount ()
 
VOID DecrementUpdateCount ()
 
VOID DecrementUpdateCountAndWait ()
 

Static Private Member Functions

static _Must_inspect_result_ NTSTATUS _QueryAllData (__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in_opt FxWmiInstance *Instance)
 
static _Must_inspect_result_ NTSTATUS _QuerySingleInstance (__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in FxWmiInstance *Instance)
 
static _Must_inspect_result_ NTSTATUS _ChangeSingleInstance (__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in FxWmiInstance *Instance)
 
static _Must_inspect_result_ NTSTATUS _ChangeSingleItem (__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in FxWmiInstance *Instance)
 
static _Must_inspect_result_ NTSTATUS _EnableDisableEventsAndCollection (__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in FxWmiInstance *Instance)
 
static _Must_inspect_result_ NTSTATUS _RegInfo (__in FxWmiIrpHandler *This, __in PIRP Irp, __in_opt FxWmiProvider *Provider, __in_opt FxWmiInstance *Instance)
 
static _Must_inspect_result_ NTSTATUS _ExecuteMethod (__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in FxWmiInstance *Instance)
 

Private Attributes

friend FxWmiProvider
 

Static Private Attributes

static MX_WORKITEM_ROUTINE _UpdateGuids
 

Additional Inherited Members

- Static Public Member Functions inherited from FxObject
static FxObject_FromDisposeEntry (__in PSINGLE_LIST_ENTRY Entry)
 
static FxObject_GetObjectFromHandle (__in WDFOBJECT Handle, __inout PWDFOBJECT_OFFSET ObjectOffset)
 
static PVOID __inline _ToHandle (__in FxObject *Object)
 
static VOID __inline _ReferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static VOID __inline _DereferenceActual (__in WDFOBJECT Object, __in_opt PVOID Tag, __in LONG Line, __in PSTR File)
 
static PVOID _GetDebugBase (__in FxObject *Object)
 
static PFX_POOL_HEADER _CleanupPointer (__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in FxObject *Object)
 
static _Must_inspect_result_ NTSTATUS _GetEffectiveLock (__in FxObject *Object, __in_opt IFxHasCallbacks *Callbacks, __in BOOLEAN AutomaticLocking, __in BOOLEAN PassiveCallbacks, __out FxCallbackLock **CallbackLock, __out_opt FxObject **CallbackLockObject)
 
static _Must_inspect_result_ NTSTATUS _ObjectQuery (_In_ FxObject *Object, _In_ CONST GUID *Guid, _In_ ULONG QueryBufferLength, _Out_writes_bytes_(QueryBufferLength) PVOID QueryBuffer)
 

Detailed Description

Definition at line 44 of file fxwmiirphandler.hpp.

Member Enumeration Documentation

◆ WmiRegisteredState

Enumerator
WmiUnregistered 
WmiRegistered 
WmiDeregistered 
WmiCleanedUp 

Definition at line 293 of file fxwmiirphandler.hpp.

Constructor & Destructor Documentation

◆ FxWmiIrpHandler()

FxWmiIrpHandler::FxWmiIrpHandler ( __in PFX_DRIVER_GLOBALS  FxDriverGlobals,
__in CfxDevice Device,
__in WDFTYPE  Type = FX_TYPE_WMI_IRP_HANDLER 
)

Definition at line 83 of file fxwmiirphandler.cpp.

87 :
88 FxPackage(FxDriverGlobals, Device, Type),
91 m_UpdateCount(1) // bias m_UpdateCount to 1, Deregister routine will
92 // decrement this.
93{
95}
Type
Definition: Type.h:7
PIO_WORKITEM m_WorkItem
LIST_ENTRY m_ProvidersListHead
WmiRegisteredState m_RegisteredState
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474

◆ ~FxWmiIrpHandler()

FxWmiIrpHandler::~FxWmiIrpHandler ( )

Definition at line 97 of file fxwmiirphandler.cpp.

98{
99 //
100 // If the device could not get past AddDevice or failed the initial start
101 // device, we will be unregistered. Otherwise we should be cleaned up.
102 //
104
106
107 if (m_WorkItem != NULL) {
109 }
110}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define ASSERT(a)
Definition: mode.c:44

Member Function Documentation

◆ _ChangeSingleInstance()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::_ChangeSingleInstance ( __in FxWmiIrpHandler This,
__in PIRP  Irp,
__in FxWmiProvider Provider,
__in FxWmiInstance Instance 
)
staticprivate

Definition at line 1297 of file fxwmiirphandler.cpp.

1303{
1304 PWNODE_SINGLE_INSTANCE pSingle;
1307 ULONG size;
1308
1309 size = 0;
1310
1312 pSingle = (PWNODE_SINGLE_INSTANCE) stack->Parameters.WMI.Buffer;
1313
1314 if (Instance->IsSetInstanceSupported() == FALSE) {
1316 }
1317 else if (pSingle->SizeDataBlock < Provider->m_MinInstanceBufferSize) {
1318 size = Provider->m_MinInstanceBufferSize;
1320 }
1321 else {
1323 }
1324
1325 if (NT_SUCCESS(status)) {
1326 size = pSingle->SizeDataBlock;
1327
1328 status = Instance->SetInstance(
1329 pSingle->SizeDataBlock,
1330 size == 0 ?
1331 NULL : WDF_PTR_ADD_OFFSET(pSingle, pSingle->DataBlockOffset)
1332 );
1333
1335 if (status == STATUS_PENDING) {
1337 size = 0;
1338 }
1339 }
1340
1341 status = This->CompleteWmiRequest(Irp, status, size);
1342
1343 return status;
1344}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
LONG NTSTATUS
Definition: precomp.h:26
Definition: _stack.h:55
_In_ PIRP Irp
Definition: csq.h:116
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
GLsizeiptr size
Definition: glext.h:5919
if(dx< 0)
Definition: linetemp.h:194
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_WMI_READ_ONLY
Definition: ntstatus.h:818
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define WDF_PTR_ADD_OFFSET(_ptr, _offset)
Definition: wdfcore.h:144
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_INSTANCE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_opt_ WDFWMIINSTANCE * Instance
Definition: wdfwmi.h:481
struct tagWNODE_SINGLE_INSTANCE * PWNODE_SINGLE_INSTANCE

◆ _ChangeSingleItem()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::_ChangeSingleItem ( __in FxWmiIrpHandler This,
__in PIRP  Irp,
__in FxWmiProvider Provider,
__in FxWmiInstance Instance 
)
staticprivate

Definition at line 1348 of file fxwmiirphandler.cpp.

1354{
1355 PWNODE_SINGLE_ITEM pSingle;
1357 ULONG size;
1358
1360
1361 size = 0;
1362
1364 Parameters.WMI.Buffer;
1365
1366 if (Instance->IsSetItemSupported() == FALSE) {
1368 }
1369 else {
1371 }
1372
1373 if (NT_SUCCESS(status)) {
1374 status = Instance->SetItem(
1375 pSingle->ItemId,
1376 pSingle->SizeDataItem,
1377 pSingle->SizeDataItem == 0 ?
1378 NULL : WDF_PTR_ADD_OFFSET(pSingle, pSingle->DataBlockOffset)
1379 );
1380
1382 if (status == STATUS_PENDING) {
1384 size = 0;
1385 }
1386 }
1387
1388 status = This->CompleteWmiRequest(Irp, status, size);
1389
1390 return status;
1391}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
struct _IO_STACK_LOCATION::@3978::@4016 WMI
ULONG DataBlockOffset
Definition: wmistr.h:129
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
struct tagWNODE_SINGLE_ITEM * PWNODE_SINGLE_ITEM

◆ _EnableDisableEventsAndCollection()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::_EnableDisableEventsAndCollection ( __in FxWmiIrpHandler This,
__in PIRP  Irp,
__in FxWmiProvider Provider,
__in FxWmiInstance Instance 
)
staticprivate

Definition at line 1395 of file fxwmiirphandler.cpp.

1401{
1406
1409
1410 Irp->IoStatus.Information = 0;
1411
1413
1414 if (stack->Parameters.WMI.BufferSize < sizeof(WNODE_HEADER)) {
1416 goto Done;
1417 }
1418
1419 switch (stack->MinorFunction) {
1421 enable = TRUE;
1422 control = WdfWmiEventControl;
1423 break;
1424
1426 enable = FALSE;
1427 control = WdfWmiEventControl;
1428 break;
1429
1431 enable = TRUE;
1432 control = WdfWmiInstanceControl;
1433 break;
1434
1436 enable = FALSE;
1437 control = WdfWmiInstanceControl;
1438 break;
1439
1440 default:
1441 status = Irp->IoStatus.Status;
1442 goto Done;
1443 }
1444
1445 if (control == WdfWmiEventControl) {
1446 Provider->m_EventControlEnabled = enable;
1447
1448 //
1449 // Capture the tracing information before making the callback
1450 //
1451 if (Provider->m_Flags & WdfWmiProviderTracing) {
1452 Provider->SetTracingHandle(
1453 ((PWNODE_HEADER) stack->Parameters.WMI.Buffer)->HistoricalContext
1454 );
1455 }
1456 }
1457 else {
1458 Provider->m_DataBlockControlEnabled = enable;
1459 }
1460
1461 if (Provider->IsFunctionControlSupported()) {
1462 status = Provider->FunctionControl(control, enable);
1463 }
1464 else {
1466 }
1467
1469 if (status == STATUS_PENDING) {
1471 }
1472
1473 //
1474 // Undo the previous capture on error
1475 //
1476 if (!NT_SUCCESS(status)) {
1477 if (control == WdfWmiEventControl) {
1478 Provider->m_EventControlEnabled = FALSE;
1479
1480 if (Provider->m_Flags & WdfWmiProviderTracing) {
1481 Provider->SetTracingHandle(NULL);
1482 }
1483 }
1484 else {
1485 Provider->m_DataBlockControlEnabled = FALSE;
1486 }
1487
1488 }
1489
1490Done:
1491 Irp->IoStatus.Status = status;
1493
1494 return status;
1495}
unsigned char BOOLEAN
#define TRUE
Definition: types.h:120
GLboolean enable
Definition: glext.h:11120
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
@ WdfWmiEventControl
Definition: wdfwmi.h:52
@ WdfWmiInstanceControl
Definition: wdfwmi.h:53
@ WdfWmiProviderTracing
Definition: wdfwmi.h:71
WDF_EXTERN_C_START enum _WDF_WMI_PROVIDER_CONTROL WDF_WMI_PROVIDER_CONTROL
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_DISABLE_COLLECTION
#define IRP_MN_DISABLE_EVENTS
#define IRP_MN_ENABLE_EVENTS
#define IRP_MN_ENABLE_COLLECTION

◆ _ExecuteMethod()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::_ExecuteMethod ( __in FxWmiIrpHandler This,
__in PIRP  Irp,
__in FxWmiProvider Provider,
__in FxWmiInstance Instance 
)
staticprivate

Definition at line 1499 of file fxwmiirphandler.cpp.

1505{
1506 PWNODE_METHOD_ITEM pMethod;
1509 ULONG size, inBufferSize, outBufferSize;
1510
1513
1514 size = 0;
1515
1517 pMethod = (PWNODE_METHOD_ITEM) stack->Parameters.WMI.Buffer;
1518 inBufferSize = pMethod->SizeDataBlock;
1519 outBufferSize = stack->Parameters.WMI.BufferSize - pMethod->DataBlockOffset;
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531 if (Instance->IsExecuteMethodSupported() == FALSE) {
1532 //
1533 // WmiLib returns this value when there is no execute method function
1534 // pointer specified to it.
1535 //
1537 }
1538 else {
1540 }
1541
1542 if (NT_SUCCESS(status)) {
1543 status = Instance->ExecuteMethod(
1544 pMethod->MethodId,
1545 inBufferSize,
1546 outBufferSize,
1547 (inBufferSize == 0 && outBufferSize == 0) ?
1548 NULL : WDF_PTR_ADD_OFFSET(pMethod, pMethod->DataBlockOffset),
1549 &size
1550 );
1551
1553 if (status == STATUS_PENDING) {
1555 size = 0;
1556 }
1557 }
1558
1559 status = This->CompleteWmiRequest(Irp, status, size);
1560
1561 return status;
1562}
ULONG DataBlockOffset
Definition: wmistr.h:140
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
struct tagWNODE_METHOD_ITEM * PWNODE_METHOD_ITEM

◆ _QueryAllData()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::_QueryAllData ( __in FxWmiIrpHandler This,
__in PIRP  Irp,
__in FxWmiProvider Provider,
__in_opt FxWmiInstance Instance 
)
staticprivate

Definition at line 813 of file fxwmiirphandler.cpp.

841{
843 PWNODE_ALL_DATA pNodeData;
846 NTSTATUS status, addStatus;
847 ULONG instanceCount, dataBlockOffset, lengthArraySize, i, sizeRemaining,
848 lastAdjustment, bufferUsed, tempOffset;
849 KIRQL irql;
850 BOOLEAN tooSmall;
851
853
855
857 pNodeData = (PWNODE_ALL_DATA) stack->Parameters.WMI.Buffer;
858
859 lastAdjustment = 0;
860 pData = NULL;
861 dataBlockOffset = 0;
862
863 //
864 // This either the amount of buffer used on successful queries or the
865 // amount of buffer required if the buffer is not big enough.
866 //
867 bufferUsed = 0;
868
869 tooSmall = FALSE;
870
871 if (stack->Parameters.WMI.BufferSize < sizeof(WNODE_ALL_DATA)) {
873 goto Done;
874 }
875
876
877
878
879
880
881
882 //
883 // All of the provider's access is guarded by the irp handler's lock
884 //
885 This->Lock(&irql);
886 instanceCount = Provider->m_NumInstances;
887 This->Unlock(irql);
888
889
890
891
892
893
894
895
896
897
898
899 if (instanceCount == 0) {
902 This->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
903 "Failing QueryAllData since no instances found for "
904 "WDFWMIPROVIDER %p, %!STATUS!",
905 Provider->GetHandle(), status);
906 bufferUsed = 0;
907 goto Done;
908 }
909
911 This->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
912 "WDFWMIPROVIDER %p QueryAllData, num instances %d",
913 Provider->GetHandle(), instanceCount);
914
915 pNodeData->InstanceCount = instanceCount;
916
917
918
919
920
921
922 pNodeData->WnodeHeader.Flags &= ~WNODE_FLAG_FIXED_INSTANCE_SIZE;
923
924 //
925 // Since value of instanceCount is not limited, do overflow-safe addition
926 // and multiplication
927 //
928 // lengthArraySize = instanceCount * sizeof(OFFSETINSTANCEDATAANDLENGTH);
929 status = RtlULongMult(instanceCount,
931 &lengthArraySize);
932
933 if (NT_SUCCESS(status)) {
934 // dataBlockOffset =
935 // FIELD_OFFSET(WNODE_ALL_DATA, OffsetInstanceDataAndLength) + lengthArraySize;
936 status = RtlULongAdd(
937 FIELD_OFFSET(WNODE_ALL_DATA, OffsetInstanceDataAndLength),
938 lengthArraySize,
939 &tempOffset);
940
941 if (NT_SUCCESS(status)) {
942 dataBlockOffset = (ULONG) WDF_ALIGN_SIZE_UP(
943 tempOffset, MEMORY_ALLOCATION_ALIGNMENT);
944
945 if (dataBlockOffset < tempOffset) {
947 }
948 }
949 }
950
951 if (!NT_SUCCESS(status)) {
953 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
954 "Failing QueryAllData since integer overflow occured using"
955 " provider instance count %d for WDFWMIPROVIDER %p, %!STATUS!",
956 instanceCount, Provider->GetHandle(), status);
957 bufferUsed = 0;
958 goto Done;
959 }
960
961 pNodeData->DataBlockOffset = dataBlockOffset;
962
963 if (dataBlockOffset <= stack->Parameters.WMI.BufferSize) {
964 pOffsets = &pNodeData->OffsetInstanceDataAndLength[0];
965 sizeRemaining = stack->Parameters.WMI.BufferSize - dataBlockOffset;
966 pData = (PUCHAR) WDF_PTR_ADD_OFFSET(pNodeData, dataBlockOffset);
967 }
968 else {
969 //
970 // There is not enough room in the WNODE to complete the query, but
971 // we still want to query all the instances to see how big a buffer the
972 // caller should resend.
973 //
974 pOffsets = NULL;
975 pData = NULL;
976 sizeRemaining = 0;
977
978 //
979 // We are in the too small case
980 //
981 tooSmall = TRUE;
983 }
984
985 if (instanceCount > 0 && Provider->GetMinInstanceBufferSize() != 0) {
986 ULONG size, minSizeAdjusted;
987
988 size = 0;
989
990 minSizeAdjusted = (ULONG) WDF_ALIGN_SIZE_UP(
991 Provider->GetMinInstanceBufferSize(),
993 );
994
995 //
996 // Quick size check to make sure there is enough buffer for all of the
997 // instances. We round up all but the last instance's minimum size so
998 // that we can make sure we have enough room for an aligned bufer for
999 // each instance.
1000 //
1001 // All but the last instance are using the adjusted size. In the end,
1002 // we will have:
1003 //
1004 // size = minSizeAdjusted * (instanceCount-1) +
1005 // Provider->GetMinInstanceBufferSize();
1006 //
1007 // NOTE: we do not care about instances which do not support query
1008 // data. We don't care b/c by computing the total size of all
1009 // instances we compute the maximum sized buffer needed, and if
1010 // a few instances do no support query data, then the buffer
1011 // will just be too large, never too small.
1012 //
1013 status = RtlULongMult(minSizeAdjusted, instanceCount - 1, &size);
1014 if (!NT_SUCCESS(status)) {
1015 goto Done;
1016 }
1017
1018 status = RtlULongAdd(size, Provider->GetMinInstanceBufferSize(), &size);
1019 if (!NT_SUCCESS(status)) {
1020 goto Done;
1021 }
1022
1023 //
1024 // Since the client indicated that that each block as a minimum instance
1025 // size (which in reality is the fixed size, variable sized instnaces
1026 // should report a minimum instance size of zero), we can compute the
1027 // required buffer size w/out querying each instance for the required
1028 // size.
1029 //
1030 if (sizeRemaining < size) {
1031 //
1032 // bufferUsed in the buffer too small case indicates how many bytes
1033 // we want the caller to allocate.
1034 //
1035 bufferUsed = size;
1037 goto Done;
1038 }
1039 }
1040
1041 for (i = 0; i < instanceCount; i++) {
1043
1044 //
1045 // In the case where we have a minimum instance size, we should have
1046 // verified correctly above to have enough buffer.
1047 //
1048 ASSERT(sizeRemaining >= Provider->GetMinInstanceBufferSize());
1049
1050 pInstance = Provider->GetInstanceReferenced(i, Irp);
1051
1052 if (pInstance == NULL) {
1053 break;
1054 }
1055
1057 ULONG tmpSize;
1058
1059 tmpSize = 0;
1060
1061 status = pInstance->QueryInstance(sizeRemaining, pData, &tmpSize);
1062
1064 ULONG adjustedSize;
1065
1066 //
1067 // We calculate the size in both cases. In the NT_SUCCESS case,
1068 // it is the amount of buffer used. In the too small case, it is
1069 // the amount of buffer required for a subsequent query.
1070 //
1071 adjustedSize = (ULONG) WDF_ALIGN_SIZE_UP(
1073 );
1074
1075 if (adjustedSize < tmpSize) {
1076 //
1077 // Overflow, adjustedSize will be >= tmpSize in the normal
1078 // case.
1079 //
1082 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
1083 "WDFWMIINSTNACE %p queried, returned a buffer size of %d,"
1084 "but it could not be rounded up, %!STATUS!",
1085 pInstance->GetHandle(), tmpSize, status);
1086 goto QueryError;
1087 }
1088
1089 //
1090 // Keep track of how much we adjusted up the size on the last
1091 // instance so that when compute the total buffer used, we
1092 // do not include the final size adjustment.
1093 //
1094 lastAdjustment = adjustedSize - tmpSize;
1095
1096 //
1097 // We only write the offset and data if we have not yet
1098 // encountered an instance where the buffer size was too small.
1099 //
1100 if (NT_SUCCESS(status) && tooSmall == FALSE) {
1101 //
1102 // dataBlockOffset is where we are currently at in the buffer
1103 //
1104 pOffsets[i].LengthInstanceData = tmpSize;
1105 pOffsets[i].OffsetInstanceData = dataBlockOffset;
1106
1107 pData += adjustedSize;
1108 }
1109 else {
1110 tooSmall = TRUE;
1111 }
1112
1113 //
1114 // Compute how much buffer we have left and our offset into it.
1115 //
1116 if (adjustedSize <= sizeRemaining) {
1117 sizeRemaining -= adjustedSize;
1118
1119 //
1120 // dataBlockOffset += adjustedSize;
1121 //
1122 addStatus = RtlULongAdd(dataBlockOffset,
1123 adjustedSize,
1124 &dataBlockOffset);
1125 }
1126 else {
1127 //
1128 // dataBlockOffset += sizeRemaining;
1129 //
1130 addStatus = RtlULongAdd(dataBlockOffset,
1131 sizeRemaining,
1132 &dataBlockOffset);
1133 sizeRemaining = 0;
1134 }
1135
1136 if (!NT_SUCCESS(addStatus)) {
1137 status = addStatus;
1139 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
1140 "WDFWMIPROVIDER %p, arithmetic overflow in computing "
1141 "block offset, %!STATUS!", Provider->GetHandle(),
1142 status);
1143 goto QueryError;
1144 }
1145
1146 //
1147 // Compute how much buffer space we have used or require the
1148 // caller to provide. This is just the count of bytes for the
1149 // data queried, it does not yet include the array size required
1150 // to report offset & lengths.
1151 //
1152 // bufferUsed += adjustedSize;
1153 //
1154 addStatus = RtlULongAdd(bufferUsed, adjustedSize, &bufferUsed);
1155
1156 if (!NT_SUCCESS(addStatus)) {
1157 status = addStatus;
1159 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
1160 "WDFWMIPROVIDER %p, arithmetic overflow in computing "
1161 "buffer consumed(%d+%d), %!STATUS!",
1162 Provider->GetHandle(), bufferUsed, adjustedSize, status);
1163 goto QueryError;
1164 }
1165 }
1166 }
1167 else if (pOffsets != NULL) {
1168 //
1169 // Indicate no buffer and the current offset. If there any
1170 // other instances after this one, they will share the same
1171 // offset.
1172 //
1173 pOffsets[i].LengthInstanceData = 0;
1174 pOffsets[i].OffsetInstanceData = dataBlockOffset;
1175 }
1176
1177QueryError:
1178 pInstance->RELEASE(Irp);
1179
1180 //
1181 // We continue on STATUS_BUFFER_TOO_SMALL so that we can ask each
1182 // instance the amount of buffer it needs.
1183 //
1185 break;
1186 }
1187 }
1188
1189 //
1190 // We can have STATUS_BUFFER_TOO_SMALL if the last instance could not fit
1191 // its data into the buffer or have success if the last instance could write
1192 // its data, but a previous instance could not.
1193 //
1194 if (status == STATUS_BUFFER_TOO_SMALL || (NT_SUCCESS(status) && tooSmall)) {
1195 //
1196 // Since we align up the size of each block to MEMORY_ALLOCATION_ALIGNMENT,
1197 // the total buffer size is possibly adjusted up too high. Subtract the
1198 // last adjustment made for alignment when computing the instance size
1199 // so that our total size is not rounded up.
1200 //
1201 // CompleteWmiQueryAllDataRequest will take care of adding enough space
1202 // to the requested size to account for the array of instance offsets
1203 // and lengths.
1204 //
1205 bufferUsed -=lastAdjustment;
1206
1208
1210 This->GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP,
1211 "WDFWMIPROVIDER %p QueryAllData returning %!STATUS!, requesting "
1212 "buffer size of 0x%x", Provider->GetHandle(), status, bufferUsed);
1213 }
1214 else if (NT_SUCCESS(status)) {
1215 //
1216 // Compute the total amount of buffer used. dataBlockOffset is the
1217 // offset of the next instance, which is one past the end, so just
1218 // compute the distance from the start.
1219 //
1220 // Since align up the size of each block to MEMORY_ALLOCATION_ALIGNMENT,
1221 // the total buffer size is possibly adjusted up too high. Subtract the
1222 // last adjustment made for alignment when computing the instance size
1223 // so that our total size is not rounded up.
1224 //
1225 ASSERT(dataBlockOffset >= pNodeData->DataBlockOffset);
1226 ASSERT(dataBlockOffset - pNodeData->DataBlockOffset >= lastAdjustment);
1227 bufferUsed = dataBlockOffset - pNodeData->DataBlockOffset - lastAdjustment;
1228 }
1229 else {
1231 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
1232 "WDFWMIPROVIDER %p QueryAllData returning %!STATUS!",
1233 Provider->GetHandle(), status);
1234
1235 bufferUsed = 0;
1236 }
1237
1239 This->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
1240 "WDFWMIPROVIDER %p QueryAllData returning %!STATUS!, buffer used 0x%x",
1241 Provider->GetHandle(), status, bufferUsed);
1242
1243Done:
1244 status = This->CompleteWmiRequest(Irp, status, bufferUsed);
1245
1246 return status;
1247}
virtual BOOLEAN IsQueryInstanceSupported(VOID)
WDFWMIINSTANCE GetHandle(VOID)
#define TRACINGPNP
Definition: dbgtrace.h:67
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
FxWmiInstanceExternal * pInstance
Definition: fxwmiapi.cpp:113
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MEMORY_ALLOCATION_ALIGNMENT
Definition: ntbasedef.h:90
#define STATUS_WMI_INSTANCE_NOT_FOUND
Definition: ntstatus.h:777
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:385
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
OFFSETINSTANCEDATAANDLENGTH OffsetInstanceDataAndLength[0]
Definition: wmistr.h:119
ULONG InstanceCount
Definition: wmistr.h:114
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:112
ULONG DataBlockOffset
Definition: wmistr.h:113
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PUCHAR
Definition: typedefs.h:53
FORCEINLINE size_t WDF_ALIGN_SIZE_UP(_In_ size_t Length, _In_ size_t AlignTo)
Definition: wdfcore.h:129
struct tagWNODE_ALL_DATA * PWNODE_ALL_DATA

◆ _QuerySingleInstance()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::_QuerySingleInstance ( __in FxWmiIrpHandler This,
__in PIRP  Irp,
__in FxWmiProvider Provider,
__in FxWmiInstance Instance 
)
staticprivate

Definition at line 1251 of file fxwmiirphandler.cpp.

1257{
1258 PWNODE_SINGLE_INSTANCE pSingle;
1262
1263 size = 0;
1264
1266 pSingle = (PWNODE_SINGLE_INSTANCE) stack->Parameters.WMI.Buffer;
1267 bufferSize = stack->Parameters.WMI.BufferSize - pSingle->DataBlockOffset;
1268
1269 if (Instance->IsQueryInstanceSupported() == FALSE) {
1271 }
1272 else if (bufferSize < Provider->GetMinInstanceBufferSize()) {
1273 size = Provider->GetMinInstanceBufferSize();
1275 }
1276 else {
1278 }
1279
1280 if (NT_SUCCESS(status)) {
1281 status = Instance->QueryInstance(
1282 bufferSize,
1283 WDF_PTR_ADD_OFFSET(pSingle, pSingle->DataBlockOffset),
1284 &size
1285 );
1286
1287 pSingle->SizeDataBlock = size;
1288 }
1289
1290 status = This->CompleteWmiRequest(Irp, status, size);
1291
1292 return status;
1293}
size_t bufferSize

◆ _RegInfo()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::_RegInfo ( __in FxWmiIrpHandler This,
__in PIRP  Irp,
__in_opt FxWmiProvider Provider,
__in_opt FxWmiInstance Instance 
)
staticprivate

Definition at line 1566 of file fxwmiirphandler.cpp.

1572{
1574 PUNICODE_STRING pRegPath;
1575 PWMIREGINFO pWmiRegInfo;
1577 PUNICODE_STRING pMofString;
1580 ULONG registryPathOffset, mofResourceOffset, bufferNeeded, information,
1581 bufferSize;
1582 KIRQL irql;
1583
1586
1587 information = 0;
1588
1590 pBuffer = (PUCHAR) stack->Parameters.WMI.Buffer;
1591 bufferSize = stack->Parameters.WMI.BufferSize;
1592
1593 pDevice = This->m_Device;
1594
1595 This->Lock(&irql);
1596
1597 mofResourceOffset = sizeof(WMIREGINFO) +
1598 This->m_NumProviders * sizeof(WMIREGGUIDW);
1599
1600 pMofString = NULL;
1601
1603 pMofString = &pDevice->m_MofResourceName;
1604 }
1605 else {
1606 //
1607 // Start with the parent and iterate up until we hit a device without
1608 // a parent.
1609 //
1611
1612 while (pDevice != NULL) {
1614 pMofString = &pDevice->m_MofResourceName;
1615 break;
1616 }
1617
1618 //
1619 // Advance to the next ancestor
1620 //
1622 }
1623
1624 //
1625 // Restore pDevice back to this device
1626 //
1627 pDevice = This->m_Device;
1628 }
1629
1631
1632 //
1633 // if there is a mof string, add its length. We always need to at least
1634 // add the USHORT to indicate a string of size 0.
1635 //
1636 registryPathOffset = mofResourceOffset + sizeof(USHORT);
1637 if (pMofString != NULL) {
1638 registryPathOffset += pMofString->Length;
1639 }
1640
1641 //
1642 // eventually bufferNeeded = registryPathOffset + pRegPath->Length +
1643 // sizeof(USHORT)
1644 //
1645 status = RtlULongAdd(registryPathOffset, pRegPath->Length, &bufferNeeded);
1646 if (!NT_SUCCESS(status)) {
1647 goto Done;
1648 }
1649
1650 status = RtlULongAdd(bufferNeeded, sizeof(USHORT), &bufferNeeded);
1651 if (!NT_SUCCESS(status)) {
1652 goto Done;
1653 }
1654
1655 if (bufferNeeded <= bufferSize) {
1657 ULONG i;
1658 BOOLEAN addref;
1659
1660 information = bufferNeeded;
1661
1662 pWmiRegInfo = (PWMIREGINFO) pBuffer;
1663 pWmiRegInfo->BufferSize = bufferNeeded;
1664 pWmiRegInfo->NextWmiRegInfo = 0;
1665 pWmiRegInfo->MofResourceName = mofResourceOffset;
1666 pWmiRegInfo->RegistryPath = registryPathOffset;
1667 pWmiRegInfo->GuidCount = This->m_NumProviders;
1668
1670 ? TRUE : FALSE;
1671
1672 for (ple = This->m_ProvidersListHead.Flink, i = 0;
1673 i < This->m_NumProviders;
1674 ple = ple->Flink, i++) {
1675
1676 PWMIREGGUIDW pWmiRegGuid;
1677 PDEVICE_OBJECT pdo;
1679
1681
1682 pWmiRegGuid = &pWmiRegInfo->WmiRegGuid[i];
1683
1684 RtlCopyMemory(&pWmiRegGuid->Guid,
1685 &pProvider->m_Guid,
1686 sizeof(GUID));
1687
1688 pWmiRegGuid->InstanceCount = pProvider->m_NumInstances;
1689
1690 pWmiRegGuid->Flags = pProvider->GetRegistrationFlagsLocked();
1691
1692 pdo = pDevice->GetPhysicalDevice();
1693 pWmiRegGuid->Pdo = (ULONG_PTR) pdo;
1694
1695 if (addref) {
1696 ObReferenceObject(pdo);
1697 }
1698 }
1699 }
1700 else {
1701 *((PULONG) pBuffer) = bufferNeeded;
1702 information = sizeof(ULONG);
1703 }
1704
1705 This->Unlock(irql);
1706
1707 //
1708 // Must copy the strings outside of any lock since they are in paged pool
1709 //
1710 if (bufferNeeded <= bufferSize) {
1711 PUSHORT pLength;
1712
1713 pLength = WDF_PTR_ADD_OFFSET_TYPE(pBuffer, mofResourceOffset, PUSHORT);
1714
1715 if (pMofString != NULL) {
1716 *pLength = pMofString->Length;
1717
1718 RtlCopyMemory(pLength + 1,
1719 pMofString->Buffer,
1720 pMofString->Length);
1721 }
1722 else {
1723 *pLength = 0;
1724 }
1725
1726 pLength = WDF_PTR_ADD_OFFSET_TYPE(pBuffer, registryPathOffset, PUSHORT);
1727
1728 *pLength = pRegPath->Length;
1729 RtlCopyMemory(pLength + 1,
1730 pRegPath->Buffer,
1731 pRegPath->Length);
1732 }
1733
1735
1736Done:
1737 if (!NT_SUCCESS(status)) {
1738 This->Unlock(irql);
1739 }
1740
1741 Irp->IoStatus.Status = status;
1742 Irp->IoStatus.Information = information;
1743
1745
1746 return status;
1747}
__inline FxDriver * GetDriver(VOID)
Definition: fxdevice.hpp:164
MdDeviceObject __inline GetPhysicalDevice(VOID)
Definition: fxdevice.hpp:228
CfxDevice * m_ParentDevice
Definition: fxdevice.hpp:569
UNICODE_STRING m_MofResourceName
Definition: fxdevice.hpp:585
PUNICODE_STRING GetRegistryPathUnicodeString(VOID)
Definition: fxdriver.hpp:243
ULONG GetRegistrationFlagsLocked(VOID)
static PDB_INFORMATION information
Definition: db.cpp:178
#define ULONG_PTR
Definition: config.h:101
FxDevice * pDevice
PSINGLE_LIST_ENTRY ple
FxWmiProvider * pProvider
Definition: fxwmiapi.cpp:54
unsigned short USHORT
Definition: pedump.c:61
PVOID pBuffer
ULONG Flags
Definition: wmistr.h:80
GUID Guid
Definition: wmistr.h:79
ULONG_PTR Pdo
Definition: wmistr.h:86
ULONG InstanceCount
Definition: wmistr.h:81
ULONG BufferSize
Definition: wmistr.h:93
ULONG GuidCount
Definition: wmistr.h:97
ULONG RegistryPath
Definition: wmistr.h:95
ULONG MofResourceName
Definition: wmistr.h:96
ULONG NextWmiRegInfo
Definition: wmistr.h:94
WMIREGGUIDW WmiRegGuid[]
Definition: wmistr.h:98
Definition: typedefs.h:120
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define WDF_PTR_ADD_OFFSET_TYPE(_ptr, _offset, _type)
Definition: wdfcore.h:141
WMIREGINFOW WMIREGINFO
Definition: wmistr.h:101
PWMIREGINFOW PWMIREGINFO
Definition: wmistr.h:102
#define IRP_MN_REGINFO_EX
#define ObReferenceObject
Definition: obfuncs.h:204

◆ AddPowerPolicyProviderAndInstance()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::AddPowerPolicyProviderAndInstance ( __in PWDF_WMI_PROVIDER_CONFIG  ProviderConfig,
__in FxWmiInstanceInternalCallbacks Callbacks,
__inout FxWmiInstanceInternal **  Instance 
)

Definition at line 422 of file fxwmiirphandler.cpp.

427{
431 KIRQL irql;
432 BOOLEAN providerAllocated, providerAdded, update;
433
434 providerAllocated = FALSE;
435 providerAdded = FALSE;
436 update = FALSE;
437
438 pInstance = NULL;
439
441
442 Lock(&irql);
443
444 pProvider = FindProviderLocked(&ProviderConfig->Guid);
445
446 if (pProvider == NULL) {
448 FxWmiProvider(GetDriverGlobals(), ProviderConfig, GetDevice());
449
450 if (pProvider == NULL) {
452 goto Done;
453 }
454
455 providerAllocated = TRUE;
456
458 if (!NT_SUCCESS(status)) {
459 goto Done;
460 }
461
462 providerAdded = TRUE;
463
465 if (!NT_SUCCESS(status)) {
466 goto Done;
467 }
468 }
469 else if (pProvider->m_NumInstances > 0 &&
470 (FxIsEqualGuid(pProvider->GetGUID(), &GUID_POWER_DEVICE_ENABLE) ||
471 FxIsEqualGuid(pProvider->GetGUID(), &GUID_POWER_DEVICE_WAKE_ENABLE))) {
472
474 "WMI Guid already registered by client driver");
476 }
477
478 if (NT_SUCCESS(status)) {
480 FxWmiInstanceInternal(GetDriverGlobals(), InstanceCallbacks, pProvider);
481
482 if (pInstance != NULL) {
484 }
485 else {
487 }
488
489 if (NT_SUCCESS(status) &&
491 pInstance,
492 NULL) != NULL) {
493 //
494 // Some other thread got here first and created an instance, just
495 // bail out. the caller will handle this specific return value
496 // gracefully.
497 //
499 }
500 else {
501 //
502 // We are the first one to set the value, good for us.
503 //
504 DO_NOTHING();
505 }
506 }
507
508 //
509 // Add the instance only if we are successful to this point
510 //
511 if (NT_SUCCESS(status)) {
512 //
513 // Passing FALSE indicates that this instance cannot be in the list
514 // when added.
515 //
517 pInstance,
518 FALSE,
519 &update,
521 );
522 }
523
524Done:
525 if (NT_SUCCESS(status)) {
526 if (update) {
527 update = DeferUpdateLocked(irql);
528 }
529 }
530 else if (providerAdded) {
532 }
533
534 Unlock(irql);
535
536 if (NT_SUCCESS(status)) {
537 if (update) {
538 UpdateGuids();
539 }
540 }
541 else {
542 if (pInstance != NULL) {
544 }
545
546 if (providerAllocated) {
548 }
549 }
550
551 return status;
552}
_Must_inspect_result_ NTSTATUS AssignParentObject(__in FxObject *ParentObject)
Definition: fxobject.cpp:529
virtual VOID DeleteObject(VOID)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
BOOLEAN DeferUpdateLocked(__in KIRQL OldIrql)
VOID RemoveProviderLocked(__in FxWmiProvider *Provider)
VOID UpdateGuids(VOID)
_Must_inspect_result_ FxWmiProvider * FindProviderLocked(__in LPGUID Guid)
_Must_inspect_result_ NTSTATUS AddProviderLocked(__in FxWmiProvider *Provider, __in KIRQL Irql, __out_opt PBOOLEAN Update=NULL)
GUID * GetGUID(VOID)
_Must_inspect_result_ NTSTATUS AddInstanceLocked(__in FxWmiInstance *Instance, __in BOOLEAN NoErrorIfPresent, __out PBOOLEAN Update, __in AddInstanceAction Action=AddInstanceToTail)
#define TRACINGIO
Definition: dbgtrace.h:66
return pList GetDevice()
_Must_inspect_result_ BOOLEAN __inline FxIsEqualGuid(__in CONST GUID *Lhs, __in CONST GUID *Rhs)
Definition: fxglobals.h:977
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define DO_NOTHING()
Definition: mxgeneral.h:32
#define STATUS_WMI_GUID_DISCONNECTED
Definition: ntstatus.h:877
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105

◆ AddProvider()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::AddProvider ( __in FxWmiProvider Provider,
__out_opt PBOOLEAN  Update = NULL 
)

Definition at line 398 of file fxwmiirphandler.cpp.

402{
404 KIRQL irql;
405
406 Lock(&irql);
407
408 if (IsListEmpty(&Provider->m_ListEntry) == FALSE ||
409 FindProviderLocked(Provider->GetGUID()) != NULL) {
411 }
412 else {
414 }
415 Unlock(irql);
416
417 return status;
418}
@ Update
Definition: registry.c:565
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114

Referenced by FxWmiProvider::_Create().

◆ AddProviderLocked()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::AddProviderLocked ( __in FxWmiProvider Provider,
__in KIRQL  Irql,
__out_opt PBOOLEAN  Update = NULL 
)
protected

Definition at line 260 of file fxwmiirphandler.cpp.

265{
266 BOOLEAN update;
267
268 update = FALSE;
269
270 switch (m_RegisteredState) {
271 case WmiRegistered:
272 if (Provider->m_Flags & WdfWmiProviderTracing) {
273 update = TRUE;
274 }
275 case WmiUnregistered:
276 break;
277
278 case WmiDeregistered:
280 }
281
282 //
283 // Didn't find it in the list, add it
284 //
287
288 if (update) {
289 update = DeferUpdateLocked(OldIrql);
290
291 if (Update != NULL) {
292 *Update = update;
293 }
294 }
295
296 return STATUS_SUCCESS;
297}
__in __drv_restoresIRQL KIRQL OldIrql
Definition: fxobject.hpp:1465
#define InsertTailList(ListHead, Entry)
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178

Referenced by AddPowerPolicyProviderAndInstance(), and AddProvider().

◆ CheckAssumptions()

VOID FxWmiIrpHandler::CheckAssumptions ( VOID  )
staticprotected

Definition at line 75 of file fxwmiirphandler.cpp.

78{
81}
static const FxWmiMinorEntry m_WmiDispatchTable[]
#define WDFCASSERT(c)
Definition: wdfassert.h:93

◆ Cleanup()

VOID FxWmiIrpHandler::Cleanup ( VOID  )

Definition at line 216 of file fxwmiirphandler.cpp.

219{
220 KIRQL irql;
221
222 Lock(&irql);
224 Unlock(irql);
225}

◆ CompleteWmiExecuteMethodRequest()

VOID FxWmiIrpHandler::CompleteWmiExecuteMethodRequest ( __in PIRP  Irp,
__in NTSTATUS  Status,
__in ULONG  BufferUsed 
)
private

Definition at line 1838 of file fxwmiirphandler.cpp.

1843{
1844 PWNODE_METHOD_ITEM pNodeMethod;
1845 ULONG bufferNeeded, information;
1846
1847 pNodeMethod = (PWNODE_METHOD_ITEM)
1849
1850 bufferNeeded = pNodeMethod->DataBlockOffset + BufferUsed;
1851
1852 if (NT_SUCCESS(Status)) {
1853 pNodeMethod->WnodeHeader.BufferSize = bufferNeeded;
1854 pNodeMethod->SizeDataBlock = BufferUsed;
1855 KeQuerySystemTime(&pNodeMethod->WnodeHeader.TimeStamp);
1856
1857 information = bufferNeeded;
1858 }
1859 else if (Status == STATUS_BUFFER_TOO_SMALL) {
1860 PWNODE_TOO_SMALL pNodeTooSmall;
1861
1862 pNodeTooSmall = (PWNODE_TOO_SMALL) pNodeMethod;
1863
1864 pNodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
1865 pNodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
1866 pNodeTooSmall->SizeNeeded = bufferNeeded;
1867
1868 information = sizeof(WNODE_TOO_SMALL);
1870 }
1871 else {
1872 information = 0;
1873 }
1874
1875 Irp->IoStatus.Information = information;
1876 Irp->IoStatus.Status = Status;
1877}
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
Status
Definition: gdiplustypes.h:25
union _IO_STACK_LOCATION::@1564 Parameters
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:136
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:52
ULONG SizeNeeded
Definition: wmistr.h:53
_In_ ULONG _Out_ PULONG BufferUsed
Definition: wdfwmi.h:92
#define WNODE_FLAG_TOO_SMALL
Definition: wmistr.h:33
struct tagWNODE_TOO_SMALL * PWNODE_TOO_SMALL
struct tagWNODE_TOO_SMALL WNODE_TOO_SMALL

Referenced by CompleteWmiRequest().

◆ CompleteWmiQueryAllDataRequest()

VOID FxWmiIrpHandler::CompleteWmiQueryAllDataRequest ( __in PIRP  Irp,
__in NTSTATUS  Status,
__in ULONG  BufferUsed 
)
private

Definition at line 1750 of file fxwmiirphandler.cpp.

1755{
1756 PWNODE_ALL_DATA pNodeAllData;
1757 ULONG bufferNeeded, information;
1759
1761
1762 pNodeAllData = (PWNODE_ALL_DATA) stack->Parameters.WMI.Buffer;
1763 bufferNeeded = pNodeAllData->DataBlockOffset + BufferUsed;
1764
1765 if (NT_SUCCESS(Status) && bufferNeeded > stack->Parameters.WMI.BufferSize) {
1767 }
1768
1769 if (NT_SUCCESS(Status)) {
1770 KeQuerySystemTime(&pNodeAllData->WnodeHeader.TimeStamp);
1771
1772 pNodeAllData->WnodeHeader.BufferSize = bufferNeeded;
1773 information = bufferNeeded;
1774 }
1775 else if (Status == STATUS_BUFFER_TOO_SMALL) {
1776 PWNODE_TOO_SMALL pNodeTooSmall;
1777
1778 pNodeTooSmall = (PWNODE_TOO_SMALL) stack->Parameters.WMI.Buffer;
1779
1780 pNodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
1781 pNodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
1782 pNodeTooSmall->SizeNeeded = bufferNeeded;
1783
1784 information = sizeof(WNODE_TOO_SMALL);
1786 }
1787 else {
1788 information = 0;
1789 }
1790
1791 Irp->IoStatus.Information = information;
1792 Irp->IoStatus.Status = Status;
1793}

Referenced by CompleteWmiRequest().

◆ CompleteWmiQuerySingleInstanceRequest()

VOID FxWmiIrpHandler::CompleteWmiQuerySingleInstanceRequest ( __in PIRP  Irp,
__in NTSTATUS  Status,
__in ULONG  BufferUsed 
)
private

Definition at line 1796 of file fxwmiirphandler.cpp.

1801{
1802 PWNODE_SINGLE_INSTANCE pNodeSingle;
1803 ULONG bufferNeeded, information;
1804
1805 pNodeSingle = (PWNODE_SINGLE_INSTANCE)
1807
1808 bufferNeeded = pNodeSingle->DataBlockOffset + BufferUsed;
1809
1810 if (NT_SUCCESS(Status)) {
1811 pNodeSingle->WnodeHeader.BufferSize = bufferNeeded;
1812 KeQuerySystemTime(&pNodeSingle->WnodeHeader.TimeStamp);
1813
1814 ASSERT(pNodeSingle->SizeDataBlock <= BufferUsed);
1815 information = bufferNeeded;
1816 }
1817 else if (Status == STATUS_BUFFER_TOO_SMALL) {
1818 PWNODE_TOO_SMALL pNodeTooSmall;
1819
1820 pNodeTooSmall = (PWNODE_TOO_SMALL) pNodeSingle;
1821
1822 pNodeTooSmall->WnodeHeader.BufferSize = sizeof(WNODE_TOO_SMALL);
1823 pNodeTooSmall->WnodeHeader.Flags = WNODE_FLAG_TOO_SMALL;
1824 pNodeTooSmall->SizeNeeded = bufferNeeded;
1825
1826 information = sizeof(WNODE_TOO_SMALL);
1828 }
1829 else {
1830 information = 0;
1831 }
1832
1833 Irp->IoStatus.Information = information;
1834 Irp->IoStatus.Status = Status;
1835}
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:58

Referenced by CompleteWmiRequest().

◆ CompleteWmiRequest()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::CompleteWmiRequest ( __in PIRP  Irp,
__in NTSTATUS  Status,
__in ULONG  BufferUsed 
)
private

Definition at line 1881 of file fxwmiirphandler.cpp.

1911{
1915 break;
1916
1919 break;
1920
1923 break;
1924
1927 //
1928 // Lot's of drivers return STATUS_BUFFER_TOO_SMALL for an invalid buffer
1929 // size. WMI expects STATUS_WMI_SET_FAILURE in this case. Change the
1930 // Status to the expected value. No way to return any size in
1931 // Information, the buffer is input only.
1932 //
1936 "Converting %!STATUS! to %!STATUS!",
1939 }
1940 // || || Fall through || ||
1941 // \/ \/ \/ \/
1942
1943 default:
1944 //
1945 // All other requests don't return any data
1946 //
1947 Irp->IoStatus.Status = Status;
1948 Irp->IoStatus.Information = 0;
1949 break;
1950 }
1951
1952 //
1953 // One of the complete functions may have morphed the status value
1954 //
1955 Status = Irp->IoStatus.Status;
1957
1958 return Status;
1959}
VOID CompleteWmiExecuteMethodRequest(__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
VOID CompleteWmiQueryAllDataRequest(__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
VOID CompleteWmiQuerySingleInstanceRequest(__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
#define STATUS_WMI_SET_FAILURE
Definition: ntstatus.h:819
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1699
#define IRP_MN_EXECUTE_METHOD
#define IRP_MN_CHANGE_SINGLE_ITEM
#define IRP_MN_QUERY_ALL_DATA
#define IRP_MN_CHANGE_SINGLE_INSTANCE
#define IRP_MN_QUERY_SINGLE_INSTANCE

◆ DecrementUpdateCount()

VOID FxWmiIrpHandler::DecrementUpdateCount ( )
inlineprivate

Definition at line 274 of file fxwmiirphandler.hpp.

274 {
275 LONG count;
276
278 ASSERT(count >= 0);
279 if (count == 0) {
281 }
282 }
#define InterlockedDecrement
Definition: armddk.h:52
GLuint GLuint GLsizei count
Definition: gl.h:1545
long LONG
Definition: pedump.c:60
VOID Set(VOID)
Definition: fxwaitlock.hpp:144

Referenced by FxWmiProvider::_Create(), DecrementUpdateCountAndWait(), and UpdateGuids().

◆ DecrementUpdateCountAndWait()

VOID FxWmiIrpHandler::DecrementUpdateCountAndWait ( )
inlineprivate

Definition at line 285 of file fxwmiirphandler.hpp.

285 {
286
288
290 }
NTSTATUS EnterCRAndWaitAndLeave(VOID)
Definition: fxwaitlock.hpp:87

Referenced by Deregister().

◆ DeferUpdateLocked()

BOOLEAN FxWmiIrpHandler::DeferUpdateLocked ( __in KIRQL  OldIrql)
private

Definition at line 300 of file fxwmiirphandler.cpp.

303{
304 BOOLEAN checkQueue;
305
306 checkQueue = FALSE;
307
308 //
309 // Check to see if the caller is going to return to something > PASSIVE_LEVEL.
310 // If so, then always defer to the workitem.
311 //
312 if (OldIrql > PASSIVE_LEVEL) {
313 checkQueue = TRUE;
314 }
315 else {
316 //
317 // At passive level and updates are allowed, indicate to the caller to
318 // update. The caller will do registration update outside of lock but
319 // update count needs to be incremented under lock, so this is done here.
320 //
322 return TRUE;
323 }
324
325 if (checkQueue && m_WorkItemQueued == FALSE) {
326 //
327 // we are going to queue a workitem which will do registration update,
328 // so increment the update count. Note that one work item may correspond
329 // to multiple requests to update (since if the workitem is already
330 // queued, it's not queued again).
331 //
333
338 this);
339 }
340
341 return FALSE;
342}
static MX_WORKITEM_ROUTINE _UpdateGuids
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
@ DelayedWorkQueue
Definition: extypes.h:190

Referenced by FxWmiProvider::AddInstance(), AddPowerPolicyProviderAndInstance(), AddProviderLocked(), and FxWmiProvider::RemoveInstance().

◆ Deregister()

VOID FxWmiIrpHandler::Deregister ( VOID  )

Definition at line 162 of file fxwmiirphandler.cpp.

165{
167 KIRQL irql;
168 BOOLEAN call;
169
170 call = FALSE;
171
172 Lock(&irql);
175
176 if (m_WorkItemQueued) {
177
178
179
180
181
182 m_WorkItemEvent = (PKEVENT)event.GetEvent();
183 }
184
185 call = TRUE;
186 }
187 Unlock(irql);
188
189 if (m_WorkItemEvent != NULL) {
190 event.EnterCRAndWaitAndLeave();
191 }
192
193 if (call) {
195
196 //
197 // Per WMI rules, there should not be any call to update WMI
198 // registration after we have deregistered because that can lead to
199 // deadlock in Pnp, so before we go ahead to deregister, let's ensure
200 // that. This will wait for any pending updates to happen.
201 //
203
206
207 if (!NT_SUCCESS(status)) {
210 "failure deregistering WMI with OS, %!STATUS!", status);
211 }
212 }
213}
VOID DecrementUpdateCountAndWait()
#define PKEVENT
Definition: env_spec_w32.h:70
return pDevice GetDeviceObject()
struct _cl_event * event
Definition: glext.h:7739
NTSTATUS NTAPI IoWMIRegistrationControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG Action)
Definition: wmi.c:68
#define WMIREG_ACTION_DEREGISTER

◆ Dispatch()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::Dispatch ( __in PIRP  Irp)
virtual

Definition at line 632 of file fxwmiirphandler.cpp.

635{
640 PDEVICE_OBJECT pAttached;
642 PVOID pTag;
643 ULONG instanceIndex;
644 KIRQL irql;
645 BOOLEAN handled, completeNow;
646 UCHAR minor;
647
649
651
653 minor = stack->MinorFunction;
654 pTag = UlongToPtr(minor);
655 status = Irp->IoStatus.Status;
656
657 pProvider = NULL;
658 pInstance = NULL;
659
660 handled = FALSE;
661 completeNow = FALSE;
662
665 "WDFDEVICE 0x%p !devobj 0x%p IRP_MJ_SYSTEM_CONTROL, %!sysctrl! IRP 0x%p",
667
668 //
669 // Verify the minor code is within range, there is hole in the table at 0xA.
670 // This check works around the hole in the table.
671 //
673 goto Done;
674 }
675
676 //
677 // If the irp is not targetted at this device, send it down the stack
678 //
679 if (stack->Parameters.WMI.ProviderId != (UINT_PTR) m_Device->GetDeviceObject()) {
680 goto Done;
681 }
682
685 }
686 else {
687 Lock(&irql);
688
689 pProvider = FindProviderLocked((LPGUID)stack->Parameters.WMI.DataPath);
690
691 if (pProvider != NULL) {
693 }
694 else {
695 //
696 // check for WMI tracing (no pProvider)
697 //
699 }
700
701 if (NT_SUCCESS(status) && m_WmiDispatchTable[minor].CheckInstance) {
703
704 pSingle = (PWNODE_SINGLE_INSTANCE) stack->Parameters.WMI.Buffer;
705
706 instanceIndex = pSingle->InstanceIndex;
707
708 //
709 // Also possible bits set in Flags related to instance names
710 // WNODE_FLAG_PDO_INSTANCE_NAMES
711 //
713 //
714 // Try to get the instance
715 //
717 instanceIndex, pTag);
718
719 if (pInstance == NULL) {
721 }
722 }
723 else {
724
725
726
727
728
729
731 }
732 }
733
734 if (NT_SUCCESS(status)) {
735 pProvider->ADDREF(pTag);
736 }
737 else {
738 //
739 // NULL out the provider so we don't deref it later. We could not
740 // use if (pProvider != NULL && NT_SUCCESS(status) in the Done: block
741 // because we could have success here, but the dispatch function
742 // returns error.
743 //
744 pProvider = NULL;
745 }
746
747 Unlock(irql);
748
749 if (!NT_SUCCESS(status)) {
750 Irp->IoStatus.Status = status;
751 completeNow = TRUE;
752 }
753 }
754
757 Irp,
758 pProvider,
759 pInstance);
760 handled = TRUE;
761 }
762
763Done:
764 if (pInstance != NULL) {
765 pInstance->RELEASE(pTag);
766 pInstance = NULL;
767 }
768
769 if (pProvider != NULL) {
770 pProvider->RELEASE(pTag);
771 pProvider = NULL;
772 }
773
774 if (handled == FALSE) {
775 pAttached = m_Device->GetAttachedDevice();
776 if (completeNow || pAttached == NULL) {
777 //
778 // Sent to a PDO, error in the FDO handling, or controller devobj
779 // style devobj, complete it here
780 //
781 status = Irp->IoStatus.Status;
783 }
784 else {
785 //
786 // Request sent to PNP device object that is not a PDO, send down
787 // the stack
788 //
790 status = IoCallDriver(pAttached, Irp);
791 }
792 }
793
794 //
795 // Only release the remove lock *after* we have removed the thread entry
796 // from the list because the list lifetime is tied to the FxDevice lifetime
797 // and the remlock controls the lifetime of FxDevice.
798 //
799 // Since we never pend the wmi request, we can release the remove lock in
800 // this Dispatch routine. If we ever pended the IRPs, this would have to
801 // have some more logic involved.
802 //
805 Irp
806 );
807
808 return status;
809}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER Handler
Definition: acpixf.h:672
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
MdDeviceObject __inline GetAttachedDevice(VOID)
Definition: fxdevice.hpp:210
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
static FxWdmDeviceExtension * _GetFxWdmExtension(__in MdDeviceObject DeviceObject)
Definition: fxdevicekm.hpp:30
CfxDevice * m_Device
Definition: fxobject.hpp:329
_Must_inspect_result_ FxWmiInstance * GetInstanceReferencedLocked(__in ULONG Index, __in PVOID Tag)
#define UlongToPtr(u)
Definition: config.h:106
PFX_DRIVER_GLOBALS pFxDriverGlobals
FX_TRACK_DRIVER(fxDriverGlobals)
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_WMI_GUID_NOT_FOUND
Definition: ntstatus.h:776
#define minor(rdev)
Definition: propsheet.cpp:929
WUDF_IO_REMOVE_LOCK IoRemoveLock
Definition: fxdevice.hpp:34
__in PFN_WMI_HANDLER_MINOR_DISPATCH Handler
#define WNODE_FLAG_STATIC_INSTANCE_NAMES
Definition: wmistr.h:35
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
#define IRP_MN_REGINFO
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ FindProviderLocked()

_Must_inspect_result_ FxWmiProvider * FxWmiIrpHandler::FindProviderLocked ( __in LPGUID  Guid)
protected

Definition at line 582 of file fxwmiirphandler.cpp.

585{
586 FxWmiProvider* pFound;
588
589 pFound = NULL;
590
593 ple = ple->Flink) {
594
596
598
600 Guid,
601 sizeof(GUID)) == sizeof(GUID)) {
602 pFound = pProvider;
603 break;
604 }
605 }
606
607 return pFound;
608}
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762

Referenced by AddPowerPolicyProviderAndInstance(), AddProvider(), Dispatch(), and FindProviderReferenced().

◆ FindProviderReferenced()

_Must_inspect_result_ FxWmiProvider * FxWmiIrpHandler::FindProviderReferenced ( __in LPGUID  Guid,
__in PVOID  Tag 
)
protected

Definition at line 612 of file fxwmiirphandler.cpp.

616{
618 KIRQL irql;
619
620 Lock(&irql);
622 if (pProvider != NULL) {
623 pProvider->ADDREF(Tag);
624 }
625 Unlock(irql);
626
627 return pProvider;
628}
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065

◆ HandleWmiTraceRequest()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::HandleWmiTraceRequest ( __in PIRP  Irp,
__in FxTraceInfo Info 
)

◆ IncrementUpdateCount()

VOID FxWmiIrpHandler::IncrementUpdateCount ( )
inlineprivate

Definition at line 265 of file fxwmiirphandler.hpp.

265 {
266 LONG count;
267
269 ASSERT(count > 1);
271 }
#define InterlockedIncrement
Definition: armddk.h:53

Referenced by DeferUpdateLocked().

◆ PostCreateDeviceInitialize()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::PostCreateDeviceInitialize ( VOID  )

Definition at line 114 of file fxwmiirphandler.cpp.

117{
119 if (m_WorkItem == NULL) {
121 }
122
123 return STATUS_SUCCESS;
124}
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75

◆ Register()

_Must_inspect_result_ NTSTATUS FxWmiIrpHandler::Register ( VOID  )

Definition at line 128 of file fxwmiirphandler.cpp.

131{
133 KIRQL irql;
134
135 //
136 // We rely on the PnP state machine to manage our state transitions properly
137 // so that we don't have to do any state checking here.
138 //
139 Lock(&irql);
143 Unlock(irql);
144
147
148 if (!NT_SUCCESS(status)) {
151 "could not register WMI with OS, %!STATUS!", status);
152
153 Lock(&irql);
155 Unlock(irql);
156 }
157
158 return status;
159}
#define WMIREG_ACTION_REGISTER

◆ RemoveProvider()

VOID FxWmiIrpHandler::RemoveProvider ( __in FxWmiProvider Provider)
protected

Definition at line 555 of file fxwmiirphandler.cpp.

558{
559 KIRQL irql;
560
561 //
562 // No need to update via IoWMIRegistrationControl because this is only
563 // called in the error path of creating a provider.
564 //
565 Lock(&irql);
567 Unlock(irql);
568}

Referenced by FxWmiProvider::_Create(), and FxWmiProvider::Dispose().

◆ RemoveProviderLocked()

VOID FxWmiIrpHandler::RemoveProviderLocked ( __in FxWmiProvider Provider)
protected

Definition at line 571 of file fxwmiirphandler.cpp.

574{
576 RemoveEntryList(&Provider->m_ListEntry);
577 InitializeListHead(&Provider->m_ListEntry);
578}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986

Referenced by AddPowerPolicyProviderAndInstance(), and RemoveProvider().

◆ ResetStateForPdoRestart()

VOID FxWmiIrpHandler::ResetStateForPdoRestart ( VOID  )

Definition at line 228 of file fxwmiirphandler.cpp.

231{
232 KIRQL irql;
233
234 Lock(&irql);
235
236 //
237 // We can reach this state in 2 ways:
238 // 1. PDO went through Init->Started->Removed->Started transition
239 // 2. PDO went through Init-><SomeFailedState>->Started state (e.g.
240 // Init->Ejected->EjectFailed->Started) transition.
241 //
242 // So, WMI registration state would either be Deregistered due to #1
243 // or, Unregistered due to #2. Also, update count would be 0 in case of #1
244 // and 1 in case of #2.
245 //
248 ASSERT(m_UpdateCount == 0 || m_UpdateCount == 1);
249
250 //
251 // Update count is biased to 1 when created so do the same here.
252 //
253 m_UpdateCount = 1;
255 Unlock(irql);
256}
CHECK_RETURN_IF_USER_MODE NTSTATUS Initialize(__in BOOLEAN InitialState=FALSE)
Definition: fxwaitlock.hpp:51

◆ UpdateGuids()

VOID FxWmiIrpHandler::UpdateGuids ( VOID  )
private

Definition at line 369 of file fxwmiirphandler.cpp.

372{
374
377
378 if (!NT_SUCCESS(status)) {
381 "IoWMIRegistrationControl DevObj %p, for UpdateGuids failed, %!STATUS!",
383
384 //
385 // Just drop the error
386 //
387 }
388
389 //
390 // The caller incremented the update count when it decided to do the update.
391 // Decrement the count now that we have completed registration update.
392 //
394}
#define WMIREG_ACTION_UPDATE_GUIDS

Referenced by FxWmiProvider::_Create(), FxWmiProvider::AddInstance(), AddPowerPolicyProviderAndInstance(), and FxWmiProvider::RemoveInstance().

Member Data Documentation

◆ _UpdateGuids

VOID FxWmiIrpHandler::_UpdateGuids
staticprivate

Definition at line 257 of file fxwmiirphandler.hpp.

Referenced by DeferUpdateLocked().

◆ FxWmiProvider

friend FxWmiIrpHandler::FxWmiProvider
private

Definition at line 45 of file fxwmiirphandler.hpp.

Referenced by AddPowerPolicyProviderAndInstance().

◆ m_NumProviders

ULONG FxWmiIrpHandler::m_NumProviders
protected

Definition at line 305 of file fxwmiirphandler.hpp.

Referenced by _RegInfo(), AddProviderLocked(), and RemoveProviderLocked().

◆ m_ProvidersListHead

LIST_ENTRY FxWmiIrpHandler::m_ProvidersListHead
protected

◆ m_RegisteredState

◆ m_UpdateCount

LONG FxWmiIrpHandler::m_UpdateCount
protected

◆ m_UpdateEvent

FxCREvent FxWmiIrpHandler::m_UpdateEvent
protected

◆ m_WmiDispatchTable

const FxWmiMinorEntry FxWmiIrpHandler::m_WmiDispatchTable
staticprotected

Definition at line 301 of file fxwmiirphandler.hpp.

Referenced by CheckAssumptions(), and Dispatch().

◆ m_WorkItem

PIO_WORKITEM FxWmiIrpHandler::m_WorkItem
protected

◆ m_WorkItemEvent

PKEVENT FxWmiIrpHandler::m_WorkItemEvent
protected

Definition at line 322 of file fxwmiirphandler.hpp.

Referenced by Deregister().

◆ m_WorkItemQueued

BOOLEAN FxWmiIrpHandler::m_WorkItemQueued
protected

Definition at line 324 of file fxwmiirphandler.hpp.

Referenced by DeferUpdateLocked(), and Deregister().


The documentation for this class was generated from the following files: