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;
|
|||
|
}
|
|||
|
|