You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
3.9 KiB
196 lines
3.9 KiB
/*++
|
|
|
|
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;
|
|
}
|
|
|