197 lines
3.7 KiB
C
197 lines
3.7 KiB
C
/*++
|
||
|
||
Copyright (c) 1999 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
rtl.c
|
||
|
||
Abstract:
|
||
|
||
Some handy-dany RTL functions. These really should be part of the kernel
|
||
|
||
|
||
Author:
|
||
|
||
Environment:
|
||
|
||
NT Kernel Model Driver only
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "pch.h"
|
||
|
||
|
||
PCM_RESOURCE_LIST
|
||
RtlDuplicateCmResourceList(
|
||
IN POOL_TYPE PoolType,
|
||
IN PCM_RESOURCE_LIST ResourceList,
|
||
IN ULONG Tag
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine will attempt to allocate memory to copy the supplied
|
||
resource list. If sufficient memory cannot be allocated then the routine
|
||
will return NULL.
|
||
|
||
Arguments:
|
||
|
||
PoolType - the type of pool to allocate the duplicate from
|
||
|
||
ResourceList - the resource list to be copied
|
||
|
||
Tag - a value to tag the memory allocation with. If 0 then untagged
|
||
memory will be allocated.
|
||
|
||
Return Value:
|
||
|
||
an allocated copy of the resource list (caller must free) or
|
||
NULL if memory could not be allocated.
|
||
|
||
--*/
|
||
{
|
||
ULONG size = sizeof(CM_RESOURCE_LIST);
|
||
PVOID buffer;
|
||
|
||
PAGED_CODE();
|
||
|
||
//
|
||
// How much memory do we need for this resource list?
|
||
//
|
||
size = RtlSizeOfCmResourceList(ResourceList);
|
||
|
||
//
|
||
// Allocate the memory and copy the list
|
||
//
|
||
buffer = ExAllocatePoolWithTag(PoolType, size, Tag);
|
||
if(buffer != NULL) {
|
||
|
||
RtlCopyMemory(
|
||
buffer,
|
||
ResourceList,
|
||
size
|
||
);
|
||
|
||
}
|
||
|
||
return buffer;
|
||
}
|
||
|
||
ULONG
|
||
RtlSizeOfCmResourceList(
|
||
IN PCM_RESOURCE_LIST ResourceList
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine returns the size of a CM_RESOURCE_LIST.
|
||
|
||
Arguments:
|
||
|
||
ResourceList - the resource list to be copied
|
||
|
||
Return Value:
|
||
|
||
an allocated copy of the resource list (caller must free) or
|
||
NULL if memory could not be allocated.
|
||
|
||
--*/
|
||
|
||
{
|
||
ULONG size = sizeof(CM_RESOURCE_LIST);
|
||
ULONG i;
|
||
|
||
PAGED_CODE();
|
||
|
||
for(i = 0; i < ResourceList->Count; i++) {
|
||
|
||
PCM_FULL_RESOURCE_DESCRIPTOR fullDescriptor = &(ResourceList->List[i]);
|
||
ULONG j;
|
||
|
||
//
|
||
// First descriptor is included in the size of the resource list.
|
||
//
|
||
if(i != 0) {
|
||
|
||
size += sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
|
||
|
||
}
|
||
|
||
for(j = 0; j < fullDescriptor->PartialResourceList.Count; j++) {
|
||
|
||
//
|
||
// First descriptor is included in the size of the partial list.
|
||
//
|
||
if(j != 0) {
|
||
|
||
size += sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
return size;
|
||
}
|
||
|
||
PCM_PARTIAL_RESOURCE_DESCRIPTOR
|
||
RtlUnpackPartialDesc(
|
||
IN UCHAR Type,
|
||
IN PCM_RESOURCE_LIST ResList,
|
||
IN OUT PULONG Count
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Pulls out a pointer to the partial descriptor you're interested in
|
||
|
||
Arguments:
|
||
|
||
Type - CmResourceTypePort, ...
|
||
ResList - The list to search
|
||
Count - Points to the index of the partial descriptor you're looking
|
||
for, gets incremented if found, i.e., start with *Count = 0,
|
||
then subsequent calls will find next partial, make sense?
|
||
|
||
Return Value:
|
||
|
||
Pointer to the partial descriptor if found, otherwise NULL
|
||
|
||
--*/
|
||
{
|
||
ULONG hit = 0;
|
||
ULONG i;
|
||
ULONG j;
|
||
|
||
for (i = 0; i < ResList->Count; i++) {
|
||
|
||
for (j = 0; j < ResList->List[i].PartialResourceList.Count; j++) {
|
||
|
||
if (ResList->List[i].PartialResourceList.PartialDescriptors[j].Type == Type) {
|
||
|
||
if (hit == *Count) {
|
||
|
||
(*Count)++;
|
||
return &ResList->List[i].PartialResourceList.PartialDescriptors[j];
|
||
|
||
} else {
|
||
|
||
hit++;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
return NULL;
|
||
}
|
||
|