ReactOS 0.4.17-dev-923-g4c9a150
ordering.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Arbitration Library
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Ordering lists and the registry assignment ordering
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include <ntifs.h>
11#include <ndk/rtlfuncs.h>
12#include "arbiter.h"
13
14#define NDEBUG
15#include <debug.h>
16
17#define ARBITER_ORDERING_GRANULARITY 16
18#define ARBITER_ORDERING_LIMIT 1024
19
20#define ARBP_POLICY_ROOT L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Arbiters\\"
21#define ARBP_LONGEST_SUBKEY L"ReservedResources"
22
23/*
24 * The PCI-Express enhanced-config (MMCONFIG / ECAM) MMIO window the memory
25 * arbiter must never hand out. Recorded by
26 * ArbiterLibAddMmConfigRangeAsBootReserved; Start > End (the initial state)
27 */
30
31/* ORDERING LISTS *************************************************************/
32
33/* Set up an empty ordering array at its starting capacity. */
34CODE_SEG("PAGE")
35static
38 _Out_ PARBITER_ORDERING_LIST OrderingList)
39{
40 PAGED_CODE();
41
42 OrderingList->Orderings = ExAllocatePoolWithTag(PagedPool,
45 if (OrderingList->Orderings == NULL)
46 {
47 OrderingList->Count = 0;
48 OrderingList->Maximum = 0;
50 }
51
52 OrderingList->Count = 0;
53 OrderingList->Maximum = ARBITER_ORDERING_GRANULARITY;
54 return STATUS_SUCCESS;
55}
56
57CODE_SEG("PAGE")
58VOID
62{
63 PAGED_CODE();
64
65 if (OrderingList->Orderings != NULL)
66 ExFreePoolWithTag(OrderingList->Orderings, TAG_ARBITER);
67
68 OrderingList->Orderings = NULL;
69 OrderingList->Count = 0;
70 OrderingList->Maximum = 0;
71}
72
73/* Append one [Start, End] window (both bounds inclusive) at the tail
74 * (= lowest preference so far). */
75CODE_SEG("PAGE")
81 _In_ UINT64 End)
82{
83 PAGED_CODE();
84
85 if (End < Start)
87
88 /* Double the array capacity when it fills up, up to the sanity cap. */
89 if (OrderingList->Count == OrderingList->Maximum)
90 {
91 ULONG NewMaximum;
92 PARBITER_ORDERING NewArray;
93
94 NewMaximum = OrderingList->Maximum ? (ULONG)OrderingList->Maximum * 2
96 if (NewMaximum > ARBITER_ORDERING_LIMIT)
98
100 NewMaximum * sizeof(ARBITER_ORDERING),
102 if (NewArray == NULL)
104
105 if (OrderingList->Orderings != NULL)
106 {
107 RtlCopyMemory(NewArray, OrderingList->Orderings,
108 OrderingList->Count * sizeof(ARBITER_ORDERING));
109 ExFreePoolWithTag(OrderingList->Orderings, TAG_ARBITER);
110 }
111
112 OrderingList->Maximum = (UINT16)NewMaximum;
113 OrderingList->Orderings = NewArray;
114 }
115
116 OrderingList->Orderings[OrderingList->Count].Start = Start;
117 OrderingList->Orderings[OrderingList->Count].End = End;
118 OrderingList->Count++;
119 return STATUS_SUCCESS;
120}
121
143CODE_SEG("PAGE")
144static
147 _Inout_ PARBITER_ORDERING_LIST OrderingList,
149 _In_ UINT64 End)
150{
154
155 PAGED_CODE();
156
157 if (End < Start)
159
161 if (!NT_SUCCESS(Status))
162 return Status;
163
164 for (Index = 0; Index < OrderingList->Count; ++Index)
165 {
166 UINT64 CurrentStart = OrderingList->Orderings[Index].Start;
167 UINT64 CurrentEnd = OrderingList->Orderings[Index].End;
168
170
171 if (CurrentEnd < Start || CurrentStart > End)
172 {
173 /* Wholly outside the hole: survives unchanged. */
174 Status = ArbiterLibAddOrdering(&Pruned, CurrentStart, CurrentEnd);
175 }
176 else
177 {
178 if (CurrentStart < Start) /* Left fragment survives */
179 Status = ArbiterLibAddOrdering(&Pruned, CurrentStart, Start - 1);
180
181 if (NT_SUCCESS(Status) && CurrentEnd > End) /* Right fragment survives */
182 Status = ArbiterLibAddOrdering(&Pruned, End + 1, CurrentEnd);
183 }
184
185 if (!NT_SUCCESS(Status))
186 {
188 return Status;
189 }
190 }
191
192 ArbiterLibFreeOrderingList(OrderingList);
193 *OrderingList = Pruned;
194 return STATUS_SUCCESS;
195}
196
197/* REGISTRY-DESCRIBED RANGES **************************************************/
198
199/*
200 * An arbiter refines its allocation policy from HKLM\...\Control\Arbiters.
201 * Each value there is a REG_RESOURCE_REQUIREMENTS_LIST whose descriptors give
202 * [MinimumAddress, MaximumAddress] ranges, filtered by the arbiter's resource
203 * This can get written to by chipset drivers.
204 */
205
206typedef VOID
208 _In_ PARBITER_INSTANCE Arbiter,
211 _In_ ULONGLONG End);
212
213/* Open one subkey of the Arbiters policy key by composing its full path. */
214CODE_SEG("PAGE")
215static
220{
221 WCHAR PathBuffer[sizeof(ARBP_POLICY_ROOT ARBP_LONGEST_SUBKEY) / sizeof(WCHAR)];
222 UNICODE_STRING KeyPath;
225
226 PAGED_CODE();
227
228 RtlInitEmptyUnicodeString(&KeyPath, PathBuffer, sizeof(PathBuffer));
230 if (NT_SUCCESS(Status))
232 if (!NT_SUCCESS(Status))
233 return Status;
234
237 return ZwOpenKey(KeyHandle, KEY_READ, &ObjectAttributes);
238}
239
240/* Read one value into a freshly-allocated KEY_VALUE_FULL_INFORMATION. */
241CODE_SEG("PAGE")
242static
248{
249 UNICODE_STRING NameString;
251 ULONG Size = 0;
254
255 PAGED_CODE();
256
257 RtlInitUnicodeString(&NameString, ValueName);
258
259 /* Size probe: only a buffer-size result means the value is readable. */
260 Status = ZwQueryValueKey(KeyHandle, &NameString, KeyValueFullInformationAlign64,
261 NULL, 0, &Size);
264
266 if (Buffer == NULL)
268
269 Status = ZwQueryValueKey(KeyHandle, &NameString, KeyValueFullInformationAlign64,
271
272 if (NT_SUCCESS(Status) &&
273 ((ULONGLONG)Buffer->DataOffset + Buffer->DataLength > ResultLength))
274 {
276 }
277
278 if (!NT_SUCCESS(Status))
279 {
281 return Status;
282 }
283
284 *Value = Buffer;
285 return STATUS_SUCCESS;
286}
287
288/* Does a policy descriptor apply to this arbiter's resource type? */
289CODE_SEG("PAGE")
290static
293 _In_ PARBITER_INSTANCE Arbiter,
295{
296 PAGED_CODE();
297
298 if (DescriptorType == (UCHAR)Arbiter->ResourceType)
299 return TRUE;
300
301 /* Large-memory descriptors also satisfy the plain memory arbiter. */
303 Arbiter->ResourceType == CmResourceTypeMemory);
304}
305
306/*
307 * Walk the policy ranges stored under HKLM\...\Control\Arbiters<Subkey>,
308 * This is used by machine-specific policy tables.
309 */
310CODE_SEG("PAGE")
311static
314 _In_ PARBITER_INSTANCE Arbiter,
315 _In_ PCWSTR Subkey,
320{
324
325 PAGED_CODE();
326
328 return STATUS_SUCCESS;
329
331
332 /* Follow a REG_SZ indirection to the named sibling value. */
333 if (NT_SUCCESS(Status) && Value->Type == REG_SZ)
334 {
335 PWSTR TargetName = (PWSTR)((PUCHAR)Value + Value->DataOffset);
336 ULONG TargetChars = Value->DataLength / sizeof(WCHAR);
338
339 if (TargetChars != 0 &&
340 TargetName[TargetChars - 1] == UNICODE_NULL &&
342 {
344 Value = Target;
345 }
346 }
347
348 if (NT_SUCCESS(Status) &&
350 Value->DataLength >= sizeof(IO_RESOURCE_REQUIREMENTS_LIST))
351 {
353 PIO_RESOURCE_LIST Alternative;
354 PUCHAR DataEnd;
355 ULONG Index;
356
357 Requirements = (PIO_RESOURCE_REQUIREMENTS_LIST)((PUCHAR)Value + Value->DataOffset);
358 DataEnd = (PUCHAR)Requirements + Value->DataLength;
359 Alternative = &Requirements->List[0];
360
361 for (Index = 0; Index < Alternative->Count; ++Index)
362 {
365 UINT64 Minimum, Maximum, Length, Alignment;
366
367 /* Never trust the stored Count past the actual value data. */
368 if ((PUCHAR)(Descriptor + 1) > DataEnd)
369 break;
370
371 /*
372 * Policy windows are written in bus-relative terms, so an arbiter
373 * that allocates in a different space translates each one first.
374 * A window it cannot translate comes back CmResourceTypeNull and
375 * is dropped by the type test below.
376 */
377 if (Translate != NULL)
378 {
379 Status = Translate(&Window, Descriptor);
380 if (!NT_SUCCESS(Status))
381 break;
382 }
383 else
384 {
386 }
387
388 if (!ArbpDescriptorMatchesArbiter(Arbiter, Window.Type))
389 continue;
390
391 /*
392 * Decode through the arbiter's own callback: the bounds live in a
393 * different union member for every resource type.
394 */
395 Status = Arbiter->UnpackRequirement(&Window, &Minimum, &Maximum,
396 &Length, &Alignment);
397 if (!NT_SUCCESS(Status))
398
399 break;
400 Callback(Arbiter, Context, Minimum, Maximum);
401 }
402 }
403
404 if (Value != NULL)
407 return STATUS_SUCCESS;
408}
409
410/* Prepend a registry-described preferred range ahead of the full-range default. */
411CODE_SEG("PAGE")
412static
413VOID
414NTAPI
416 _In_ PARBITER_INSTANCE Arbiter,
419 _In_ ULONGLONG End)
420{
421 PAGED_CODE();
423 ArbiterLibAddOrdering(&Arbiter->OrderingList, Start, End);
424}
425
452CODE_SEG("PAGE")
453static
454VOID
455NTAPI
457 _In_ PARBITER_INSTANCE Arbiter,
460 _In_ ULONGLONG End)
461{
462 PAGED_CODE();
464
465 if (NT_SUCCESS(ArbiterLibAddOrdering(&Arbiter->ReservedList, Start, End)))
466 ArbpExcludeOrderingRange(&Arbiter->OrderingList, Start, End);
467}
468
486CODE_SEG("PAGE")
487static
488VOID
489NTAPI
491 _In_ PARBITER_INSTANCE Arbiter,
494 _In_ ULONGLONG End)
495{
496 PAGED_CODE();
497 UNREFERENCED_PARAMETER(Arbiter);
500}
501
519CODE_SEG("PAGE")
520static
521VOID
522NTAPI
524 _In_ PARBITER_INSTANCE Arbiter,
527 _In_ ULONGLONG End)
528{
529 PAGED_CODE();
530 UNREFERENCED_PARAMETER(Arbiter);
531
533 ArbpMmConfigEnd = End;
536}
537
568CODE_SEG("PAGE")
570NTAPI
573 _In_ PCWSTR AllocationOrderName,
574 _In_ PCWSTR ReservedResourcesName,
575 _In_opt_ PARB_TRANSLATE_ORDERING TranslateOrderingFunction)
576{
578
579 PAGED_CODE();
580
581 ArbiterLibFreeOrderingList(&Arbiter->OrderingList);
582 ArbiterLibFreeOrderingList(&Arbiter->ReservedList);
583
584 Status = ArbpCreateOrderingList(&Arbiter->OrderingList);
585 if (!NT_SUCCESS(Status))
586 return Status;
587 Status = ArbpCreateOrderingList(&Arbiter->ReservedList);
588 if (!NT_SUCCESS(Status))
589 {
590 ArbiterLibFreeOrderingList(&Arbiter->OrderingList);
591 return Status;
592 }
593
594 ArbpForEachRegistryRange(Arbiter, L"AllocationOrder", AllocationOrderName,
595 TranslateOrderingFunction, ArbpAddOrderingCallback, NULL);
596
597 Status = ArbiterLibAddOrdering(&Arbiter->OrderingList, 0, ARBITER_MAXIMUM_ADDRESS);
598 if (!NT_SUCCESS(Status))
599 return Status;
600
601 /*
602 * The reserved windows come last, after the fallback is in place, so the
603 * pruning punches them out of the fallback too. Otherwise the fallback
604 * pass would hand them out like any other range.
605 */
606 return ArbpForEachRegistryRange(Arbiter, L"ReservedResources", ReservedResourcesName,
607 TranslateOrderingFunction, ArbpAddReservedCallback,
608 NULL);
609}
610
631CODE_SEG("PAGE")
633NTAPI
635 _In_ PARBITER_INSTANCE Arbiter,
636 _In_ PCWSTR OrderingName,
637 _Inout_ PRTL_RANGE_LIST RangeList)
638{
639 PAGED_CODE();
640 return ArbpForEachRegistryRange(Arbiter, L"InaccessibleRange", OrderingName,
641 NULL, ArbpAddRangeCallback, RangeList);
642}
643
660CODE_SEG("PAGE")
662NTAPI
664 _In_ PARBITER_INSTANCE Arbiter,
665 _Inout_ PRTL_RANGE_LIST RangeList)
666{
667 PAGED_CODE();
668 return ArbpForEachRegistryRange(Arbiter, L"ReservedResources", L"MmConfigRange",
669 NULL, ArbpMmConfigCallback, RangeList);
670}
671
688NTAPI
691 _In_ ULONGLONG End)
692{
694 return FALSE; /* No MMCONFIG window recorded */
695
696 return (BOOLEAN)(Start <= ArbpMmConfigEnd && ArbpMmConfigStart <= End);
697}
#define PAGED_CODE()
#define CODE_SEG(...)
static _Out_opt_ PULONGLONG Start
#define VOID
Definition: acefi.h:82
unsigned short UINT16
Definition: actypes.h:129
unsigned char BOOLEAN
Definition: actypes.h:127
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define REG_SZ
Definition: layer.c:22
NTSTATUS(NTAPI * PARB_TRANSLATE_ORDERING)(_Out_ PIO_RESOURCE_DESCRIPTOR OutIoDescriptor, _In_ PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: arbiter.h:278
#define ARBITER_MAXIMUM_ADDRESS
Definition: arbiter.h:13
#define TAG_ARBITER
Definition: arbiter.h:10
#define ARBITER_RANGE_INACCESSIBLE
Definition: arbiter.h:56
#define ARBITER_RANGE_BOOT_ALLOCATED
Definition: arbiter.h:53
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ PWSTR SubkeyName
Definition: cdrom.h:960
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ ULONG _In_ ULONG _In_opt_ DXGKCB_MIRACAST_SEND_MESSAGE_CALLBACK Callback
Definition: dispmprt.h:620
#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:33
#define L(x)
Definition: resources.c:13
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define PagedPool
Definition: env_spec_w32.h:308
union Alignment_ Alignment
Status
Definition: gdiplustypes.h:24
if(dx< 0)
Definition: linetemp.h:194
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
@ KeyValueFullInformationAlign64
Definition: reg.c:111
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI RtlAddRange(_Inout_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Start, _In_ ULONGLONG End, _In_ UCHAR Attributes, _In_ ULONG Flags, _In_opt_ PVOID UserData, _In_opt_ PVOID Owner)
#define RTL_RANGE_LIST_ADD_IF_CONFLICT
Definition: rtltypes.h:81
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define KEY_READ
Definition: nt_native.h:1026
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_RESOURCE_REQUIREMENTS_LIST
Definition: nt_native.h:1507
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
static ULONGLONG ArbpMmConfigEnd
Definition: ordering.c:29
VOID(NTAPI * PARB_RANGE_CALLBACK)(_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
Definition: ordering.c:207
static BOOLEAN ArbpDescriptorMatchesArbiter(_In_ PARBITER_INSTANCE Arbiter, _In_ UCHAR DescriptorType)
Definition: ordering.c:292
static VOID NTAPI ArbpAddReservedCallback(_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
Range callback moving one reserved window into last-resort territory: recorded in the arbiter's Reser...
Definition: ordering.c:456
NTSTATUS NTAPI ArbiterLibAddInaccessibleAllocationRange(_In_ PARBITER_INSTANCE Arbiter, _In_ PCWSTR OrderingName, _Inout_ PRTL_RANGE_LIST RangeList)
Carves the firmware-reported inaccessible ranges (Arbiters\InaccessibleRange<OrderingName>) out of a ...
Definition: ordering.c:634
static NTSTATUS ArbpReadPolicyValue(_In_ HANDLE KeyHandle, _In_ PCWSTR ValueName, _Out_ PKEY_VALUE_FULL_INFORMATION *Value)
Definition: ordering.c:244
static NTSTATUS ArbpExcludeOrderingRange(_Inout_ PARBITER_ORDERING_LIST OrderingList, _In_ UINT64 Start, _In_ UINT64 End)
Removes [Start, End] from every window of an ordering list, splitting windows that straddle it.
Definition: ordering.c:146
static NTSTATUS ArbpOpenPolicySubkey(_In_ PCWSTR SubkeyName, _Out_ PHANDLE KeyHandle)
Definition: ordering.c:217
#define ARBITER_ORDERING_LIMIT
Definition: ordering.c:18
#define ARBP_POLICY_ROOT
Definition: ordering.c:20
static VOID NTAPI ArbpAddRangeCallback(_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
Range callback carving one window out of a range list as an unowned blocking range,...
Definition: ordering.c:490
static NTSTATUS ArbpCreateOrderingList(_Out_ PARBITER_ORDERING_LIST OrderingList)
Definition: ordering.c:37
NTSTATUS NTAPI ArbiterLibAddMmConfigRangeAsBootReserved(_In_ PARBITER_INSTANCE Arbiter, _Inout_ PRTL_RANGE_LIST RangeList)
Reserves the PCI-Express enhanced-config (MMCONFIG / ECAM) MMIO window (Arbiters\ReservedResources\Mm...
Definition: ordering.c:663
#define ARBP_LONGEST_SUBKEY
Definition: ordering.c:21
NTSTATUS NTAPI ArbiterLibDefaultAssignmentOrdering(_Inout_ PARBITER_INSTANCE Arbiter, _In_ PCWSTR AllocationOrderName, _In_ PCWSTR ReservedResourcesName, _In_opt_ PARB_TRANSLATE_ORDERING TranslateOrderingFunction)
Builds the arbiter's allocation ordering from the registry policy, most-preferred window first.
Definition: ordering.c:571
static ULONGLONG ArbpMmConfigStart
Definition: ordering.c:28
static VOID NTAPI ArbpAddOrderingCallback(_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
Definition: ordering.c:415
BOOLEAN NTAPI ArbiterLibIsConflictWithMmConfigRange(_In_ ULONGLONG Start, _In_ ULONGLONG End)
Determines whether a range overlaps the recorded MMCONFIG window.
Definition: ordering.c:689
static VOID NTAPI ArbpMmConfigCallback(_In_ PARBITER_INSTANCE Arbiter, _In_opt_ PVOID Context, _In_ ULONGLONG Start, _In_ ULONGLONG End)
Range callback recording the MMCONFIG (ECAM) window and reserving it in a range list as a boot alloca...
Definition: ordering.c:523
VOID NTAPI ArbiterLibFreeOrderingList(_Inout_ PARBITER_ORDERING_LIST OrderingList)
Definition: ordering.c:60
#define ARBITER_ORDERING_GRANULARITY
Definition: ordering.c:17
NTSTATUS NTAPI ArbiterLibAddOrdering(_Inout_ PARBITER_ORDERING_LIST OrderingList, _In_ UINT64 Start, _In_ UINT64 End)
Definition: ordering.c:78
static NTSTATUS ArbpForEachRegistryRange(_In_ PARBITER_INSTANCE Arbiter, _In_ PCWSTR Subkey, _In_ PCWSTR ValueName, _In_opt_ PARB_TRANSLATE_ORDERING Translate, _In_ PARB_RANGE_CALLBACK Callback, _In_opt_ PVOID Context)
Definition: ordering.c:313
short WCHAR
Definition: pedump.c:58
static PCWSTR TargetName
Definition: ping.c:67
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
#define CmResourceTypeMemory
Definition: restypes.h:106
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
_In_ PVOID Context
Definition: storport.h:2269
Definition: window.c:29
UINT64 Start
Definition: arbiter.h:99
IO_RESOURCE_DESCRIPTOR Descriptors[1]
Definition: iotypes.h:2739
IO_RESOURCE_LIST List[1]
Definition: iotypes.h:2749
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char UCHAR
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
uint64_t ULONGLONG
Definition: typedefs.h:67
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ PVOID _In_ LONG DescriptorType
Definition: usbdlib.h:160
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3782
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
#define CmResourceTypeMemoryLarge
Definition: cmtypes.h:231
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST