Reactos
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxResourceAPI.cpp
8
9Abstract:
10
11 This module implements the resource class.
12
13Author:
14
15
16
17
18Environment:
19
20 Both kernel and user mode
21
22Revision History:
23
24--*/
25#include "fxsupportpch.hpp"
26
27extern "C" {
28// #include "FxResourceAPI.tmh"
29}
30
31//
32// Extern "C" the entire file
33//
34extern "C" {
35
36__drv_maxIRQL(DISPATCH_LEVEL)
37VOID
38NTAPI
39WDFEXPORT(WdfIoResourceRequirementsListSetSlotNumber)(
40 __in
41 PWDF_DRIVER_GLOBALS DriverGlobals,
42 __in
43 WDFIORESREQLIST RequirementsList,
44 __in
45 ULONG SlotNumber
46 )
47/*++
48
49Routine Description:
50 Sets the slot number for a given resource requirements list
51
52Arguments:
53 RequirementsList - list to be modified
54
55 SlotNumber - slot value to assign
56
57Return Value:
58 None
59
60 --*/
61{
62 FxIoResReqList* pIoResReqList;
63
64 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
65 RequirementsList,
66 FX_TYPE_IO_RES_REQ_LIST,
67 (PVOID*) &pIoResReqList);
68
69 if (pIoResReqList->m_SlotNumber != SlotNumber) {
70 pIoResReqList->MarkChanged();
71 }
72 pIoResReqList->m_SlotNumber = SlotNumber;
73}
74
75__drv_maxIRQL(DISPATCH_LEVEL)
76VOID
77NTAPI
78WDFEXPORT(WdfIoResourceRequirementsListSetInterfaceType)(
79 __in
80 PWDF_DRIVER_GLOBALS DriverGlobals,
81 __in
82 WDFIORESREQLIST RequirementsList,
83 __in
84 __drv_strictTypeMatch(__drv_typeCond)
85 INTERFACE_TYPE InterfaceType
86 )
87/*++
88
89Routine Description:
90 Sets the InterfaceType for a given resource requirements list
91
92Arguments:
93 RequirementsList - list to be modified
94
95 InterfaceType - interface type to assign
96
97Return Value:
98 None
99
100 --*/
101{
102 FxIoResReqList* pIoResReqList;
103
104 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
105 RequirementsList,
106 FX_TYPE_IO_RES_REQ_LIST,
107 (PVOID*) &pIoResReqList);
108
109 if (pIoResReqList->m_InterfaceType != InterfaceType) {
110 pIoResReqList->MarkChanged();
111 }
112
113 pIoResReqList->m_InterfaceType = InterfaceType;
114}
115
116_Must_inspect_result_
117__drv_maxIRQL(DISPATCH_LEVEL)
118NTSTATUS
119FxIoResourceRequirementsListInsertIoResList(
120 __in
121 PWDF_DRIVER_GLOBALS DriverGlobals,
122 __in
123 WDFIORESREQLIST RequirementsList,
124 __in
125 WDFIORESLIST IoResList,
126 ULONG Index
127 )
128/*++
129
130Routine Description:
131 Inserts a resource list into a requirements list at a particular index.
132
133Arguments:
134 RequirementsList - list to be modified
135
136 IoResList - resource list to add
137
138 Index - zero based index to insert at
139
140Return Value:
141 NTSTATUS
142
143 --*/
144{
145 PFX_DRIVER_GLOBALS pFxDriverGlobals;
146 FxIoResReqList* pIoResReqList;
147 FxIoResList* pIoResList;
148 NTSTATUS status;
149
150 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
151 RequirementsList,
152 FX_TYPE_IO_RES_REQ_LIST,
153 (PVOID*) &pIoResReqList,
154 &pFxDriverGlobals);
155
156 FxObjectHandleGetPtr(pFxDriverGlobals,
157 IoResList,
158 FX_TYPE_IO_RES_LIST,
159 (PVOID*) &pIoResList);
160
161 if (pIoResList->m_OwningList != pIoResReqList) {
162 return STATUS_INVALID_DEVICE_REQUEST;
163 }
164
165 status = pIoResReqList->AddAt(Index, pIoResList);
166
167 if (NT_SUCCESS(status)) {
168 //
169 // Mirror the access flags as well.
170 //
171 pIoResList->m_AccessFlags = pIoResReqList->m_AccessFlags;
172 pIoResList->m_OwningList = pIoResReqList;
173 }
174
175 return status;
176}
177
178
179_Must_inspect_result_
180__drv_maxIRQL(DISPATCH_LEVEL)
181NTSTATUS
182NTAPI
183WDFEXPORT(WdfIoResourceRequirementsListInsertIoResList)(
184 __in
185 PWDF_DRIVER_GLOBALS DriverGlobals,
186 __in
187 WDFIORESREQLIST RequirementsList,
188 __in
189 WDFIORESLIST IoResList,
190 __in
191 ULONG Index
192 )
193/*++
194
195Routine Description:
196 Inserts a resource list into a requirements list at a particular index.
197
198Arguments:
199 RequirementsList - list to be modified
200
201 IoResList - resource list to add
202
203 Index - zero based index to insert at
204
205Return Value:
206 NTSTATUS
207
208 --*/
209{
210 return FxIoResourceRequirementsListInsertIoResList(DriverGlobals,
211 RequirementsList,
212 IoResList,
213 Index);
214}
215
216_Must_inspect_result_
217__drv_maxIRQL(DISPATCH_LEVEL)
218NTSTATUS
219NTAPI
220WDFEXPORT(WdfIoResourceRequirementsListAppendIoResList)(
221 __in
222 PWDF_DRIVER_GLOBALS DriverGlobals,
223 __in
224 WDFIORESREQLIST RequirementsList,
225 __in
226 WDFIORESLIST IoResList
227 )
228/*++
229
230Routine Description:
231 Appends a resource list to a resource requirements list
232
233Arguments:
234 RequirementsList - list to be modified
235
236 IoResList - resource list to append
237
238Return Value:
239 NTSTATUS
240
241 --*/
242
243{
244 return FxIoResourceRequirementsListInsertIoResList(DriverGlobals,
245 RequirementsList,
246 IoResList,
247 WDF_INSERT_AT_END);
248}
249
250
251__drv_maxIRQL(DISPATCH_LEVEL)
252ULONG
253NTAPI
254WDFEXPORT(WdfIoResourceRequirementsListGetCount)(
255 __in
256 PWDF_DRIVER_GLOBALS DriverGlobals,
257 __in
258 WDFIORESREQLIST RequirementsList
259 )
260/*++
261
262Routine Description:
263 Returns the number of resource lists in the requirements list
264
265
266Arguments:
267 RequirementsList - requirements list whose count will be returned
268
269Return Value:
270 number of elements in the list
271
272 --*/
273
274{
275 FxIoResReqList* pList;
276 ULONG count;
277 KIRQL irql;
278
279 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
280 RequirementsList,
281 FX_TYPE_IO_RES_REQ_LIST,
282 (PVOID*) &pList);
283
284 pList->Lock(&irql);
285 count = pList->Count();
286 pList->Unlock(irql);
287
288 return count;
289}
290
291__drv_maxIRQL(DISPATCH_LEVEL)
292WDFIORESLIST
293NTAPI
294WDFEXPORT(WdfIoResourceRequirementsListGetIoResList)(
295 __in
296 PWDF_DRIVER_GLOBALS DriverGlobals,
297 __in
298 WDFIORESREQLIST RequirementsList,
299 __in
300 ULONG Index
301 )
302/*++
303
304Routine Description:
305 Retrieves a resource list from the requirements list at a given index.
306
307Arguments:
308 RequirementsList - list to retrieve the resource list from
309
310 Index - zero based index from which to retrieve the list
311
312Return Value:
313 resource list handle or NULL
314
315 --*/
316{
317 FxIoResReqList* pIoResReqList;
318 FxObject* pObject;
319 KIRQL irql;
320
321 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
322 RequirementsList,
323 FX_TYPE_IO_RES_REQ_LIST,
324 (PVOID*) &pIoResReqList);
325
326 pIoResReqList->Lock(&irql);
327 pObject = pIoResReqList->GetItem(Index);
328 pIoResReqList->Unlock(irql);
329
330 if (pObject == NULL) {
331 return NULL;
332 }
333 else {
334 return (WDFIORESLIST) pObject->GetObjectHandle();
335 }
336}
337
338__drv_maxIRQL(DISPATCH_LEVEL)
339VOID
340NTAPI
341WDFEXPORT(WdfIoResourceRequirementsListRemove)(
342 __in
343 PWDF_DRIVER_GLOBALS DriverGlobals,
344 __in
345 WDFIORESREQLIST RequirementsList,
346 __in
347 ULONG Index
348 )
349/*++
350
351Routine Description:
352 Removes a resource list from the requirements list at a given index
353
354Arguments:
355 RequirementsList - list of resource requirements which will be modified
356
357 Index - zero based index which indictes location in the list to find the
358 resource list
359
360Return Value:
361 None
362
363 --*/
364{
365 PFX_DRIVER_GLOBALS pFxDriverGlobals;
366 FxIoResReqList* pList;
367
368 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
369 RequirementsList,
370 FX_TYPE_IO_RES_REQ_LIST,
371 (PVOID*) &pList,
372 &pFxDriverGlobals);
373
374 if (pList->RemoveAndDelete(Index) == FALSE) {
375 DoTraceLevelMessage(
376 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
377 "WDFIORESLIST %p, could not remove list at index %d (not found), "
378 "list item count is %d", RequirementsList, Index, pList->Count());
379
380 FxVerifierDbgBreakPoint(pFxDriverGlobals);
381 }
382}
383
384__drv_maxIRQL(DISPATCH_LEVEL)
385VOID
386NTAPI
387WDFEXPORT(WdfIoResourceRequirementsListRemoveByIoResList)(
388 __in
389 PWDF_DRIVER_GLOBALS DriverGlobals,
390 __in
391 WDFIORESREQLIST RequirementsList,
392 __in
393 WDFIORESLIST IoResList
394 )
395/*++
396
397Routine Description:
398 Removes a resource list from the requirements list based on the resource list's
399 handle
400
401Arguments:
402 RequirementsList - resource requirements list being modified
403
404 IoResList - resource list to be removed
405
406Return Value:
407 None
408
409 --*/
410{
411 PFX_DRIVER_GLOBALS pFxDriverGlobals;
412 FxCollectionEntry* cur, *end;
413 FxIoResReqList* pList;
414 FxIoResList* pResList;
415 KIRQL irql;
416 BOOLEAN listFound;
417
418 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
419 RequirementsList,
420 FX_TYPE_IO_RES_REQ_LIST,
421 (PVOID*) &pList,
422 &pFxDriverGlobals);
423
424 if (pList->IsRemoveAllowed() == FALSE) {
425 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
426 "WDFIORESREQLIST %p: Removes not allowed",
427 RequirementsList);
428
429 FxVerifierDbgBreakPoint(pFxDriverGlobals);
430 return;
431 }
432
433 FxObjectHandleGetPtr(pFxDriverGlobals,
434 IoResList,
435 FX_TYPE_IO_RES_LIST,
436 (PVOID*) &pResList);
437
438 pList->Lock(&irql);
439
440 cur = pList->Start();
441 end = pList->End();
442 listFound = FALSE;
443
444 while (cur != end) {
445 if (cur->m_Object == pResList) {
446 pList->MarkChanged();
447
448 pList->RemoveEntry(cur);
449 listFound = TRUE;
450 break;
451 }
452
453 cur = cur->Next();
454 }
455
456 pList->Unlock(irql);
457
458 if (listFound) {
459 pResList->DeleteObject();
460 pResList = NULL;
461 }
462}
463
464_Must_inspect_result_
465__drv_maxIRQL(DISPATCH_LEVEL)
466NTSTATUS
467NTAPI
468WDFEXPORT(WdfIoResourceListCreate)(
469 __in
470 PWDF_DRIVER_GLOBALS DriverGlobals,
471 __in
472 WDFIORESREQLIST RequirementsList,
473 __in_opt
474 PWDF_OBJECT_ATTRIBUTES Attributes,
475 __out
476 WDFIORESLIST* ResourceList
477 )
478/*++
479
480Routine Description:
481 Creates a resource list.
482
483Arguments:
484 RequirementsList - the resource requirements list that the resource list will
485 be associated with
486
487 Attributes - generic object attributes for the new resource list
488
489 ResourceList - pointer which will receive the new object handle
490
491Return Value:
492 NTSTATUS
493
494 --*/
495{
496 PFX_DRIVER_GLOBALS pFxDriverGlobals;
497 FxIoResReqList* pIoResReqList;
498 FxIoResList* pIoResList;
499 NTSTATUS status;
500
501 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
502 RequirementsList,
503 FX_TYPE_IO_RES_REQ_LIST,
504 (PVOID*) &pIoResReqList,
505 &pFxDriverGlobals);
506
507 FxPointerNotNull(pFxDriverGlobals, ResourceList);
508 *ResourceList = NULL;
509
510 status = FxValidateObjectAttributes(pFxDriverGlobals,
511 Attributes,
512 FX_VALIDATE_OPTION_PARENT_NOT_ALLOWED);
513
514 if (!NT_SUCCESS(status)) {
515 return status;
516 }
517
518 pIoResList = new (pFxDriverGlobals, Attributes) FxIoResList(
519 pFxDriverGlobals, pIoResReqList);
520
521 if (pIoResList == NULL) {
522 return STATUS_INSUFFICIENT_RESOURCES;
523 }
524
525 status = pIoResList->Commit(Attributes,
526 (WDFOBJECT*) ResourceList,
527 pIoResReqList);
528
529 if (!NT_SUCCESS(status)) {
530 pIoResList->DeleteFromFailedCreate();
531 }
532
533 return status;
534}
535
536_Must_inspect_result_
537__drv_maxIRQL(DISPATCH_LEVEL)
538NTSTATUS
539FxIoResourceListInsertDescriptor(
540 __in
541 PWDF_DRIVER_GLOBALS DriverGlobals,
542 __in
543 WDFIORESLIST ResourceList,
544 __in
545 PIO_RESOURCE_DESCRIPTOR Descriptor,
546 ULONG Index
547 )
548/*++
549
550Routine Description:
551 Inserts a descriptor into a resource list at a particular index.
552
553Arguments:
554 ResourceList - list to be modified
555
556 Descriptor - descriptor to insert
557
558 Index - zero based index to insert at
559
560Return Value:
561 NTSTATUS
562
563 --*/
564{
565 PFX_DRIVER_GLOBALS pFxDriverGlobals;
566 FxIoResList* pList;
567 FxResourceIo* pObject;
568 NTSTATUS status;
569
570 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
571 ResourceList,
572 FX_TYPE_IO_RES_LIST,
573 (PVOID*) &pList,
574 &pFxDriverGlobals);
575
576 FxPointerNotNull(pFxDriverGlobals, Descriptor);
577
578 if (pList->m_OwningList->IsAddAllowed() == FALSE) {
579 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
580 "Removes not allowed on WDFIORESLIST %p",
581 ResourceList);
582 FxVerifierDbgBreakPoint(pFxDriverGlobals);
583 return STATUS_ACCESS_DENIED;
584 }
585
586 pObject = new(pFxDriverGlobals)
587 FxResourceIo(pFxDriverGlobals, Descriptor);
588
589 if (pObject == NULL) {
590 return STATUS_INSUFFICIENT_RESOURCES;
591 }
592
593 status = pObject->AssignParentObject(pList);
594 if (!NT_SUCCESS(status)) {
595 pObject->DeleteObject();
596 return status;
597 }
598
599 status = pList->AddAt(Index, pObject);
600
601 //
602 // Mark both this list and its owning list as changed so when it comes
603 // time to evaluate the entire requirements list for changes, we do not
604 // have to iterate over all the resource lists.
605 //
606 if (NT_SUCCESS(status)) {
607 pList->m_OwningList->MarkChanged();
608 }
609
610 return status;
611}
612
613_Must_inspect_result_
614__drv_maxIRQL(DISPATCH_LEVEL)
615NTSTATUS
616NTAPI
617WDFEXPORT(WdfIoResourceListInsertDescriptor)(
618 __in
619 PWDF_DRIVER_GLOBALS DriverGlobals,
620 __in
621 WDFIORESLIST ResourceList,
622 __in
623 PIO_RESOURCE_DESCRIPTOR Descriptor,
624 __in
625 ULONG Index
626 )
627/*++
628
629Routine Description:
630 Inserts a descriptor into a resource list at a particular index.
631
632Arguments:
633 ResourceList - list to be modified
634
635 Descriptor - descriptor to insert
636
637 Index - zero based index to insert at
638
639Return Value:
640 NTSTATUS
641
642 --*/
643{
644 return FxIoResourceListInsertDescriptor(DriverGlobals,
645 ResourceList,
646 Descriptor,
647 Index);
648}
649
650_Must_inspect_result_
651__drv_maxIRQL(DISPATCH_LEVEL)
652NTSTATUS
653NTAPI
654WDFEXPORT(WdfIoResourceListAppendDescriptor)(
655 __in
656 PWDF_DRIVER_GLOBALS DriverGlobals,
657 __in
658 WDFIORESLIST ResourceList,
659 __in
660 PIO_RESOURCE_DESCRIPTOR Descriptor
661 )
662/*++
663
664Routine Description:
665 Appends a descriptor to a resource list
666
667Arguments:
668 ResourceList - list to be modified
669
670 Descriptor - item to be appended
671
672Return Value:
673 NTSTATUS
674
675 --*/
676{
677 return FxIoResourceListInsertDescriptor(DriverGlobals,
678 ResourceList,
679 Descriptor,
680 WDF_INSERT_AT_END);
681}
682
683__drv_maxIRQL(DISPATCH_LEVEL)
684VOID
685NTAPI
686WDFEXPORT(WdfIoResourceListUpdateDescriptor)(
687 __in
688 PWDF_DRIVER_GLOBALS DriverGlobals,
689 __in
690 WDFIORESLIST ResourceList,
691 __in
692 PIO_RESOURCE_DESCRIPTOR Descriptor,
693 __in
694 ULONG Index
695 )
696/*++
697
698Routine Description:
699 Updates resource requirement in place in the list.
700
701Arguments:
702 ResourceList - list to be modified
703
704 Descriptor - Pointer to descriptor whic contains the updated value
705
706 Index - zero based location in the list to update
707
708Return Value:
709 None
710
711 --*/
712{
713 PFX_DRIVER_GLOBALS pFxDriverGlobals;
714 FxIoResList* pList;
715 FxResourceIo* pObject;
716 KIRQL irql;
717
718 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
719 ResourceList,
720 FX_TYPE_IO_RES_LIST,
721 (PVOID*) &pList,
722 &pFxDriverGlobals);
723
724 FxPointerNotNull(pFxDriverGlobals, Descriptor);
725
726 pList->Lock(&irql);
727 pObject = (FxResourceIo*) pList->GetItem(Index);
728 pList->Unlock(irql);
729
730 if (pObject != NULL) {
731 //
732 // We don't check for add or remove access because we don't know what
733 // the update is actually doing (ie widening a range, shortening it, etc).
734 // For this operation we have to trust the driver that it is doing the
735 // right thing at the right time.
736 //
737 RtlCopyMemory(&pObject->m_Descriptor,
738 Descriptor,
739 sizeof(pObject->m_Descriptor));
740
741 //
742 // Mark both this list and its owning list as changed so when it comes
743 // time to evaluate the entire requirements list for changes, we do not
744 // have to iterate over all the resource lists.
745 //
746 pList->MarkChanged();
747 pList->m_OwningList->MarkChanged();
748 }
749 else {
750 DoTraceLevelMessage(
751 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
752 "WDFIORESREQLIST %p, cannot update item at index %d, item not found,"
753 " list item count is %d", ResourceList, Index, pList->Count());
754
755 FxVerifierDbgBreakPoint(pFxDriverGlobals);
756 }
757}
758
759__drv_maxIRQL(DISPATCH_LEVEL)
760ULONG
761NTAPI
762WDFEXPORT(WdfIoResourceListGetCount)(
763 __in
764 PWDF_DRIVER_GLOBALS DriverGlobals,
765 __in
766 WDFIORESLIST ResourceList
767 )
768/*++
769
770Routine Description:
771 Returns the number of descriptors in the resource list
772
773Arguments:
774 ResourceList - resource list whose count will be returned
775
776Return Value:
777 number of elements in the list
778
779 --*/
780{
781 FxIoResList* pList;
782 ULONG count;
783 KIRQL irql;
784
785 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
786 ResourceList,
787 FX_TYPE_IO_RES_LIST,
788 (PVOID*) &pList);
789
790 pList->Lock(&irql);
791 count = pList->Count();
792 pList->Unlock(irql);
793
794 return count;
795}
796
797
798__drv_maxIRQL(DISPATCH_LEVEL)
799PIO_RESOURCE_DESCRIPTOR
800NTAPI
801WDFEXPORT(WdfIoResourceListGetDescriptor)(
802 __in
803 PWDF_DRIVER_GLOBALS DriverGlobals,
804 __in
805 WDFIORESLIST ResourceList,
806 __in
807 ULONG Index
808 )
809/*++
810
811Routine Description:
812 Retrieves an io resource desciptor for a given index in the resource list
813
814Arguments:
815 ResourceList - list being looked up
816
817 Index - zero based index into the list to find the value of
818
819Return Value:
820 pointer to an io resource descriptor upon success, NULL upon error
821
822 --*/
823
824{
825 FxIoResList* pList;
826 FxResourceIo* pObject;
827 KIRQL irql;
828
829 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
830 ResourceList,
831 FX_TYPE_IO_RES_LIST,
832 (PVOID*) &pList);
833
834 pList->Lock(&irql);
835 pObject = (FxResourceIo*) pList->GetItem(Index);
836 pList->Unlock(irql);
837
838 if (pObject == NULL) {
839 return NULL;
840 }
841 else {
842 //
843 // Copy the current descriptor to the clone and return it
844 //
845 RtlCopyMemory(&pObject->m_DescriptorClone,
846 &pObject->m_Descriptor,
847 sizeof(pObject->m_Descriptor));
848
849 return &pObject->m_DescriptorClone;
850 }
851}
852
853__drv_maxIRQL(DISPATCH_LEVEL)
854VOID
855NTAPI
856WDFEXPORT(WdfIoResourceListRemove)(
857 __in
858 PWDF_DRIVER_GLOBALS DriverGlobals,
859 __in
860 WDFIORESLIST ResourceList,
861 __in
862 ULONG Index
863 )
864/*++
865
866Routine Description:
867 Removes a descriptor in an io resource list
868
869Arguments:
870 ResourceList - resource list to modify
871
872 Index - zero based index into the list in which to remove the descriptor
873
874Return Value:
875 None
876
877 --*/
878{
879 PFX_DRIVER_GLOBALS pFxDriverGlobals;
880 FxIoResList* pList;
881
882 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
883 ResourceList,
884 FX_TYPE_IO_RES_LIST,
885 (PVOID*) &pList,
886 &pFxDriverGlobals);
887
888 if (pList->RemoveAndDelete(Index)) {
889 //
890 // Mark this list's owning list as changed so when it comes
891 // time to evaluate the entire requirements list for changes, we do not
892 // have to iterate over all the resource lists.
893 //
894 // RemoveAndDelete marked pList as changed already
895 //
896 pList->m_OwningList->MarkChanged();
897 }
898 else {
899 DoTraceLevelMessage(
900 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
901 "WDFIORESLIST %p, could not remove item at index %d (not found), "
902 "list item count is %d", ResourceList, Index, pList->Count());
903
904 FxVerifierDbgBreakPoint(pFxDriverGlobals);
905 }
906}
907
908__drv_maxIRQL(DISPATCH_LEVEL)
909VOID
910NTAPI
911WDFEXPORT(WdfIoResourceListRemoveByDescriptor)(
912 __in
913 PWDF_DRIVER_GLOBALS DriverGlobals,
914 __in
915 WDFIORESLIST ResourceList,
916 __in
917 PIO_RESOURCE_DESCRIPTOR Descriptor
918 )
919/*++
920
921Routine Description:
922 Removes a descriptor by value in a given io resource list. Equality is
923 determined by RtlCompareMemory.
924
925Arguments:
926 ResourceList - the io resource list to modify
927
928 Descriptor - pointer to a descriptor to remove.
929
930Return Value:
931 None
932
933 --*/
934{
935 PFX_DRIVER_GLOBALS pFxDriverGlobals;
936 FxCollectionEntry* cur, *end;
937 FxIoResList* pList;
938 FxResourceIo* pObject;
939 KIRQL irql;
940
941 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
942 ResourceList,
943 FX_TYPE_IO_RES_LIST,
944 (PVOID*) &pList,
945 &pFxDriverGlobals);
946
947 FxPointerNotNull(pFxDriverGlobals, Descriptor);
948
949 if (pList->IsRemoveAllowed() == FALSE) {
950 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
951 "Removes not allowed on WDFIORESLIST %p",
952 ResourceList);
953
954 FxVerifierDbgBreakPoint(pFxDriverGlobals);
955 return;
956 }
957
958 pList->Lock(&irql);
959
960 cur = pList->Start();
961 end = pList->End();
962 pObject = NULL;
963
964 while (cur != end) {
965 pObject = (FxResourceIo*) cur->m_Object;
966
967 if (RtlCompareMemory(&pObject->m_Descriptor,
968 Descriptor,
969 sizeof(*Descriptor)) == sizeof(*Descriptor)) {
970 //
971 // Mark both this list and its owning list as changed so when it
972 // comes time to evaluate the entire requirements list for
973 // changes, we do not have to iterate over all the resource lists.
974 //
975 pList->MarkChanged();
976 pList->m_OwningList->MarkChanged();
977
978 pList->RemoveEntry(cur);
979 break;
980 }
981
982 //
983 // Set to NULL so that we do not delete it if this is the last item in
984 // the list.
985 //
986 pObject = NULL;
987
988 cur = cur->Next();
989 }
990
991 pList->Unlock(irql);
992
993 if (pObject != NULL) {
994 pObject->DeleteObject();
995 }
996}
997
998_Must_inspect_result_
999__drv_maxIRQL(DISPATCH_LEVEL)
1000NTSTATUS
1001FxCmResourceListInsertDescriptor(
1002 __in
1003 PWDF_DRIVER_GLOBALS DriverGlobals,
1004 __in
1005 WDFCMRESLIST List,
1006 __in
1007 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
1008 __in
1009 ULONG Index
1010 )
1011/*++
1012
1013Routine Description:
1014 Inserts a descriptor into a cm resource list at a particular index.
1015
1016Arguments:
1017 ResourceList - list to be modified
1018
1019 Descriptor - descriptor to insert
1020
1021 Index - zero based index to insert at
1022
1023Return Value:
1024 NTSTATUS
1025
1026 --*/
1027{
1028 PFX_DRIVER_GLOBALS pFxDriverGlobals;
1029 FxCmResList* pList;
1030 FxResourceCm* pObject;
1031 NTSTATUS status;
1032
1033 pFxDriverGlobals = GetFxDriverGlobals(DriverGlobals);
1034
1035 FxPointerNotNull(pFxDriverGlobals, Descriptor);
1036
1037 FxObjectHandleGetPtr(pFxDriverGlobals,
1038 List,
1039 FX_TYPE_CM_RES_LIST,
1040 (PVOID*) &pList);
1041
1042 pObject = new(pFxDriverGlobals) FxResourceCm(pFxDriverGlobals, Descriptor);
1043
1044 if (pObject == NULL) {
1045 return STATUS_INSUFFICIENT_RESOURCES;
1046 }
1047
1048 status = pObject->AssignParentObject(pList);
1049 if (!NT_SUCCESS(status)) {
1050 pObject->DeleteObject();
1051 return status;
1052 }
1053
1054 return pList->AddAt(Index, pObject);
1055}
1056
1057_Must_inspect_result_
1058__drv_maxIRQL(DISPATCH_LEVEL)
1059NTSTATUS
1060NTAPI
1061WDFEXPORT(WdfCmResourceListInsertDescriptor)(
1062 __in
1063 PWDF_DRIVER_GLOBALS DriverGlobals,
1064 __in
1065 WDFCMRESLIST List,
1066 __in
1067 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
1068 __in
1069 ULONG Index
1070 )
1071/*++
1072
1073Routine Description:
1074 Inserts a descriptor into a cm resource list at a particular index.
1075
1076Arguments:
1077 ResourceList - list to be modified
1078
1079 Descriptor - descriptor to insert
1080
1081 Index - zero based index to insert at
1082
1083Return Value:
1084 NTSTATUS
1085
1086 --*/
1087{
1088 DDI_ENTRY();
1089
1090 return FxCmResourceListInsertDescriptor(DriverGlobals,
1091 List,
1092 Descriptor,
1093 Index);
1094}
1095
1096_Must_inspect_result_
1097__drv_maxIRQL(DISPATCH_LEVEL)
1098NTSTATUS
1099NTAPI
1100WDFEXPORT(WdfCmResourceListAppendDescriptor)(
1101 __in
1102 PWDF_DRIVER_GLOBALS DriverGlobals,
1103 __in
1104 WDFCMRESLIST List,
1105 __in
1106 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
1107 )
1108/*++
1109
1110Routine Description:
1111 Appends a descriptor to a cm resource list
1112
1113Arguments:
1114 ResourceList - list to be modified
1115
1116 Descriptor - item to be appended
1117
1118Return Value:
1119 NTSTATUS
1120
1121 --*/
1122{
1123 DDI_ENTRY();
1124
1125 return FxCmResourceListInsertDescriptor(DriverGlobals,
1126 List,
1127 Descriptor,
1128 WDF_INSERT_AT_END);
1129}
1130
1131__drv_maxIRQL(DISPATCH_LEVEL)
1132ULONG
1133NTAPI
1134WDFEXPORT(WdfCmResourceListGetCount)(
1135 __in
1136 PWDF_DRIVER_GLOBALS DriverGlobals,
1137 __in
1138 WDFCMRESLIST List
1139 )
1140/*++
1141
1142Routine Description:
1143 Returns the number of cm descriptors in the resource list
1144
1145Arguments:
1146 ResourceList - resource list whose count will be returned
1147
1148Return Value:
1149 number of elements in the list
1150
1151 --*/
1152{
1153 FxCmResList* pList;
1154
1155 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
1156 List,
1157 FX_TYPE_CM_RES_LIST,
1158 (PVOID*) &pList);
1159
1160 return pList->GetCount();
1161}
1162
1163
1164__drv_maxIRQL(DISPATCH_LEVEL)
1165PCM_PARTIAL_RESOURCE_DESCRIPTOR
1166NTAPI
1167WDFEXPORT(WdfCmResourceListGetDescriptor)(
1168 __in
1169 PWDF_DRIVER_GLOBALS DriverGlobals,
1170 __in
1171 WDFCMRESLIST List,
1172 __in
1173 ULONG Index
1174 )
1175/*++
1176
1177Routine Description:
1178 Retrieves a cm resource desciptor for a given index in the resource list
1179
1180Arguments:
1181 ResourceList - list being looked up
1182
1183 Index - zero based index into the list to find the value of
1184
1185Return Value:
1186 pointer to a cm resource descriptor upon success, NULL upon error
1187
1188 --*/
1189{
1190 DDI_ENTRY();
1191
1192 FxCmResList* pList;
1193
1194 FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals),
1195 List,
1196 FX_TYPE_CM_RES_LIST,
1197 (PVOID*) &pList);
1198
1199 return pList->GetDescriptor(Index);
1200}
1201
1202__drv_maxIRQL(DISPATCH_LEVEL)
1203VOID
1204NTAPI
1205WDFEXPORT(WdfCmResourceListRemove)(
1206 __in
1207 PWDF_DRIVER_GLOBALS DriverGlobals,
1208 __in
1209 WDFCMRESLIST List,
1210 __in
1211 ULONG Index
1212 )
1213/*++
1214
1215Routine Description:
1216 Removes a descriptor in an cm resource list
1217
1218Arguments:
1219 ResourceList - resource list to modify
1220
1221 Index - zero based index into the list in which to remove the descriptor
1222
1223Return Value:
1224 None
1225
1226 --*/
1227{
1228 DDI_ENTRY();
1229
1230 PFX_DRIVER_GLOBALS pFxDriverGlobals;
1231 FxCmResList* pList;
1232
1233 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
1234 List,
1235 FX_TYPE_CM_RES_LIST,
1236 (PVOID*) &pList,
1237 &pFxDriverGlobals);
1238
1239 if (pList->RemoveAndDelete(Index) == FALSE) {
1240 DoTraceLevelMessage(
1241 pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
1242 "WDFCMRESLIST %p, could not remove list at index %d (not found), "
1243 "list item count is %d", List, Index, pList->Count());
1244
1245 FxVerifierDbgBreakPoint(pFxDriverGlobals);
1246 }
1247}
1248
1249__drv_maxIRQL(DISPATCH_LEVEL)
1250VOID
1251NTAPI
1252WDFEXPORT(WdfCmResourceListRemoveByDescriptor)(
1253 __in
1254 PWDF_DRIVER_GLOBALS DriverGlobals,
1255 __in
1256 WDFCMRESLIST List,
1257 __in
1258 PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
1259 )
1260/*++
1261
1262Routine Description:
1263 Removes a descriptor by value in a given cm resource list. Equality is
1264 determined by RtlCompareMemory.
1265
1266Arguments:
1267 ResourceList - the io resource list to modify
1268
1269 Descriptor - pointer to a descriptor to remove.
1270
1271Return Value:
1272 None
1273
1274 --*/
1275{
1276 DDI_ENTRY();
1277
1278 PFX_DRIVER_GLOBALS pFxDriverGlobals;
1279 FxCollectionEntry* cur;
1280 FxCollectionEntry* end;
1281 FxCmResList* pList;
1282 FxResourceCm* pObject;
1283 KIRQL irql;
1284
1285 FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals),
1286 List,
1287 FX_TYPE_CM_RES_LIST,
1288 (PVOID*) &pList,
1289 &pFxDriverGlobals);
1290
1291 FxPointerNotNull(pFxDriverGlobals, Descriptor);
1292
1293 if (pList->IsRemoveAllowed() == FALSE) {
1294 DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP,
1295 "Removes not allowed on WDFCMRESLIST %p", List);
1296
1297 FxVerifierDbgBreakPoint(pFxDriverGlobals);
1298 return;
1299 }
1300
1301 pList->Lock(&irql);
1302
1303 cur = pList->Start();
1304 end = pList->End();
1305 pObject = NULL;
1306
1307 while (cur != end) {
1308 pObject = (FxResourceCm*) cur->m_Object;
1309
1310 if (RtlCompareMemory(&pObject->m_Descriptor,
1311 Descriptor,
1312 sizeof(*Descriptor)) == sizeof(*Descriptor)) {
1313 pList->MarkChanged();
1314
1315 pList->RemoveEntry(cur);
1316 break;
1317 }
1318
1319 //
1320 // Set to NULL so that we do not delete it if this is the last item in
1321 // the list.
1322 //
1323 pObject = NULL;
1324
1325 cur = cur->Next();
1326 }
1327
1328 pList->Unlock(irql);
1329
1330 if (pObject != NULL) {
1331 pObject->DeleteObject();
1332 pObject = NULL;
1333 }
1334}
1335
1336} // extern "C"