ReactOS 0.4.15-dev-7958-gcd0bb1a
fxpkgpdo.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxPkgPdo.cpp
8
9Abstract:
10
11 This module implements the Pnp package for Pdo devices.
12
13Author:
14
15
16
17Environment:
18
19 Both kernel and user mode
20
21Revision History:
22
23
24
25
26--*/
27
28#include "pnppriv.hpp"
29#include <wdmguid.h>
30
31// Tracing support
32#if defined(EVENT_TRACING)
33extern "C" {
34#include "FxPkgPdo.tmh"
35}
36#endif
37
39{
40 _PnpStartDevice, // IRP_MN_START_DEVICE
41 _PnpQueryRemoveDevice, // IRP_MN_QUERY_REMOVE_DEVICE
42 _PnpRemoveDevice, // IRP_MN_REMOVE_DEVICE
43 _PnpCancelRemoveDevice, // IRP_MN_CANCEL_REMOVE_DEVICE
44 _PnpStopDevice, // IRP_MN_STOP_DEVICE
45 _PnpQueryStopDevice, // IRP_MN_QUERY_STOP_DEVICE
46 _PnpCancelStopDevice, // IRP_MN_CANCEL_STOP_DEVICE
47
48 _PnpQueryDeviceRelations, // IRP_MN_QUERY_DEVICE_RELATIONS
49 _PnpQueryInterface, // IRP_MN_QUERY_INTERFACE
50 _PnpQueryCapabilities, // IRP_MN_QUERY_CAPABILITIES
51 _PnpQueryResources, // IRP_MN_QUERY_RESOURCES
52 _PnpQueryResourceRequirements, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS
53 _PnpQueryDeviceText, // IRP_MN_QUERY_DEVICE_TEXT
54 _PnpFilterResourceRequirements, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS
55
56 _PnpCompleteIrp, // 0x0E
57
58 _PnpCompleteIrp, // IRP_MN_READ_CONFIG
59 _PnpCompleteIrp, // IRP_MN_WRITE_CONFIG
60 _PnpEject, // IRP_MN_EJECT
61 _PnpSetLock, // IRP_MN_SET_LOCK
62 _PnpQueryId, // IRP_MN_QUERY_ID
63 _PnpQueryPnpDeviceState, // IRP_MN_QUERY_PNP_DEVICE_STATE
64 _PnpQueryBusInformation, // IRP_MN_QUERY_BUS_INFORMATION
65 _PnpDeviceUsageNotification, // IRP_MN_DEVICE_USAGE_NOTIFICATION
66 _PnpSurpriseRemoval, // IRP_MN_SURPRISE_REMOVAL
67};
68
70{
71 _DispatchWaitWake, // IRP_MN_WAIT_WAKE
72 _DispatchPowerSequence, // IRP_MN_POWER_SEQUENCE
73 _DispatchSetPower, // IRP_MN_SET_POWER
74 _DispatchQueryPower, // IRP_MN_QUERY_POWER
75};
76
77//#if defined(ALLOC_PRAGMA)
78//#pragma code_seg("PAGE")
79//#endif
80
82 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
84 ) :
85 FxPkgPnp(FxDriverGlobals, Device, FX_TYPE_PACKAGE_PDO)
86/*++
87
88Routine Description:
89
90 This is the constructor for the FxPkgPdo. Don't do any initialization
91 that might fail here.
92
93Arguments:
94
95 none
96
97Returns:
98
99 none
100
101--*/
102
103{
105
112
113 m_RawOK = FALSE;
114 m_Static = FALSE;
116
117 //
118 // By default the PDO is the owner of wait wake irps (only case where this
119 // wouldn't be the case is for a bus filter to be sitting above us).
120 //
122
125
128
131}
132
134 VOID
135 )
136/*++
137
138Routine Description:
139
140 This is the destructor for the FxPkgPdo
141
142Arguments:
143
144 none
145
146Returns:
147
148 none
149
150--*/
151{
152 //
153 // If IoCreateDevice fails on a dynamically created PDO, m_Description will
154 // be != NULL b/c we will not go through the pnp state machine in its entirety
155 // for cleanup. FxChildList will need a valid m_Description to cleanup upon
156 // failure from EvtChildListDeviceCrate, so we just leave m_Description alone
157 // here if != NULL.
158 //
159 // ASSERT(m_Description == NULL);
160
162
163 //
164 // This will free the underlying memory for m_DeviceID, m_InstanceID,
165 // m_HardwareIDs, m_CompatibleIDs and m_ContainerID
166 //
167 if (m_IDsAllocation != NULL) {
170 }
171
172 if (m_OwningChildList != NULL) {
173 m_OwningChildList->RELEASE(this);
174 }
175
176 if (m_EjectionDeviceList != NULL) {
179 }
180}
181
186 )
187/*++
188
189Routine Description:
190
191 Do initialization that might fail here.
192
193Arguemnts:
194
195 DeviceInit - the structure the driver passed in with initialization data
196
197Returns:
198
199 NTSTATUS
200
201--*/
202{
204 size_t cbLength, cbStrLength;
205 PWSTR pCur;
206 PdoInit* pPdo;
207
209 if (!NT_SUCCESS(status)) {
210 return status;
211 }
212
213 cbLength = 0;
214
215 //
216 // Compute the total number of bytes required for all strings and then
217 // make one allocation and remember pointers w/in the string so we can
218 // retrieve them individually later.
219 //
220 pPdo = &DeviceInit->Pdo;
221 cbLength += FxCalculateTotalStringSize(&pPdo->HardwareIDs);
222 cbLength += FxCalculateTotalStringSize(&pPdo->CompatibleIDs);
223
224 if (pPdo->DeviceID != NULL) {
225 cbLength += pPdo->DeviceID->ByteLength(TRUE);
226 }
227 if (pPdo->InstanceID != NULL) {
228 cbLength += pPdo->InstanceID->ByteLength(TRUE);
229 }
230 if (pPdo->ContainerID != NULL) {
231 cbLength += pPdo->ContainerID->ByteLength(TRUE);
232 }
233
234 m_IDsAllocation = (PWSTR) FxPoolAllocate(GetDriverGlobals(),
235 PagedPool,
236 cbLength);
237
238 if (m_IDsAllocation == NULL) {
240
243 "DeviceInit %p could not allocate string for device IDs "
244 "(length %I64d), %!STATUS!", DeviceInit, cbLength, status);
245
246 return status;
247 }
248
250
252 pCur = FxCopyMultiSz(m_HardwareIDs, &pPdo->HardwareIDs);
253
255 pCur = FxCopyMultiSz(m_CompatibleIDs, &pPdo->CompatibleIDs);
256
257 if (pPdo->DeviceID != NULL) {
259
260 //
261 // Copy the bytes and then null terminate the buffer
262 //
263 cbStrLength = pPdo->DeviceID->ByteLength(FALSE);
264
266 pPdo->DeviceID->Buffer(),
267 cbStrLength);
268
269 m_DeviceID[cbStrLength / sizeof(WCHAR)] = UNICODE_NULL;
270
272 cbStrLength + sizeof(UNICODE_NULL));
273 }
274
275 if (pPdo->InstanceID != NULL) {
277
278 //
279 // Copy the bytes and then null terminate the buffer
280 //
281 cbStrLength = pPdo->InstanceID->ByteLength(FALSE);
282
284 pPdo->InstanceID->Buffer(),
285 cbStrLength);
286
287 m_InstanceID[cbStrLength / sizeof(WCHAR)] = UNICODE_NULL;
288
290 cbStrLength + sizeof(UNICODE_NULL));
291 }
292
293 if (pPdo->ContainerID != NULL) {
295
296 //
297 // Copy the bytes and then null terminate the buffer
298 //
299 cbStrLength = pPdo->ContainerID->ByteLength(FALSE);
300
302 pPdo->ContainerID->Buffer(),
303 cbStrLength);
304
305 m_ContainerID[cbStrLength / sizeof(WCHAR)] = UNICODE_NULL;
306 }
307
308 m_Static = pPdo->Static;
309
310 if (m_Static) {
311 //
312 // Statically enumerated children do not support reenumeration requests
313 // from the stack on top of them.
314 //
315
316 //
317 // The only way we can have static children is if an FDO enumerates them.
318 //
319
320
321
322
323
326
327 m_OwningChildList->ADDREF(this);
328 }
329 else {
330 m_Description = pPdo->DescriptionEntry;
331
333 m_OwningChildList->ADDREF(this);
334 }
335
336 return STATUS_SUCCESS;
337}
338
339VOID
342 )
343{
344 PdoInit* pdoInit;
345
346 pdoInit = &DeviceInit->Pdo;
347
350 pdoInit->DeviceText.Next = NULL;
351
352 //
353 // Important to do this last since this will cause a pnp state machine
354 // transition
355 //
356 FxPkgPnp::FinishInitialize(DeviceInit); // __super call
357}
358
362 __in FxIrp* Irp
363 )
364/*++
365
366Routine Description:
367 Virtual override for synchronously sending a request down the stack and
368 catching it on the way back up. For PDOs, we are the bottom, so this is a
369 no-op.
370
371Arguments:
372 Irp - The request
373
374Return Value:
375 Status in the Irp
376
377 --*/
378{
379 return Irp->GetStatus();
380}
381
386 )
387/*++
388
389Routine Description:
390
391 Virtual override for sending a request down the stack and forgetting about
392 it. Since we are the bottom of the stack, just complete the request.
393
394Arguments:
395
396Return Value:
397
398--*/
399{
401
402 status = Irp->GetStatus();
403
404 if (Irp->GetMajorFunction() == IRP_MJ_POWER) {
406 }
407 else {
409 }
410}
411
417 )
418{
419 return ((FxPkgPdo*) This)->CompletePnpRequest(Irp, Irp->GetStatus());
420}
421
427 )
428{
429 return ((FxPkgPdo*) This)->PnpQueryDeviceRelations(Irp);
430}
431
436 )
437/*++
438
439Routine Description:
440
441 This method is called in response to a PnP QDR. PDOs handle Ejection
442 Relations and Target Relations.
443
444Arguments:
445
446 Irp - a pointer to the FxIrp
447
448Returns:
449
450 NTSTATUS
451
452--*/
453{
454 PDEVICE_RELATIONS pDeviceRelations;
458
459 status = Irp->GetStatus();
461
462 type = Irp->GetParameterQDRType();
463 switch (type) {
464 case BusRelations:
466 break;
467
469 case RemovalRelations:
471 Irp,
474
475 //
476 // STATUS_NOT_SUPPORTED is a special value. It means that
477 // HandleQueryDeviceRelations did not modify the irp at all and it
478 // should be sent off as is.
479 //
481 //
482 // Complete the request with the status it was received with
483 //
484 status = Irp->GetStatus();
485 }
486 break;
487
491
492 if (pDeviceRelations != NULL) {
494
495 pDeviceObject = reinterpret_cast<PDEVICE_OBJECT> (m_Device->GetDeviceObject());
496
498
499 pDeviceRelations->Count = 1;
500 pDeviceRelations->Objects[0] = pDeviceObject;
501
502 Irp->SetInformation((ULONG_PTR) pDeviceRelations);
504 }
505 else {
506 Irp->SetInformation(NULL);
508
511 "WDFDEVICE %p failing TargetDeviceRelations, %!STATUS!",
513 }
514 break;
515 }
516
518}
519
524 IN FxIrp *Irp
525 )
526/*++
527
528Routine Description:
529 Query interface handler for the PDO
530
531Arguments:
532 This - the package
533
534 Irp - the QI request
535
536Return Value:
537 NTSTATUS
538
539 --*/
540{
542 BOOLEAN completeIrp;
543
544 status = ((FxPkgPdo*) This)->HandleQueryInterface(Irp, &completeIrp);
545
547}
548
554 )
555{
556 return ((FxPkgPdo*) This)->PnpQueryCapabilities(Irp);
557}
558
563 )
564
565/*++
566
567Routine Description:
568
569 This method is invoked in response to a Pnp QueryCapabilities IRP.
570
571Arguments:
572
573 Irp - a pointer to the FxIrp
574
575Returns:
576
577 NTSTATUS
578
579--*/
580
581{
582 PDEVICE_CAPABILITIES pDeviceCapabilities;
583 STACK_DEVICE_CAPABILITIES parentStackCapabilities = {0};
585
587
588 pDeviceCapabilities = Irp->GetParameterDeviceCapabilities();
589
590 //
591 // Confirm this is a valid DeviceCapabilities structure.
592 //
593 ASSERT(pDeviceCapabilities->Size >= sizeof(DEVICE_CAPABILITIES));
594 ASSERT(pDeviceCapabilities->Version == 1);
595
596 if ((pDeviceCapabilities->Version == 1) &&
597 (pDeviceCapabilities->Size >= sizeof(DEVICE_CAPABILITIES))) {
598
599 //
600 // Since query caps must be sent to the parent stack until it reaches
601 // the root, we can quickly run out of stack space. If that happens,
602 // then move to a work item to get a fresh stack with plenty of stack
603 // space.
604 //
606 MxWorkItem workItem;
607
609
610 if (NT_SUCCESS(status)) {
611 //
612 // Store off the work item so we can free it in the worker routine
613 //
614 Irp->SetContext(0, (PVOID)workItem.GetWorkItem());
615
616 //
617 // Mark the irp as pending because it will be completed in
618 // another thread
619 //
620 Irp->MarkIrpPending();
621
622 //
623 // Kick off to another thread
624 //
625 workItem.Enqueue(_QueryCapsWorkItem, Irp->GetIrp());
626
627 return STATUS_PENDING;
628 }
629 else {
630 //
631 // Not enough for a work item, return error
632 //
634 }
635 }
636 else {
637 MxDeviceObject parentDeviceObject;
638
639 parentDeviceObject.SetObject(
643 &parentDeviceObject,
644 NULL, // D3ColdInterface
645 &parentStackCapabilities);
646
647 if (NT_SUCCESS(status)) {
648#pragma prefast(suppress:__WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY, "prefast is confused")
649 HandleQueryCapabilities(pDeviceCapabilities,
650 &parentStackCapabilities.DeviceCaps);
651
652 //
653 // The check above does not guarantee STATUS_SUCCESS explicitly
654 // (ie the verifier can change the value to something other then
655 // STATUS_SUCCESS) so set it here
656 //
658 }
659 }
660 }
661
663}
664
665VOID
667 __inout PDEVICE_CAPABILITIES ReportedCaps,
668 __in_bcount(ParentCaps->size) PDEVICE_CAPABILITIES ParentCaps
669 )
670{
671 LONG pnpCaps;
672 ULONG i;
673
674 //
675 // PowerSystemUnspecified is reserved for system use as per the DDK
676 //
679
681
682 if (state == PowerDeviceMaximum) {
683 //
684 // PDO did not specify any value, use parent's cap
685 //
686#pragma prefast(suppress:__WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY, "Esp:675")
687 ReportedCaps->DeviceState[i] = ParentCaps->DeviceState[i];
688 }
689 else {
690 //
691 // Use PDO's reported value
692 //
693 ReportedCaps->DeviceState[i] = state;
694 }
695 }
696
697 pnpCaps = GetPnpCapsInternal();
698
699 //
700 // Appropriately fill the DeviceCapabilities structure.
701 //
702 SET_PNP_CAP(pnpCaps, ReportedCaps, LockSupported);
703 SET_PNP_CAP(pnpCaps, ReportedCaps, EjectSupported);
704 SET_PNP_CAP(pnpCaps, ReportedCaps, Removable);
705 SET_PNP_CAP(pnpCaps, ReportedCaps, DockDevice);
706 SET_PNP_CAP(pnpCaps, ReportedCaps, UniqueID);
707
709 SET_PNP_CAP(pnpCaps, ReportedCaps, SilentInstall);
710 }
711 else if (m_RawOK) {
712 //
713 // By default, we report raw devices as silent install devices
714 // because if they are raw, they don't need any further
715 // installation.
716 //
717 ReportedCaps->SilentInstall = TRUE;
718 }
719
720 SET_PNP_CAP(pnpCaps, ReportedCaps, SurpriseRemovalOK);
721 SET_PNP_CAP(pnpCaps, ReportedCaps, HardwareDisabled);
722 SET_PNP_CAP(pnpCaps, ReportedCaps, NoDisplayInUI);
723
724 SET_POWER_CAP(m_PowerCaps.Caps , ReportedCaps, WakeFromD0);
725 SET_POWER_CAP(m_PowerCaps.Caps , ReportedCaps, WakeFromD1);
726 SET_POWER_CAP(m_PowerCaps.Caps , ReportedCaps, WakeFromD2);
727 SET_POWER_CAP(m_PowerCaps.Caps , ReportedCaps, WakeFromD3);
728 SET_POWER_CAP(m_PowerCaps.Caps , ReportedCaps, DeviceD1);
729 SET_POWER_CAP(m_PowerCaps.Caps , ReportedCaps, DeviceD2);
730
731 if (m_RawOK) {
732 ReportedCaps->RawDeviceOK = TRUE;
733 }
734
735 ReportedCaps->UINumber = m_PnpCapsUINumber;
736 ReportedCaps->Address = m_PnpCapsAddress;
737
739 ReportedCaps->SystemWake = (SYSTEM_POWER_STATE) m_PowerCaps.SystemWake;
740 }
741 else {
742 ReportedCaps->SystemWake = ParentCaps->SystemWake;
743 }
744
745 //
746 // Set the least-powered device state from which the device can
747 // wake the system.
748 //
750 ReportedCaps->DeviceWake = (DEVICE_POWER_STATE) m_PowerCaps.DeviceWake;
751 }
752 else {
753 ReportedCaps->DeviceWake = ParentCaps->DeviceWake;
754 }
755
756 //
757 // Set the Device wake up latencies.
758 //
759 if (m_PowerCaps.D1Latency != (ULONG) -1) {
760 ReportedCaps->D1Latency = m_PowerCaps.D1Latency;
761 }
762 else {
763 ReportedCaps->D1Latency = 0;
764 }
765
766 if (m_PowerCaps.D2Latency != (ULONG) -1) {
767 ReportedCaps->D2Latency = m_PowerCaps.D2Latency;
768 }
769 else {
770 ReportedCaps->D2Latency = 0;
771 }
772
773 if (m_PowerCaps.D3Latency != (ULONG) -1) {
774 ReportedCaps->D3Latency = m_PowerCaps.D3Latency;
775 }
776}
777
778VOID
782 )
783{
784 STACK_DEVICE_CAPABILITIES parentCapabilities;
785 MdWorkItem pItem;
787 FxIrp irp;
789 MxDeviceObject parentDeviceObject;
790
792 pItem = (MdWorkItem) irp.GetContext(0);
793
795
796 parentDeviceObject.SetObject(
798
801 &parentDeviceObject,
802 NULL, // D3ColdInterface
803 &parentCapabilities);
804
805 if (NT_SUCCESS(status)) {
806#pragma prefast(suppress:__WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY, "prefast is confused")
809 &parentCapabilities.DeviceCaps
810 );
812 }
813
815
816 MxWorkItem::_Free(pItem);
817}
818
823 )
824
825/*++
826
827Routine Description:
828
829
830
831Arguments:
832
833Returns:
834
835--*/
836
837{
839
840 for (ple = Head->Next; ple != NULL; ple = ple->Next) {
842
844
846 //
847 // We found our object!
848 //
849 return pDeviceText;
850 }
851 }
852
853 return NULL;
854}
855
861 )
862
863/*++
864
865Routine Description:
866
867 This method is invoked in response to a Pnp QueryDeviceText IRP.
868 We return the decription or the location.
869
870Arguments:
871
872 Irp - a pointer to the FxIrp
873
874Returns:
875
876 NTSTATUS
877
878--*/
879
880{
881 FxPkgPdo* pThis;
882 LCID localeId;
883 FxDeviceText *pDeviceTextObject;
886
887 pThis = (FxPkgPdo*) This;
889
890 localeId = Irp->GetParameterQueryDeviceTextLocaleId();
891 status = Irp->GetStatus();
892
893 //
894 // The PDO package maintains a collection of "DeviceText" objects. We
895 // will look up the item in the collection with the "appropriate" locale.
896 //
897 // If no entries are found in the collection for the given locale, then
898 // we will use the "default locale" property of the PDO and use the
899 // entry for the "default locale".
900 //
901
902 //
903 // Try to find the FxDeviceText object for the given locale.
904 //
905 pDeviceTextObject = FindObjectForGivenLocale(
906 &pThis->m_DeviceTextHead, localeId);
907
908 if (pDeviceTextObject == NULL) {
909 pDeviceTextObject = FindObjectForGivenLocale(
910 &pThis->m_DeviceTextHead, pThis->m_DefaultLocale);
911 }
912
913 if (pDeviceTextObject != NULL) {
914 PWCHAR pInformation;
915
916 pInformation = NULL;
917
918 switch (Irp->GetParameterQueryDeviceTextType()) {
920 pInformation = pDeviceTextObject->m_Description;
921 break;
922
924 pInformation = pDeviceTextObject->m_LocationInformation;
925 break;
926 }
927
928 //
929 // Information should now point to a valid unicode string.
930 //
931 if (pInformation != NULL) {
933 size_t length;
934
935 length = (wcslen(pInformation) + 1) * sizeof(WCHAR);
936
937 //
938 // Make sure the information field of the IRP isn't already set.
939 //
940 ASSERT(Irp->GetInformation() == NULL);
941
944
945 if (pBuffer != NULL) {
946 RtlCopyMemory(pBuffer, pInformation, length);
947 Irp->SetInformation((ULONG_PTR) pBuffer);
948
950 }
951 else {
953
956 "WDFDEVICE %p failing Query Device Text, type %d, %!STATUS!",
957 pThis->m_Device->GetHandle(),
958 Irp->GetParameterQueryDeviceTextType(), status);
959 }
960 }
961 }
962
963 return pThis->CompletePnpRequest(Irp, status);
964}
965
971 )
972/*++
973
974Routine Description:
975
976 Ejection is handled by the PnP state machine. Handle it synchronously.
977 Don't pend it since PnP manager does not serilaize it with other state
978 changing pnp irps if handled asynchronously.
979
980Arguments:
981
982 This - the package
983
984 Irp - the request
985
986Return Value:
987
988 NTSTATUS
989
990 --*/
991{
993 FxPkgPdo* pdoPkg;
995
996 pdoPkg = (FxPkgPdo*)This;
997
998 //
999 // This will make sure no new state changing pnp irps arrive while
1000 // we are still processing this one. Also, note that irp is not being
1001 // marked pending.
1002 //
1003 pdoPkg->SetPendingPnpIrp(Irp, FALSE);
1004
1005 status = event.Initialize(SynchronizationEvent, FALSE);
1006 if (!NT_SUCCESS(status)) {
1007
1010 "Event allocation failed while processing eject for WDFDEVICE %p,"
1011 " %!STATUS!",
1012 pdoPkg->m_Device->GetHandle(), status);
1013 }
1014 else {
1016 pdoPkg->m_DeviceEjectProcessed = event.GetSelfPointer();
1017
1018 //
1019 // let state machine process eject
1020 //
1022
1023 //
1024 // No need to wait in a critical region because we are in the context of a
1025 // pnp request which is in the system context.
1026 //
1027 event.WaitFor(Executive, KernelMode, FALSE, NULL);
1028
1029 pdoPkg->m_DeviceEjectProcessed = NULL;
1030
1031 status = Irp->GetStatus();
1032 }
1033
1034 //
1035 // complete request
1036 //
1037
1038 pdoPkg->ClearPendingPnpIrp();
1039 pdoPkg->CompletePnpRequest(Irp, status);
1040
1041 return status;
1042}
1043
1046 VOID
1047 )
1048/*++
1049
1050Routine Description:
1051
1052 This function implements the EjectHardware state. This
1053 function overloads the base PnP State machine handler. Its
1054 job is to call EvtDeviceEject. If that succeeds, then we
1055 transition immediately to EjectedWaitingForRemove. If not,
1056 then to EjectFailed.
1057
1058Arguments:
1059
1060 none
1061
1062Return Value:
1063
1064 NTSTATUS
1065
1066--*/
1067{
1070
1072
1073 if (NT_SUCCESS(status)) {
1074
1075 //
1076 // Upon a successful eject, mark the child as missing so that when we
1077 // get another QDR, it is not re-reported.
1078 //
1080 MxEvent* event;
1081
1083
1085 if (NT_SUCCESS(status)) {
1088 "PDO WDFDEVICE %p !devobj %p marked missing as a result of eject",
1090 }
1091 else {
1094 "Failed to mark PDO WDFDEVICE %p !devobj %p missing after eject %!STATUS!",
1096 status);
1097 }
1098
1099 //
1100 // We must wait for any pending scans to finish so that the previous
1101 // update as missing is enacted into the list and reported to the
1102 // OS. Otherwise, if we don't wait we could be in the middle of a
1103 // scan, complete the eject, report the child again and it will be
1104 // reenumerated.
1105 //
1106 event = pList->GetScanEvent();
1107
1109 "waiting on event %p for device to finish scanning",
1110 &event);
1111
1112 //
1113 // No need to wait in a crtical region because we are in the context of a
1114 // pnp request which is in the system context.
1115 //
1116 event->WaitFor(Executive, KernelMode, FALSE, NULL);
1117
1118 //
1119 // Change the state.
1120 //
1122 }
1123 else {
1127 "Eject failed since driver's EvtDeviceEject returned %!STATUS!", status);
1128
1132 "EvtDeviceEject returned an invalid status STATUS_NOT_SUPPORTED");
1133
1134 if (GetDriverGlobals()->IsVerificationEnabled(1, 11, OkForDownLevel)) {
1136 }
1137 }
1138 }
1139
1140 //
1141 // set irp status
1142 //
1144
1145 //
1146 // Pnp dispatch routine is waiting on this event, and it will complete
1147 // the Eject irp
1148 //
1150
1151 return state;
1152}
1153
1156 VOID
1157 )
1158/*++
1159
1160Routine Description:
1161
1162 This function implements the CheckForDevicePresence state. This
1163 function overloads the base PnP State machine handler. It's
1164 job is to figure out whether the removed device is actually
1165 still attached. It then changes state based on that result.
1166
1167Arguments:
1168
1169 none
1170
1171Return Value:
1172
1173 NTSTATUS
1174
1175--*/
1176
1177{
1178 if (m_Description != NULL) {
1180 //
1181 // The description freed itself now that the device has been reported
1182 // missing.
1183 //
1185 }
1186 else {
1187 //
1188 // Device was not reported as missing, keep it alive
1189 //
1191 }
1192 }
1193 else {
1194 //
1195 // Only static children can get this far without having an m_Description
1196 //
1198
1199 //
1200 // The description freed itself now that the device has been reported
1201 // missing.
1202 //
1204 }
1205}
1206
1209 VOID
1210 )
1211/*++
1212
1213Routine Description:
1214
1215 This function implements the Removed state. This
1216 function overloads the base PnP State machine handler.
1217
1218Arguments:
1219
1220 none
1221
1222Return Value:
1223
1224 NTSTATUS
1225
1226--*/
1227{
1229
1230 //
1231 // Unconditionally delete the symbolic link now (vs calling
1232 // DeleteSymbolicLinkOverload()) because we know that the device has been
1233 // reported as missing.
1234 //
1236
1237 //
1238 // Do that which all device stacks need to do upon removal.
1239 //
1241
1242 //
1243 // m_Device is Release()'ed in FxPkgPnp::PnpEventFinal
1244 //
1245 if (m_Description != NULL) {
1247 "Removing entry reference %p on FxPkgPnp %p",
1248 m_Description, this);
1249
1252 }
1253
1254 return WdfDevStatePnpFinal;
1255}
1256
1259 VOID
1260 )
1261{
1262 //
1263 // Transition to the check for device presence state.
1264 //
1266}
1267
1270 VOID
1271 )
1272{
1273 ASSERT(!"This should only be implemented for FDOs.");
1274
1275 //
1276 // Do something safe. Act like the device is not present.
1277 //
1278 return WdfDevStatePnpFinal;
1279}
1280
1281VOID
1283 VOID
1284 )
1285{
1286 if (m_Description != NULL) {
1288 }
1289
1291}
1292
1293BOOLEAN
1295 VOID
1296 )
1297/*++
1298
1299Routine Description:
1300 Process the start irp on the way down the stack during a start.
1301
1302 Since the PDO is the bottom, just move to the new state where we
1303 are processing the irp up the stack.
1304
1305Arguments:
1306 None
1307
1308Return Value:
1309 TRUE, the completion of the start irp down the stack was synchronous
1310
1311 --*/
1312{
1313 //
1314 // We are successful so far, indicate this in the irp.
1315 //
1317
1318 return TRUE;
1319}
1320
1326 )
1327/*++
1328
1329Routine Description:
1330 Set lock
1331
1332Arguments:
1333 This - the package
1334
1335 Irp - the irp
1336
1337Return Value:
1338 NTSTATUS
1339
1340 --*/
1341{
1343 BOOLEAN lock;
1344
1345 lock = Irp->GetParameterSetLockLock();
1346
1347 status = ((FxPkgPdo*) This)->m_DeviceSetLock.Invoke(
1348 ((FxPkgPdo*) This)->m_Device->GetHandle(), lock);
1349
1350 if (NT_SUCCESS(status)) {
1351 Irp->SetInformation(NULL);
1352 }
1353
1354 return ((FxPkgPdo*) This)->CompletePnpRequest(Irp, status);
1355}
1356
1362 )
1363{
1364 FxPkgPdo* pThis;
1367 PCWSTR pSrc;
1368 size_t cbLength;
1370 BUS_QUERY_ID_TYPE queryIdType;
1371
1372 pThis = (FxPkgPdo*) This;
1374 status = Irp->GetStatus();
1375 cbLength = 0;
1376
1377 queryIdType = Irp->GetParameterQueryIdType();
1378
1379 switch (queryIdType) {
1380 case BusQueryDeviceID:
1381 case BusQueryInstanceID:
1383 if (queryIdType == BusQueryDeviceID) {
1384 pSrc = pThis->m_DeviceID;
1385 }
1386 else if (queryIdType == BusQueryInstanceID) {
1387 pSrc = pThis->m_InstanceID;
1388 }
1389 else {
1390 pSrc = pThis->m_ContainerID;
1391 }
1392
1393 if (pSrc != NULL) {
1394 cbLength = (wcslen(pSrc) + 1) * sizeof(WCHAR);
1395
1397 PagedPool, cbLength, pFxDriverGlobals->Tag);
1398 }
1399 else {
1400 status = Irp->GetStatus();
1401 break;
1402 }
1403
1404 if (pBuffer != NULL) {
1405
1406 //
1407 // This will copy the NULL terminator too
1408 //
1409 RtlCopyMemory(pBuffer, pSrc, cbLength);
1410 Irp->SetInformation((ULONG_PTR) pBuffer);
1412 }
1413 else {
1415 }
1416 break;
1417
1420 if (queryIdType == BusQueryHardwareIDs) {
1421 pSrc = pThis->m_HardwareIDs;
1422 }
1423 else {
1424 pSrc = pThis->m_CompatibleIDs;
1425 }
1426
1427 if (pSrc != NULL) {
1428 cbLength = FxCalculateTotalMultiSzStringSize(pSrc);
1429 }
1430 else {
1431 //
1432 // Must return an empty list
1433 //
1434 cbLength = 2 * sizeof(UNICODE_NULL);
1435 }
1436
1438 PagedPool, cbLength, pFxDriverGlobals->Tag);
1439
1440 if (pBuffer != NULL) {
1441 if (pSrc != NULL) {
1442 RtlCopyMemory(pBuffer, pSrc, cbLength);
1443 }
1444 else {
1445 RtlZeroMemory(pBuffer, cbLength);
1446 }
1447
1448 Irp->SetInformation((ULONG_PTR) pBuffer);
1450 }
1451 else {
1453 }
1454 break;
1455 }
1456
1457 if (!NT_SUCCESS(status)) {
1458 Irp->SetInformation(NULL);
1459
1463 "WDFDEVICE %p does not have a string for PnP query IdType "
1464 "%!BUS_QUERY_ID_TYPE!, %!STATUS!",
1465 pThis->m_Device->GetHandle(),
1466 queryIdType, status);
1467 }
1468 else {
1471 "WDFDEVICE %p could not alloc string for PnP query IdType "
1472 "%!BUS_QUERY_ID_TYPE!, %!STATUS!",
1473 pThis->m_Device->GetHandle(),
1474 queryIdType, status);
1475 }
1476 }
1477
1478 return ((FxPkgPdo*) pThis)->CompletePnpRequest(Irp, status);
1479}
1480
1486 )
1487/*++
1488
1489Routine Description:
1490 indicates the current device state
1491
1492Arguments:
1493 This - the package
1494
1495 Irp - the request
1496
1497Return Value:
1498 NTSTATUS
1499
1500 --*/
1501{
1502 PNP_DEVICE_STATE pnpDeviceState;
1503 PFX_DRIVER_GLOBALS FxDriverGlobals = This->GetDriverGlobals();
1504
1506 "Entering QueryPnpDeviceState handler");
1507
1508 pnpDeviceState = ((FxPkgPdo*) This)->HandleQueryPnpDeviceState(
1509 (PNP_DEVICE_STATE) Irp->GetInformation());
1510
1511 Irp->SetInformation((ULONG_PTR) pnpDeviceState);
1512
1514 FxDriverGlobals, TRACE_LEVEL_INFORMATION, TRACINGPNP,
1515 "WDFDEVICE 0x%p !devobj 0x%p returning PNP_DEVICE_STATE 0x%d IRP 0x%p",
1516 This->GetDevice()->GetHandle(),
1517 This->GetDevice()->GetDeviceObject(),
1518 pnpDeviceState,
1519 Irp->GetIrp());
1520
1522 "Exiting QueryPnpDeviceState handler");
1523
1524 return ((FxPkgPdo*) This)->CompletePnpRequest(Irp, STATUS_SUCCESS);
1525}
1526
1532 )
1533/*++
1534
1535Routine Description:
1536 Returns the bus information for this child
1537
1538Arguments:
1539 This - the package
1540
1541 Irp - the request
1542
1543Return Value:
1544 NTSTATUS
1545
1546 --*/
1547{
1548 FxPkgPdo* pThis;
1550
1551 pThis = (FxPkgPdo*) This;
1552
1555
1556 return pThis->CompletePnpRequest(Irp, status);
1557}
1558
1564 )
1565{
1566 FxPkgPdo* pThis;
1567
1568 pThis = (FxPkgPdo*) This;
1569
1571
1572 return pThis->PnpSurpriseRemoval(Irp);
1573}
1574
1575VOID
1578 )
1579{
1580 m_DeviceResourcesQuery.m_Method = DispatchTable->EvtDeviceResourcesQuery;
1581 m_DeviceResourceRequirementsQuery.m_Method = DispatchTable->EvtDeviceResourceRequirementsQuery;
1582 m_DeviceEject.m_Method = DispatchTable->EvtDeviceEject;
1583 m_DeviceSetLock.m_Method = DispatchTable->EvtDeviceSetLock;
1584
1585 m_DeviceEnableWakeAtBus.m_Method = DispatchTable->EvtDeviceEnableWakeAtBus;
1586 m_DeviceDisableWakeAtBus.m_Method = DispatchTable->EvtDeviceDisableWakeAtBus;
1587
1588 //
1589 // this callback was added in V1.11
1590 //
1591 if (DispatchTable->Size > sizeof(WDF_PDO_EVENT_CALLBACKS_V1_9)) {
1592 m_DeviceReportedMissing.m_Method = DispatchTable->EvtDeviceReportedMissing;
1593 }
1594}
1595
1599 VOID
1600 )
1601/*++
1602
1603Routine Description:
1604 This routine asks the PDO to ask its parent bus driver to Surprise-Remove
1605 and re-enumerate the PDO. This will be done only at the point of
1606 catastrophic software failure, and occasionally after catastrophic hardware
1607 failure.
1608
1609Arguments:
1610 None
1611
1612Return Value:
1613 status
1614
1615 --*/
1616{
1617 //
1618 // Static children do not support reenumeration.
1619 //
1620 if (m_Description != NULL && m_Static == FALSE) {
1622 return STATUS_SUCCESS;
1623 }
1624
1625 return STATUS_NOT_FOUND;
1626}
1627
1628
1629VOID
1631 __in BOOLEAN GracefulRemove
1632 )
1633/*++
1634
1635Routine Description:
1636 Role specific virtual function which determines if the symbolic link for a
1637 device should be deleted.
1638
1639Arguments:
1640 None
1641
1642Return Value:
1643 None
1644
1645 --*/
1646{
1647 if (GracefulRemove) {
1648 //
1649 // We will remove the symbolic link when we determine if the PDO was
1650 // reported missing or not.
1651 //
1652 return;
1653 }
1655 //
1656 // Surprise removed and we have reported the PDO as missing
1657 //
1658
1660 }
1661}
1662
1663
1664VOID
1667 )
1668/*++
1669
1670Routine Description:
1671 This routine is passed out to higher-level drivers as part of the
1672 re-enumeration interface.
1673
1674Arguments:
1675 This
1676
1677Return Value:
1678 void
1679
1680 --*/
1681{
1682 ((FxPkgPdo*) Context)->AskParentToRemoveAndReenumerate();
1683}
1684
1688 __in FxIrp* Irp,
1690 )
1691/*++
1692
1693Routine Description:
1694 Handles a query interface on the PDO for the self reenumeration interface.
1695
1696Arguments:
1697 Irp - the request containing the QI
1698
1699 CompleteRequest - whether the caller should complete the request when this
1700 call returns
1701
1702Return Value:
1703 status to complete the irp with
1704
1705 --*/
1706{
1709
1711
1712 if (m_Static) {
1713 //
1714 // Return the embedded status in the irp since this is a statically
1715 // enumerated child. Only dynamically enuemrated child support self
1716 // reenumeration.
1717 //
1718 return Irp->GetStatus();
1719 }
1720
1721 if (Irp->GetParameterQueryInterfaceVersion() == 1 &&
1722 Irp->GetParameterQueryInterfaceSize() >= sizeof(*pInterface)) {
1723
1725 Irp->GetParameterQueryInterfaceInterface();
1726
1727 //
1728 // Expose the interface to the requesting driver.
1729 //
1730 pInterface->Version = 1;
1731 pInterface->Size = sizeof(*pInterface);
1732 pInterface->Context = this;
1735 pInterface->SurpriseRemoveAndReenumerateSelf = &FxPkgPdo::_RemoveAndReenumerateSelf;
1736
1738
1739 //
1740 // Caller assumes a reference has been taken.
1741 //
1743 }
1744 else {
1746 }
1747
1748 return status;
1749}
1750
1755 )
1756{
1757 if (m_CanBeDeleted) {
1758 //
1759 // After this is called, any irp dispatched to FxDevice::DispatchWithLock
1760 // will fail with STATUS_INVALID_DEVICE_REQUEST.
1761 //
1762
1763
1764
1765
1766
1767
1768
1771 Irp->GetIrp()
1772 );
1773
1774 //
1775 // Cleanup the state machines and release the power thread.
1776 //
1778
1779 //
1780 // Detach and delete the device object.
1781 //
1782 DeleteDevice();
1783
1784 //
1785 // Can't call CompletePnpRequest because we just released the tag in
1786 // IoReleaseRemoveLockAndWait above.
1787 //
1788 Irp->CompleteRequest(IO_NO_INCREMENT);
1789
1790 return STATUS_SUCCESS;
1791 }
1792 else {
1793 //
1794 // This was a PDO which was not reported missing, so do not free the
1795 // memory and clear out our stack local address.
1796 //
1798 return CompletePnpRequest(Irp, Irp->GetStatus());
1799 }
1800}
1801
1805 VOID
1806 )
1807/*++
1808
1809Routine Description:
1810 Since the PDO is the lowest device in the stack, it does not have to send
1811 a query down the stack. Rather, it just creates the thread and returns.
1812
1813Arguments:
1814 None
1815
1816Return Value:
1817 NTSTATUS
1818
1819 --*/
1820{
1821 return CreatePowerThread();
1822}
1823
1828 )
1829{
1830 FxRelatedDevice* pRelated;
1832
1833 if (m_EjectionDeviceList == NULL) {
1834 KIRQL irql;
1835
1836 Lock(&irql);
1837 if (m_EjectionDeviceList == NULL) {
1839
1840 if (m_EjectionDeviceList != NULL) {
1842 }
1843 else {
1847 "Could not allocate ejection device list for PDO WDFDEVICE %p",
1848
1849 m_Device->GetHandle());
1850 }
1851 }
1852 else {
1853 //
1854 // another thread allocated the list already
1855 //
1857 }
1858 Unlock(irql);
1859
1860 if (!NT_SUCCESS(status)) {
1861 return status;
1862 }
1863 }
1864
1865 pRelated = new(GetDriverGlobals())
1867
1868 if (pRelated == NULL) {
1870 }
1871
1873
1874 if (NT_SUCCESS(status)) {
1875 //
1876 // EjectRelations are queried automatically by PnP when the device is
1877 // going to be ejected. No need to tell pnp that the list changed
1878 // until it needs to query for it.
1879 //
1880 DO_NOTHING();
1881 }
1882 else {
1883 pRelated->DeleteFromFailedCreate();
1884 }
1885
1886 return status;
1887}
1888
1889VOID
1892 )
1893{
1894 if (m_EjectionDeviceList != NULL) {
1896 }
1897
1898 //
1899 // EjectRelations are queried automatically by PnP when the device is
1900 // going to be ejected. No need to tell pnp that the list changed
1901 // until it needs to query for it.
1902 //
1903}
1904
1905VOID
1907 VOID
1908 )
1909{
1911
1912 if (m_EjectionDeviceList != NULL) {
1916 pEntry->GetDevice());
1917 }
1919 }
1920
1921 //
1922 // EjectRelations are queried automatically by PnP when the device is
1923 // going to be ejected. No need to tell pnp that the list changed
1924 // until it needs to query for it.
1925 //
1926}
unsigned char BOOLEAN
static int state
Definition: maze.c:121
LONG NTSTATUS
Definition: precomp.h:26
VOID ReenumerateEntry(__inout FxDeviceDescriptionEntry *Entry)
MxEvent * GetScanEvent(VOID)
_Must_inspect_result_ NTSTATUS UpdateAsMissing(__in PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Description)
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
VOID DeleteSymbolicLink(VOID)
__inline FxPkgFdo * GetFdoPkg(VOID)
Definition: fxdevice.hpp:1236
static VOID STDCALL _InterfaceDereferenceNoOp(__in_opt PVOID Context)
Definition: fxdevice.hpp:1778
CfxDevice * m_ParentDevice
Definition: fxdevice.hpp:569
static FxDevice * GetFxDevice(__in MdDeviceObject DeviceObject)
Definition: fxdeviceum.cpp:60
FxPkgPnp * m_PkgPnp
Definition: fxdevice.hpp:670
MdRemoveLock GetRemoveLock(VOID)
Definition: fxdevicekm.hpp:47
__inline FxPkgPdo * GetPdoPkg(VOID)
Definition: fxdevice.hpp:1254
static VOID STDCALL _InterfaceReferenceNoOp(__in_opt PVOID Context)
Definition: fxdevice.hpp:1767
__inline BOOLEAN IsFdo(VOID)
Definition: fxdevice.hpp:1227
Definition: fxirp.hpp:28
PDEVICE_CAPABILITIES GetParameterDeviceCapabilities()
Definition: fxirpum.cpp:1132
PVOID GetContext(__in ULONG Index)
Definition: fxirpum.cpp:361
MdIrp SetIrp(MdIrp irp)
Definition: fxirpkm.hpp:71
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
VOID DeleteFromFailedCreate(VOID)
Definition: fxobject.cpp:391
FxChildList * m_StaticDeviceList
Definition: fxpkgfdo.hpp:42
FxPowerDeviceEnableWakeAtBus m_DeviceEnableWakeAtBus
Definition: fxpkgpdo.hpp:53
SINGLE_LIST_ENTRY m_DeviceTextHead
Definition: fxpkgpdo.hpp:37
virtual BOOLEAN PnpSendStartDeviceDownTheStackOverload(VOID)
Definition: fxpkgpdo.cpp:1294
virtual WDF_DEVICE_PNP_STATE PnpEventEjectHardwareOverload(VOID)
Definition: fxpkgpdo.cpp:1045
virtual VOID DeleteSymbolicLinkOverload(__in BOOLEAN GracefulRemove)
Definition: fxpkgpdo.cpp:1630
virtual VOID PnpEventSurpriseRemovePendingOverload(VOID)
Definition: fxpkgpdo.cpp:1282
virtual WDF_DEVICE_PNP_STATE PnpGetPostRemoveState(VOID)
Definition: fxpkgpdo.cpp:1258
virtual _Must_inspect_result_ NTSTATUS ProcessRemoveDeviceOverload(__inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:1753
BOOLEAN m_AddedToStaticList
Definition: fxpkgpdo.hpp:63
static _Must_inspect_result_ NTSTATUS _PnpSurpriseRemoval(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:1561
static VOID STDCALL _RemoveAndReenumerateSelf(__in PVOID Context)
Definition: fxpkgpdo.cpp:1665
VOID HandleQueryCapabilities(__inout PDEVICE_CAPABILITIES ReportedCaps, __in PDEVICE_CAPABILITIES ParentCaps)
Definition: fxpkgpdo.cpp:666
static _Must_inspect_result_ NTSTATUS _PnpQueryDeviceText(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:858
PWSTR m_DeviceID
Definition: fxpkgpdo.hpp:77
virtual _Must_inspect_result_ NTSTATUS SendIrpSynchronously(__in FxIrp *Irp)
Definition: fxpkgpdo.cpp:361
static _Must_inspect_result_ NTSTATUS _PnpEject(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:968
virtual VOID FinishInitialize(__in PWDFDEVICE_INIT DeviceInit)
Definition: fxpkgpdo.cpp:340
_Must_inspect_result_ NTSTATUS HandleQueryInterfaceForReenumerate(__in FxIrp *Irp, __out PBOOLEAN CompleteRequest)
Definition: fxpkgpdo.cpp:1687
FxPowerDeviceDisableWakeAtBus m_DeviceDisableWakeAtBus
Definition: fxpkgpdo.hpp:54
PWSTR m_CompatibleIDs
Definition: fxpkgpdo.hpp:98
static const PFN_PNP_POWER_CALLBACK m_PdoPowerFunctionTable[IRP_MN_QUERY_POWER+1]
Definition: fxpkgpdo.hpp:152
FxRelatedDeviceList * m_EjectionDeviceList
Definition: fxpkgpdo.hpp:113
static VOID STDCALL _QueryCapsWorkItem(__in MdDeviceObject DeviceObject, __in PVOID Context)
Definition: fxpkgpdo.cpp:779
virtual WDF_DEVICE_PNP_STATE PnpEventPdoRemovedOverload(VOID)
Definition: fxpkgpdo.cpp:1208
VOID RemoveEjectionDevice(__in MdDeviceObject DependentDevice)
Definition: fxpkgpdo.cpp:1890
virtual _Must_inspect_result_ NTSTATUS FireAndForgetIrp(__inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:384
virtual _Must_inspect_result_ NTSTATUS Initialize(__in PWDFDEVICE_INIT DeviceInit)
Definition: fxpkgpdo.cpp:184
FxPnpDeviceSetLock m_DeviceSetLock
Definition: fxpkgpdo.hpp:51
static _Must_inspect_result_ NTSTATUS _PnpQueryPnpDeviceState(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:1483
static _Must_inspect_result_ NTSTATUS _PnpQueryInterface(IN FxPkgPnp *This, IN FxIrp *Irp)
Definition: fxpkgpdo.cpp:522
static _Must_inspect_result_ NTSTATUS _PnpSetLock(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:1323
PWSTR m_ContainerID
Definition: fxpkgpdo.hpp:105
PWSTR m_InstanceID
Definition: fxpkgpdo.hpp:84
BOOLEAN m_Static
Definition: fxpkgpdo.hpp:61
static _Must_inspect_result_ NTSTATUS _PnpQueryBusInformation(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:1529
static _Must_inspect_result_ NTSTATUS _PnpQueryDeviceRelations(__in FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:424
FxPnpDeviceResourceRequirementsQuery m_DeviceResourceRequirementsQuery
Definition: fxpkgpdo.hpp:49
virtual _Must_inspect_result_ NTSTATUS QueryForPowerThread(VOID)
Definition: fxpkgpdo.cpp:1804
FxChildList * m_OwningChildList
Definition: fxpkgpdo.hpp:42
LCID m_DefaultLocale
Definition: fxpkgpdo.hpp:38
FxPkgPdo(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in CfxDevice *Device)
Definition: fxpkgpdo.cpp:81
FxDeviceDescriptionEntry * m_Description
Definition: fxpkgpdo.hpp:40
VOID RegisterCallbacks(__in PWDF_PDO_EVENT_CALLBACKS DispatchTable)
Definition: fxpkgpdo.cpp:1576
static _Must_inspect_result_ NTSTATUS _PnpQueryCapabilities(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:551
virtual WDF_DEVICE_PNP_STATE PnpEventFdoRemovedOverload(VOID)
Definition: fxpkgpdo.cpp:1269
FxPnpDeviceEject m_DeviceEject
Definition: fxpkgpdo.hpp:50
_Must_inspect_result_ NTSTATUS AddEjectionDevice(__in MdDeviceObject DependentDevice)
Definition: fxpkgpdo.cpp:1826
BOOLEAN m_EnableWakeAtBusInvoked
Definition: fxpkgpdo.hpp:141
FxPnpDeviceResourcesQuery m_DeviceResourcesQuery
Definition: fxpkgpdo.hpp:48
PWSTR m_HardwareIDs
Definition: fxpkgpdo.hpp:91
virtual _Must_inspect_result_ NTSTATUS AskParentToRemoveAndReenumerate(VOID)
Definition: fxpkgpdo.cpp:1598
FxPnpDeviceReportedMissing m_DeviceReportedMissing
Definition: fxpkgpdo.hpp:57
static _Must_inspect_result_ NTSTATUS _PnpCompleteIrp(__in FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:414
BOOLEAN m_RawOK
Definition: fxpkgpdo.hpp:59
PWSTR m_IDsAllocation
Definition: fxpkgpdo.hpp:111
_Must_inspect_result_ NTSTATUS PnpQueryCapabilities(__inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:561
VOID ClearEjectionDevicesList(VOID)
Definition: fxpkgpdo.cpp:1906
MxEvent * m_DeviceEjectProcessed
Definition: fxpkgpdo.hpp:121
virtual WDF_DEVICE_PNP_STATE PnpEventCheckForDevicePresenceOverload(VOID)
Definition: fxpkgpdo.cpp:1155
static const PFN_PNP_POWER_CALLBACK m_PdoPnpFunctionTable[IRP_MN_SURPRISE_REMOVAL+1]
Definition: fxpkgpdo.hpp:147
BOOLEAN m_CanBeDeleted
Definition: fxpkgpdo.hpp:123
static _Must_inspect_result_ NTSTATUS _PnpQueryId(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:1359
_Must_inspect_result_ NTSTATUS PnpQueryDeviceRelations(__inout FxIrp *Irp)
Definition: fxpkgpdo.cpp:434
ULONG m_PnpCapsUINumber
Definition: fxpkgpnp.hpp:4091
_Must_inspect_result_ NTSTATUS HandleQueryBusInformation(__inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:947
_Must_inspect_result_ NTSTATUS CreatePowerThread(VOID)
Definition: fxpkgpnp.cpp:5125
virtual _Must_inspect_result_ NTSTATUS Initialize(__in PWDFDEVICE_INIT DeviceInit)
Definition: fxpkgpnp.cpp:349
MxEvent * m_DeviceRemoveProcessed
Definition: fxpkgpnp.hpp:4172
_Must_inspect_result_ NTSTATUS HandleQueryDeviceRelations(__inout FxIrp *Irp, __inout FxRelatedDeviceList *List)
Definition: fxpkgpnp.cpp:996
VOID SetPendingPnpIrpStatus(__in NTSTATUS Status)
Definition: fxpkgpnp.hpp:3018
MdIrp ClearPendingPnpIrp(VOID)
Definition: fxpkgpnp.hpp:3029
virtual VOID PnpEventSurpriseRemovePendingOverload(VOID)
LONG GetPnpCapsInternal(VOID)
Definition: fxpkgpnp.cpp:5466
VOID CleanupStateMachines(__in BOOLEAN ClenaupPnp)
Definition: fxpkgpnp.cpp:2066
FxPowerCaps m_PowerCaps
Definition: fxpkgpnp.hpp:4093
_Must_inspect_result_ NTSTATUS HandleQueryBusRelations(__inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:758
ULONG m_PnpCapsAddress
Definition: fxpkgpnp.hpp:4090
VOID DeleteDevice(VOID)
Definition: fxpkgpnp.cpp:2249
SharedPowerData m_SharedPower
Definition: fxpkgpnp.hpp:4161
VOID PnpEventRemovedCommonCode(VOID)
VOID PnpProcessEvent(__in FxPnpEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
NTSTATUS CompletePowerRequest(__inout FxIrp *Irp, __in NTSTATUS Status)
Definition: fxpkgpnp.cpp:5404
FxRelatedDeviceList * m_RemovalDeviceList
Definition: fxpkgpnp.hpp:4115
VOID SetPendingPnpIrp(__inout FxIrp *Irp, __in BOOLEAN MarkIrpPending=TRUE)
Definition: fxpkgpnp.cpp:4883
NTSTATUS CompletePnpRequest(__inout FxIrp *Irp, __in NTSTATUS Status)
Definition: fxpkgpnp.cpp:5752
static DEVICE_POWER_STATE _GetPowerCapState(__in ULONG Index, __in ULONG State)
Definition: fxpkgpnp.cpp:5657
virtual VOID FinishInitialize(__inout PWDFDEVICE_INIT DeviceInit)
Definition: fxpkgpnp.cpp:1240
_Must_inspect_result_ NTSTATUS PnpSurpriseRemoval(__inout FxIrp *Irp)
Definition: fxpkgpnp.cpp:2366
PFN_WDF_DEVICE_EJECT m_Method
_Must_inspect_result_ NTSTATUS Invoke(__in WDFDEVICE Device)
PFN_WDF_DEVICE_REPORTED_MISSING m_Method
PFN_WDF_DEVICE_RESOURCE_REQUIREMENTS_QUERY m_Method
PFN_WDF_DEVICE_RESOURCES_QUERY m_Method
PFN_WDF_DEVICE_SET_LOCK m_Method
PFN_WDF_DEVICE_DISABLE_WAKE_AT_BUS m_Method
PFN_WDF_DEVICE_ENABLE_WAKE_AT_BUS m_Method
VOID UnlockFromEnum(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
_Must_inspect_result_ NTSTATUS Add(__in PFX_DRIVER_GLOBALS Globals, __inout FxRelatedDevice *Entry)
VOID Remove(__in PFX_DRIVER_GLOBALS Globals, __in MdDeviceObject Device)
VOID LockForEnum(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
_Must_inspect_result_ FxRelatedDevice * GetNextEntry(__in_opt FxRelatedDevice *Entry)
__inline VOID SetObject(__in_opt MdDeviceObject DeviceObject)
__inline VOID Set()
Definition: mxeventkm.h:91
MxEvent * GetSelfPointer(VOID)
Definition: mxevent.h:110
static __inline PVOID MxAllocatePoolWithTag(__in POOL_TYPE PoolType, __in SIZE_T NumberOfBytes, __in ULONG Tag)
Definition: mxmemorykm.h:30
__inline MdWorkItem GetWorkItem()
Definition: mxworkitemkm.h:73
__inline VOID Enqueue(__in PMX_WORKITEM_ROUTINE Callback, __in PVOID Context)
Definition: mxworkitemkm.h:58
static __inline VOID _Free(__in MdWorkItem Item)
Definition: mxworkitemkm.h:81
_Must_inspect_result_ __inline NTSTATUS Allocate(__in MdDeviceObject DeviceObject, __in_opt PVOID ThreadPoolEnv=NULL)
Definition: mxworkitemkm.h:41
static __inline VOID MxReleaseRemoveLockAndWait(__in MdRemoveLock RemoveLock, __in PVOID Tag)
Definition: mxgeneralkm.h:288
static __inline BOOLEAN MxHasEnoughRemainingThreadStack(VOID)
Definition: mxgeneralkm.h:298
static __inline VOID MxAssert(__in BOOLEAN Condition)
Definition: mxgeneralkm.h:165
static __inline VOID MxReferenceObject(__in PVOID Object)
Definition: mxgeneralkm.h:238
_In_ PIRP Irp
Definition: csq.h:116
#define __in
Definition: dbghelp.h:35
#define __in_bcount(x)
Definition: dbghelp.h:41
#define __inout
Definition: dbghelp.h:50
#define __out
Definition: dbghelp.h:62
#define TRACINGPNP
Definition: dbgtrace.h:67
#define TRACINGDEVICE
Definition: dbgtrace.h:58
#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
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PagedPool
Definition: env_spec_w32.h:308
FxChildList * pList
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS pFxDriverGlobals
FxDevice * pPdo
FxDeviceText * pDeviceText
SINGLE_LIST_ENTRY * pCur
PSINGLE_LIST_ENTRY ple
FxVerifierDbgBreakPoint(pFxDriverGlobals)
FxPkgPdo * pPkgPdo
@ OkForDownLevel
Definition: fxglobals.h:80
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
FxDeviceText * FindObjectForGivenLocale(__in PSINGLE_LIST_ENTRY Head, __in LCID LocaleId)
Definition: fxpkgpdo.cpp:820
_Must_inspect_result_ NTSTATUS(* PFN_PNP_POWER_CALLBACK)(__inout FxPkgPnp *This, __inout FxIrp *Irp)
Definition: fxpkgpnp.hpp:225
@ FxPnpCapSilentInstallUseDefault
Definition: fxpkgpnp.hpp:309
@ FxPnpCapSilentInstallMask
Definition: fxpkgpnp.hpp:310
@ PnpEventEject
void FxPoolFree(__in_xcount(ptr is at an offset from AllocationStart) PVOID ptr)
Definition: wdfpool.cpp:361
PINTERFACE pInterface
FxIrp * irp
@ FX_TYPE_PACKAGE_PDO
Definition: fxtypes.h:94
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
struct _cl_event * event
Definition: glext.h:7739
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define DO_NOTHING()
Definition: mxgeneral.h:32
IWudfIrp * MdIrp
Definition: mxum.h:103
PIO_WORKITEM MdWorkItem
Definition: mxworkitemkm.h:27
_In_ PNDIS_STRING _In_ PNDIS_STRING _Out_ PDEVICE_OBJECT * pDeviceObject
Definition: ndis.h:4679
#define KernelMode
Definition: asm.h:34
#define UNICODE_NULL
@ SynchronizationEvent
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
@ PowerSystemMaximum
Definition: ntpoapi.h:42
@ PowerSystemWorking
Definition: ntpoapi.h:36
@ PowerDeviceMaximum
Definition: ntpoapi.h:53
enum _DEVICE_POWER_STATE DEVICE_POWER_STATE
enum _SYSTEM_POWER_STATE SYSTEM_POWER_STATE
@ Unlock
Definition: ntsecapi.h:294
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
long LONG
Definition: pedump.c:60
#define SET_POWER_CAP(caps, pCaps, FieldName)
Definition: pnppriv.hpp:289
#define SET_PNP_CAP(caps, pCaps, FieldName)
Definition: pnppriv.hpp:279
PVOID pBuffer
DWORD LCID
Definition: nls.h:13
@ Removable
Definition: arc.h:81
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
PWSTR FxCopyMultiSz(__out LPWSTR Buffer, __in FxCollectionInternal *StringCollection)
Definition: stringutil.cpp:129
size_t FxCalculateTotalMultiSzStringSize(__in __nullnullterminated PCWSTR MultiSz)
Definition: stringutil.cpp:84
size_t FxCalculateTotalStringSize(__in FxCollectionInternal *StringCollection, __in BOOLEAN Verify=FALSE, __out_opt PBOOLEAN ContainsOnlyStrings=NULL)
Definition: stringutil.cpp:32
VOID DeviceSurpriseRemoved(VOID)
BOOLEAN IsDeviceReportedMissing(VOID)
PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER GetId(VOID)
BOOLEAN IsDeviceRemoved(VOID)
FxChildList * GetParentList(VOID)
PWCHAR m_LocationInformation
static FxDeviceText * _FromEntry(__in PSINGLE_LIST_ENTRY Entry)
PWCHAR m_Description
static void _CleanupList(__inout PSINGLE_LIST_ENTRY Head)
ULONG D3Latency
Definition: fxpkgpnp.hpp:425
BYTE SystemWake
Definition: fxpkgpnp.hpp:413
ULONG D2Latency
Definition: fxpkgpnp.hpp:424
ULONG D1Latency
Definition: fxpkgpnp.hpp:423
USHORT Caps
Definition: fxpkgpnp.hpp:406
BYTE DeviceWake
Definition: fxpkgpnp.hpp:412
ULONG States
Definition: fxpkgpnp.hpp:418
SINGLE_LIST_ENTRY DeviceText
BOOLEAN m_WaitWakeOwner
Definition: fxpkgpnp.hpp:186
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
PVOID Context
Definition: miniport.h:123
USHORT Version
Definition: miniport.h:122
USHORT Size
Definition: miniport.h:121
PINTERFACE_REFERENCE InterfaceReference
Definition: miniport.h:124
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: miniport.h:125
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
DEVICE_CAPABILITIES DeviceCaps
Definition: device_common.h:30
Definition: ps.c:97
_Must_inspect_result_ NTSTATUS GetStackCapabilities(__in PFX_DRIVER_GLOBALS DriverGlobals, __in MxDeviceObject *DeviceInStack, __in_opt PD3COLD_SUPPORT_INTERFACE D3ColdInterface, __out PSTACK_DEVICE_CAPABILITIES Capabilities)
Definition: supportkm.cpp:48
rwlock_t lock
Definition: tcpcore.h:0
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ PWDFDEVICE_INIT DeviceInit
Definition: wdfcontrol.h:113
#define WDF_PTR_ADD_OFFSET(_ptr, _offset)
Definition: wdfcore.h:144
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
@ WdfDevStatePnpFinal
Definition: wdfdevice.h:117
@ WdfDevStatePnpEjectedWaitingForRemove
Definition: wdfdevice.h:68
@ WdfDevStatePnpPdoRemoved
Definition: wdfdevice.h:84
@ WdfDevStatePnpRemovedPdoWait
Definition: wdfdevice.h:85
@ WdfDevStatePnpCheckForDevicePresence
Definition: wdfdevice.h:65
@ WdfDevStatePnpEjectFailed
Definition: wdfdevice.h:66
_Must_inspect_result_ _In_ WDFDEVICE _In_ PDEVICE_OBJECT DependentDevice
Definition: wdfdevice.h:2263
enum _WDF_DEVICE_PNP_STATE WDF_DEVICE_PNP_STATE
_In_ PWDFDEVICE_INIT _In_ PWDF_PDO_EVENT_CALLBACKS DispatchTable
Definition: wdfpdo.h:248
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:437
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
DEVICE_CAPABILITIES
Definition: iotypes.h:965
@ EjectionRelations
Definition: iotypes.h:2153
@ RemovalRelations
Definition: iotypes.h:2155
@ BusRelations
Definition: iotypes.h:2152
@ TargetDeviceRelation
Definition: iotypes.h:2156
enum _BUS_QUERY_ID_TYPE BUS_QUERY_ID_TYPE
#define IO_NO_INCREMENT
Definition: iotypes.h:598
ULONG PNP_DEVICE_STATE
Definition: iotypes.h:997
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
struct _REENUMERATE_SELF_INTERFACE_STANDARD * PREENUMERATE_SELF_INTERFACE_STANDARD
* PDEVICE_CAPABILITIES
Definition: iotypes.h:965
@ DeviceTextLocationInformation
Definition: iotypes.h:2946
@ DeviceTextDescription
Definition: iotypes.h:2945
#define IRP_MJ_POWER
@ BusQueryCompatibleIDs
Definition: iotypes.h:2938
@ BusQueryContainerID
Definition: iotypes.h:2941
@ BusQueryInstanceID
Definition: iotypes.h:2939
@ BusQueryDeviceID
Definition: iotypes.h:2936
@ BusQueryHardwareIDs
Definition: iotypes.h:2937
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
#define IRP_MN_QUERY_POWER
@ Executive
Definition: ketypes.h:415
__wchar_t WCHAR
Definition: xmlstorage.h:180