Leaked source code of windows server 2003
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

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. rtl.c
  5. Abstract:
  6. Some handy-dany RTL functions. These really should be part of the kernel
  7. Author:
  8. Environment:
  9. NT Kernel Model Driver only
  10. Revision History:
  11. --*/
  12. #include "pch.h"
  13. PCM_RESOURCE_LIST
  14. RtlDuplicateCmResourceList(
  15. IN POOL_TYPE PoolType,
  16. IN PCM_RESOURCE_LIST ResourceList,
  17. IN ULONG Tag
  18. )
  19. /*++
  20. Routine Description:
  21. This routine will attempt to allocate memory to copy the supplied
  22. resource list. If sufficient memory cannot be allocated then the routine
  23. will return NULL.
  24. Arguments:
  25. PoolType - the type of pool to allocate the duplicate from
  26. ResourceList - the resource list to be copied
  27. Tag - a value to tag the memory allocation with. If 0 then untagged
  28. memory will be allocated.
  29. Return Value:
  30. an allocated copy of the resource list (caller must free) or
  31. NULL if memory could not be allocated.
  32. --*/
  33. {
  34. ULONG size = sizeof(CM_RESOURCE_LIST);
  35. PVOID buffer;
  36. PAGED_CODE();
  37. //
  38. // How much memory do we need for this resource list?
  39. //
  40. size = RtlSizeOfCmResourceList(ResourceList);
  41. //
  42. // Allocate the memory and copy the list
  43. //
  44. buffer = ExAllocatePoolWithTag(PoolType, size, Tag);
  45. if(buffer != NULL) {
  46. RtlCopyMemory(
  47. buffer,
  48. ResourceList,
  49. size
  50. );
  51. }
  52. return buffer;
  53. }
  54. ULONG
  55. RtlSizeOfCmResourceList(
  56. IN PCM_RESOURCE_LIST ResourceList
  57. )
  58. /*++
  59. Routine Description:
  60. This routine returns the size of a CM_RESOURCE_LIST.
  61. Arguments:
  62. ResourceList - the resource list to be copied
  63. Return Value:
  64. an allocated copy of the resource list (caller must free) or
  65. NULL if memory could not be allocated.
  66. --*/
  67. {
  68. ULONG size = sizeof(CM_RESOURCE_LIST);
  69. ULONG i;
  70. PAGED_CODE();
  71. for(i = 0; i < ResourceList->Count; i++) {
  72. PCM_FULL_RESOURCE_DESCRIPTOR fullDescriptor = &(ResourceList->List[i]);
  73. ULONG j;
  74. //
  75. // First descriptor is included in the size of the resource list.
  76. //
  77. if(i != 0) {
  78. size += sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
  79. }
  80. for(j = 0; j < fullDescriptor->PartialResourceList.Count; j++) {
  81. //
  82. // First descriptor is included in the size of the partial list.
  83. //
  84. if(j != 0) {
  85. size += sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
  86. }
  87. }
  88. }
  89. return size;
  90. }
  91. PCM_PARTIAL_RESOURCE_DESCRIPTOR
  92. RtlUnpackPartialDesc(
  93. IN UCHAR Type,
  94. IN PCM_RESOURCE_LIST ResList,
  95. IN OUT PULONG Count
  96. )
  97. /*++
  98. Routine Description:
  99. Pulls out a pointer to the partial descriptor you're interested in
  100. Arguments:
  101. Type - CmResourceTypePort, ...
  102. ResList - The list to search
  103. Count - Points to the index of the partial descriptor you're looking
  104. for, gets incremented if found, i.e., start with *Count = 0,
  105. then subsequent calls will find next partial, make sense?
  106. Return Value:
  107. Pointer to the partial descriptor if found, otherwise NULL
  108. --*/
  109. {
  110. ULONG hit = 0;
  111. ULONG i;
  112. ULONG j;
  113. for (i = 0; i < ResList->Count; i++) {
  114. for (j = 0; j < ResList->List[i].PartialResourceList.Count; j++) {
  115. if (ResList->List[i].PartialResourceList.PartialDescriptors[j].Type == Type) {
  116. if (hit == *Count) {
  117. (*Count)++;
  118. return &ResList->List[i].PartialResourceList.PartialDescriptors[j];
  119. } else {
  120. hit++;
  121. }
  122. }
  123. }
  124. }
  125. return NULL;
  126. }