1 /* 2 * PROJECT: ReactOS Kernel 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Helper functions to parse CM_RESOURCE_LISTs 5 * COPYRIGHT: Copyright 2020 Timo Kreuzer (timo.kreuzer@reactos.org) 6 */ 7 8 #include <wdm.h> 9 10 // 11 // Resource list helpers 12 // 13 14 /* Usage note: 15 * As there can be only one variable-sized CM_PARTIAL_RESOURCE_DESCRIPTOR in the list (and it must be the last one), 16 * a right looping through resources can look like this: 17 * 18 * PCM_FULL_RESOURCE_DESCRIPTOR FullDesc = &ResourceList->List[0]; 19 * for (ULONG i = 0; i < ResourceList->Count; i++, FullDesc = CmiGetNextResourceDescriptor(FullDesc)) 20 * { 21 * for (ULONG j = 0; j < FullDesc->PartialResourceList.Count; j++) 22 * { 23 * PartialDesc = &FullDesc->PartialResourceList.PartialDescriptors[j]; 24 * // work with PartialDesc 25 * } 26 * } 27 */ 28 29 FORCEINLINE 30 PCM_PARTIAL_RESOURCE_DESCRIPTOR CmiGetNextPartialDescriptor(_In_ const CM_PARTIAL_RESOURCE_DESCRIPTOR * PartialDescriptor)31CmiGetNextPartialDescriptor( 32 _In_ const CM_PARTIAL_RESOURCE_DESCRIPTOR *PartialDescriptor) 33 { 34 const CM_PARTIAL_RESOURCE_DESCRIPTOR *NextDescriptor; 35 36 /* Assume the descriptors are the fixed size ones */ 37 NextDescriptor = PartialDescriptor + 1; 38 39 /* But check if this is actually a variable-sized descriptor */ 40 if (PartialDescriptor->Type == CmResourceTypeDeviceSpecific) 41 { 42 /* Add the size of the variable section as well */ 43 NextDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)((ULONG_PTR)NextDescriptor + 44 PartialDescriptor->u.DeviceSpecificData.DataSize); 45 ASSERT(NextDescriptor >= PartialDescriptor + 1); 46 } 47 48 /* Now the correct pointer has been computed, return it */ 49 return (PCM_PARTIAL_RESOURCE_DESCRIPTOR)NextDescriptor; 50 } 51 52 FORCEINLINE 53 PCM_FULL_RESOURCE_DESCRIPTOR CmiGetNextResourceDescriptor(_In_ const CM_FULL_RESOURCE_DESCRIPTOR * ResourceDescriptor)54CmiGetNextResourceDescriptor( 55 _In_ const CM_FULL_RESOURCE_DESCRIPTOR *ResourceDescriptor) 56 { 57 const CM_PARTIAL_RESOURCE_DESCRIPTOR *LastPartialDescriptor; 58 59 /* Calculate the location of the last partial descriptor, which can have a 60 variable size! */ 61 LastPartialDescriptor = &ResourceDescriptor->PartialResourceList.PartialDescriptors[ 62 ResourceDescriptor->PartialResourceList.Count - 1]; 63 64 /* Next full resource descriptor follows the last partial descriptor */ 65 return (PCM_FULL_RESOURCE_DESCRIPTOR)CmiGetNextPartialDescriptor(LastPartialDescriptor); 66 } 67