ReactOS 0.4.15-dev-8138-g1e75ea8
fxwmiirphandler.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxWmiIrpHandler.cpp
8
9Abstract:
10
11 This module implements the wmi irp handler for the driver frameworks.
12
13Author:
14
15
16
17Environment:
18
19 Kernel mode only
20
21Revision History:
22
23--*/
24
25#include "fxwmipch.hpp"
26
27extern "C" {
28// #include "FxWmiIrpHandler.tmh"
29}
30
31#ifndef WppDebug
32#define WppDebug(a, b)
33#endif
34
36{
37 // IRP_MN_QUERY_ALL_DATA
38 { _QueryAllData, FALSE },
39
40 // IRP_MN_QUERY_SINGLE_INSTANCE
41 { _QuerySingleInstance, TRUE },
42
43 // IRP_MN_CHANGE_SINGLE_INSTANCE
44 { _ChangeSingleInstance, TRUE },
45
46 // IRP_MN_CHANGE_SINGLE_ITEM
47 { _ChangeSingleItem, TRUE },
48
49 // IRP_MN_ENABLE_EVENTS
50 { _EnableDisableEventsAndCollection, FALSE },
51
52 // IRP_MN_DISABLE_EVENTS
53 { _EnableDisableEventsAndCollection, FALSE },
54
55 // IRP_MN_ENABLE_COLLECTION
56 { _EnableDisableEventsAndCollection, FALSE },
57
58 // IRP_MN_DISABLE_COLLECTION
59 { _EnableDisableEventsAndCollection, FALSE },
60
61 // IRP_MN_REGINFO
62 { _RegInfo, FALSE },
63
64 // IRP_MN_EXECUTE_METHOD
65 { _ExecuteMethod, TRUE },
66
67 // 0xA is reseverved
68 { NULL, FALSE },
69
70 // IRP_MN_REGINFO_EX
71 { _RegInfo, FALSE },
72};
73
74VOID
76 VOID
77 )
78{
81}
82
84 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
87 ) :
88 FxPackage(FxDriverGlobals, Device, Type),
89 m_NumProviders(0), m_RegisteredState(WmiUnregistered),
90 m_WorkItem(NULL), m_WorkItemEvent(NULL), m_WorkItemQueued(FALSE),
91 m_UpdateCount(1) // bias m_UpdateCount to 1, Deregister routine will
92 // decrement this.
93{
95}
96
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}
111
115 VOID
116 )
117{
119 if (m_WorkItem == NULL) {
121 }
122
123 return STATUS_SUCCESS;
124}
125
129 VOID
130 )
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}
160
161VOID
163 VOID
164 )
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}
214
215VOID
217 VOID
218 )
219{
220 KIRQL irql;
221
222 Lock(&irql);
224 Unlock(irql);
225}
226
227VOID
229 VOID
230 )
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}
257
264 )
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}
298
302 )
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}
343
344VOID
348 )
349{
350 FxWmiIrpHandler* pThis;
351 KIRQL irql;
352
354
355 pThis = (FxWmiIrpHandler*)Context;
356
357 pThis->UpdateGuids();
358
359 pThis->Lock(&irql);
360 pThis->m_WorkItemQueued = FALSE;
361
362 if (pThis->m_WorkItemEvent != NULL) {
364 }
365 pThis->Unlock(irql);
366}
367
368VOID
370 VOID
371 )
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}
395
401 )
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}
419
423 __in PWDF_WMI_PROVIDER_CONFIG ProviderConfig,
424 __in FxWmiInstanceInternalCallbacks* InstanceCallbacks,
426 )
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}
553
554VOID
557 )
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}
569
570VOID
573 )
574{
576 RemoveEntryList(&Provider->m_ListEntry);
577 InitializeListHead(&Provider->m_ListEntry);
578}
579
584 )
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}
609
615 )
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}
629
634 )
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}
810
815 __in PIRP Irp,
818 )
819/*++
820
821Routine Description:
822 Handles querying all instances for data. In the case where there is not
823 enough space in the buffer, we query each instance for the required amount
824 of buffer space and report that.
825
826Arguments:
827 This - device instance
828
829 Irp - WMI request for query all data
830
831 Providre - the provider being queried
832
833 Instance - ignored, NULL
834
835Return Value:
836 STATUS_BUFFER_TOO_SMALL in case the buffer is not large enough
837 STATUS_SUCCESS on a successful query
838 or other values depending on the client driver
839
840 --*/
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}
1248
1253 __in PIRP Irp,
1256 )
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}
1294
1299 __in PIRP Irp,
1302 )
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}
1345
1350 __in PIRP Irp,
1353 )
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}
1392
1397 __in PIRP Irp,
1400 )
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}
1496
1501 __in PIRP Irp,
1504 )
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}
1563
1568 __in PIRP Irp,
1571 )
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}
1748
1749VOID
1751 __in PIRP Irp,
1754 )
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}
1794
1795VOID
1797 __in PIRP Irp,
1800 )
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}
1836
1837VOID
1839 __in PIRP Irp,
1842 )
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}
1878
1882 __in PIRP Irp,
1885 )
1886/*++
1887
1888Routine Description:
1889 This routine will do the work of completing a WMI irp. Depending upon the
1890 the WMI request this routine will fixup the returned WNODE appropriately.
1891
1892 This may be called at DPC level
1893
1894Arguments:
1895
1896 Irp - Supplies the Irp making the request.
1897
1898 Status has the return status code for the IRP
1899
1900 BufferUsed has the number of bytes needed by the device to return the
1901 data requested in any query. In the case that the buffer passed to
1902 the device is too small this has the number of bytes needed for the
1903 return data. If the buffer passed is large enough then this has the
1904 number of bytes actually used by the device.
1905
1906Return Value:
1907
1908 status
1909
1910--*/
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}
1960
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
Type
Definition: Type.h:7
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
LONG NTSTATUS
Definition: precomp.h:26
@ Update
Definition: registry.c:565
__inline FxDriver * GetDriver(VOID)
Definition: fxdevice.hpp:164
MdDeviceObject __inline GetPhysicalDevice(VOID)
Definition: fxdevice.hpp:228
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
MdDeviceObject __inline GetAttachedDevice(VOID)
Definition: fxdevice.hpp:210
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
CfxDevice * m_ParentDevice
Definition: fxdevice.hpp:569
UNICODE_STRING m_MofResourceName
Definition: fxdevice.hpp:585
static FxWdmDeviceExtension * _GetFxWdmExtension(__in MdDeviceObject DeviceObject)
Definition: fxdevicekm.hpp:30
PUNICODE_STRING GetRegistryPathUnicodeString(VOID)
Definition: fxdriver.hpp:243
_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
CfxDevice * m_Device
Definition: fxobject.hpp:329
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
__in __drv_restoresIRQL KIRQL OldIrql
Definition: fxobject.hpp:1465
virtual BOOLEAN IsQueryInstanceSupported(VOID)
WDFWMIINSTANCE GetHandle(VOID)
BOOLEAN DeferUpdateLocked(__in KIRQL OldIrql)
static MX_WORKITEM_ROUTINE _UpdateGuids
_Must_inspect_result_ FxWmiProvider * FindProviderReferenced(__in LPGUID Guid, __in PVOID Tag)
virtual _Must_inspect_result_ NTSTATUS Dispatch(__in PIRP Irp)
VOID RemoveProvider(__in FxWmiProvider *Provider)
static VOID CheckAssumptions(VOID)
static _Must_inspect_result_ NTSTATUS _ExecuteMethod(__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in FxWmiInstance *Instance)
VOID CompleteWmiExecuteMethodRequest(__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
PIO_WORKITEM m_WorkItem
_Must_inspect_result_ NTSTATUS AddProvider(__in FxWmiProvider *Provider, __out_opt PBOOLEAN Update=NULL)
LIST_ENTRY m_ProvidersListHead
WmiRegisteredState m_RegisteredState
VOID RemoveProviderLocked(__in FxWmiProvider *Provider)
static _Must_inspect_result_ NTSTATUS _RegInfo(__in FxWmiIrpHandler *This, __in PIRP Irp, __in_opt FxWmiProvider *Provider, __in_opt FxWmiInstance *Instance)
_Must_inspect_result_ NTSTATUS AddPowerPolicyProviderAndInstance(__in PWDF_WMI_PROVIDER_CONFIG ProviderConfig, __in FxWmiInstanceInternalCallbacks *Callbacks, __inout FxWmiInstanceInternal **Instance)
VOID UpdateGuids(VOID)
static _Must_inspect_result_ NTSTATUS _ChangeSingleInstance(__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in FxWmiInstance *Instance)
_Must_inspect_result_ FxWmiProvider * FindProviderLocked(__in LPGUID Guid)
static _Must_inspect_result_ NTSTATUS _QueryAllData(__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in_opt FxWmiInstance *Instance)
static _Must_inspect_result_ NTSTATUS _ChangeSingleItem(__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in FxWmiInstance *Instance)
static const FxWmiMinorEntry m_WmiDispatchTable[]
FxWmiIrpHandler(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device, __in WDFTYPE Type=FX_TYPE_WMI_IRP_HANDLER)
_Must_inspect_result_ NTSTATUS PostCreateDeviceInitialize(VOID)
static _Must_inspect_result_ NTSTATUS _EnableDisableEventsAndCollection(__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in FxWmiInstance *Instance)
_Must_inspect_result_ NTSTATUS Register(VOID)
VOID CompleteWmiQueryAllDataRequest(__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
VOID DecrementUpdateCountAndWait()
_Must_inspect_result_ NTSTATUS AddProviderLocked(__in FxWmiProvider *Provider, __in KIRQL Irql, __out_opt PBOOLEAN Update=NULL)
VOID ResetStateForPdoRestart(VOID)
static _Must_inspect_result_ NTSTATUS _QuerySingleInstance(__in FxWmiIrpHandler *This, __in PIRP Irp, __in FxWmiProvider *Provider, __in FxWmiInstance *Instance)
_Must_inspect_result_ NTSTATUS CompleteWmiRequest(__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
VOID CompleteWmiQuerySingleInstanceRequest(__in PIRP Irp, __in NTSTATUS Status, __in ULONG BufferUsed)
GUID * GetGUID(VOID)
_Must_inspect_result_ FxWmiInstance * GetInstanceReferencedLocked(__in ULONG Index, __in PVOID Tag)
_Must_inspect_result_ NTSTATUS AddInstanceLocked(__in FxWmiInstance *Instance, __in BOOLEAN NoErrorIfPresent, __out PBOOLEAN Update, __in AddInstanceAction Action=AddInstanceToTail)
ULONG GetRegistrationFlagsLocked(VOID)
Definition: _stack.h:55
_In_ PIRP Irp
Definition: csq.h:116
static PDB_INFORMATION information
Definition: db.cpp:178
#define __out_opt
Definition: dbghelp.h:65
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define __in_opt
Definition: dbghelp.h:38
#define TRACINGIO
Definition: dbgtrace.h:66
#define TRACINGPNP
Definition: dbgtrace.h:67
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
KIRQL irql
Definition: wave.h:1
#define UlongToPtr(u)
Definition: config.h:106
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define PKEVENT
Definition: env_spec_w32.h:70
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
FxDevice * pDevice
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
return pList GetDevice()
PFX_DRIVER_GLOBALS pFxDriverGlobals
return pDevice GetDeviceObject()
FX_TRACK_DRIVER(fxDriverGlobals)
PSINGLE_LIST_ENTRY ple
_Must_inspect_result_ BOOLEAN __inline FxIsEqualGuid(__in CONST GUID *Lhs, __in CONST GUID *Rhs)
Definition: fxglobals.h:977
USHORT WDFTYPE
Definition: fxtypes.h:29
size_t bufferSize
FxWmiProvider * pProvider
Definition: fxwmiapi.cpp:54
FxWmiInstanceExternal * pInstance
Definition: fxwmiapi.cpp:113
Status
Definition: gdiplustypes.h:25
GLsizeiptr size
Definition: glext.h:5919
struct _cl_event * event
Definition: glext.h:7739
GLboolean enable
Definition: glext.h:11120
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 InterlockedCompareExchangePointer
Definition: interlocked.h:129
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: ms_sal.h:558
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define DO_NOTHING()
Definition: mxgeneral.h:32
#define MEMORY_ALLOCATION_ALIGNMENT
Definition: ntbasedef.h:90
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
NTSTATUS NTAPI IoWMIRegistrationControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG Action)
Definition: wmi.c:68
#define STATUS_WMI_GUID_DISCONNECTED
Definition: ntstatus.h:877
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
#define STATUS_WMI_SET_FAILURE
Definition: ntstatus.h:819
#define STATUS_WMI_INSTANCE_NOT_FOUND
Definition: ntstatus.h:777
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_WMI_GUID_NOT_FOUND
Definition: ntstatus.h:776
#define STATUS_WMI_READ_ONLY
Definition: ntstatus.h:818
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:385
unsigned short USHORT
Definition: pedump.c:61
#define minor(rdev)
Definition: propsheet.cpp:929
PVOID pBuffer
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
CHECK_RETURN_IF_USER_MODE NTSTATUS Initialize(__in BOOLEAN InitialState=FALSE)
Definition: fxwaitlock.hpp:51
WUDF_IO_REMOVE_LOCK IoRemoveLock
Definition: fxdevice.hpp:34
__in PFN_WMI_HANDLER_MINOR_DISPATCH Handler
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
struct _IO_STACK_LOCATION::@3983::@4021 WMI
union _IO_STACK_LOCATION::@1568 Parameters
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: ps.c:97
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
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:136
ULONG DataBlockOffset
Definition: wmistr.h:140
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:58
ULONG DataBlockOffset
Definition: wmistr.h:129
struct _WNODE_HEADER WnodeHeader
Definition: wmistr.h:52
ULONG SizeNeeded
Definition: wmistr.h:53
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
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
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WDFCASSERT(c)
Definition: wdfassert.h:93
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define WDF_PTR_ADD_OFFSET_TYPE(_ptr, _offset, _type)
Definition: wdfcore.h:141
FORCEINLINE size_t WDF_ALIGN_SIZE_UP(_In_ size_t Length, _In_ size_t AlignTo)
Definition: wdfcore.h:129
#define WDF_PTR_ADD_OFFSET(_ptr, _offset)
Definition: wdfcore.h:144
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1699
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
_In_ ULONG _Out_ PULONG BufferUsed
Definition: wdfwmi.h:92
@ WdfWmiEventControl
Definition: wdfwmi.h:52
@ WdfWmiInstanceControl
Definition: wdfwmi.h:53
@ WdfWmiProviderTracing
Definition: wdfwmi.h:71
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_INSTANCE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_opt_ WDFWMIINSTANCE * Instance
Definition: wdfwmi.h:481
WDF_EXTERN_C_START enum _WDF_WMI_PROVIDER_CONTROL WDF_WMI_PROVIDER_CONTROL
struct tagWNODE_METHOD_ITEM * PWNODE_METHOD_ITEM
#define WNODE_FLAG_TOO_SMALL
Definition: wmistr.h:33
#define WNODE_FLAG_STATIC_INSTANCE_NAMES
Definition: wmistr.h:35
struct tagWNODE_ALL_DATA * PWNODE_ALL_DATA
struct tagWNODE_SINGLE_ITEM * PWNODE_SINGLE_ITEM
struct tagWNODE_SINGLE_INSTANCE * PWNODE_SINGLE_INSTANCE
WMIREGINFOW WMIREGINFO
Definition: wmistr.h:101
struct tagWNODE_TOO_SMALL * PWNODE_TOO_SMALL
struct tagWNODE_TOO_SMALL WNODE_TOO_SMALL
PWMIREGINFOW PWMIREGINFO
Definition: wmistr.h:102
@ DelayedWorkQueue
Definition: extypes.h:190
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
#define IRP_MN_EXECUTE_METHOD
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_DISABLE_COLLECTION
#define IRP_MN_CHANGE_SINGLE_ITEM
#define WMIREG_ACTION_REGISTER
#define IRP_MN_QUERY_ALL_DATA
#define WMIREG_ACTION_DEREGISTER
#define IRP_MN_DISABLE_EVENTS
#define WMIREG_ACTION_UPDATE_GUIDS
#define IRP_MN_ENABLE_EVENTS
#define IRP_MN_ENABLE_COLLECTION
#define IRP_MN_REGINFO
#define IRP_MN_REGINFO_EX
#define IRP_MN_CHANGE_SINGLE_INSTANCE
#define IRP_MN_QUERY_SINGLE_INSTANCE
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define ObReferenceObject
Definition: obfuncs.h:204
unsigned char UCHAR
Definition: xmlstorage.h:181