Windows NT 4.0 source code leak
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.

325 lines
6.7 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. blktable.c
  5. Abstract:
  6. This module implements routines for managing tables.
  7. Author:
  8. Chuck Lenzmeier (chuckl) 4-Oct-1989
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #define BugCheckFileId SRV_FILE_BLKTABLE
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text( PAGE, SrvAllocateTable )
  16. #endif
  17. #if 0
  18. NOT PAGEABLE -- SrvGrowTable
  19. NOT PAGEABLE -- SrvRemoveEntryTable
  20. #endif
  21. VOID
  22. SrvAllocateTable (
  23. IN PTABLE_HEADER TableHeader,
  24. IN CSHORT NumberOfEntries,
  25. IN BOOLEAN Nonpaged
  26. )
  27. /*++
  28. Routine Description:
  29. This routine allocates a table and sets those fields that it can.
  30. Arguments:
  31. TableHeader - a pointer to the table header structure
  32. NumberOfEntries - the number of table entries to allocate
  33. Nonpaged - indicates whether the table should be allocated from
  34. nonpaged pool
  35. Return Value:
  36. None.
  37. --*/
  38. {
  39. SHORT i;
  40. CLONG tableSize;
  41. PTABLE_ENTRY table;
  42. PAGED_CODE( );
  43. //
  44. // Allocate space for the table.
  45. //
  46. tableSize = sizeof(TABLE_ENTRY) * NumberOfEntries;
  47. if ( Nonpaged ) {
  48. table = ALLOCATE_NONPAGED_POOL( tableSize, BlockTypeTable );
  49. } else {
  50. table = ALLOCATE_HEAP( tableSize, BlockTypeTable );
  51. }
  52. if ( table == NULL ) {
  53. INTERNAL_ERROR(
  54. ERROR_LEVEL_EXPECTED,
  55. "SrvAllocateTable: Unable to allocate %d bytes from paged pool.",
  56. tableSize,
  57. NULL
  58. );
  59. TableHeader->Table = NULL;
  60. return;
  61. }
  62. IF_DEBUG(HEAP) {
  63. SrvPrint1( "SrvAllocateTable: Allocated table at %lx\n", table );
  64. }
  65. //
  66. // Initialize the table, creating a linked list of free entries.
  67. //
  68. RtlZeroMemory( table, tableSize );
  69. table[NumberOfEntries-1].NextFreeEntry = -1;
  70. for ( i = (SHORT)(NumberOfEntries - 2); i >= 0; i-- ) {
  71. table[i].NextFreeEntry = (SHORT)(i + 1);
  72. }
  73. //
  74. // Point the table header to the table and set the first and
  75. // free entry indexes.
  76. //
  77. TableHeader->Table = table;
  78. TableHeader->Nonpaged = Nonpaged;
  79. TableHeader->TableSize = NumberOfEntries;
  80. TableHeader->FirstFreeEntry = 0;
  81. TableHeader->LastFreeEntry = (SHORT)(NumberOfEntries-1);
  82. return;
  83. } // SrvAllocateTable
  84. BOOLEAN
  85. SrvGrowTable (
  86. IN PTABLE_HEADER TableHeader,
  87. IN CSHORT NumberOfNewEntries,
  88. IN CSHORT MaxNumberOfEntries
  89. )
  90. /*++
  91. Routine Description:
  92. This routine grows a table by the number of entries specified. It
  93. allocates new space that is large enough to hold the expanded
  94. table, copies over the current table, initializes the entries
  95. that were added, and frees the old table.
  96. WARNING: The calling routine *must* hold a lock for the table to
  97. prevent access to the table while it is being copied over.
  98. Arguments:
  99. TableHeader - a pointer to the table header structure
  100. NumberOfNewEntries - the number of table entries to add to the table
  101. MaxNumberOfEntries - the maximum allowable size for the table
  102. Return Value:
  103. BOOLEAN - TRUE if the table was successfully grown, FALSE otherwise.
  104. --*/
  105. {
  106. CSHORT newTableSize, totalEntries, oldNumberOfEntries;
  107. CSHORT i;
  108. PTABLE_ENTRY table;
  109. oldNumberOfEntries = TableHeader->TableSize;
  110. totalEntries = oldNumberOfEntries + NumberOfNewEntries;
  111. //
  112. // If the table is already at the maximum size, kick out the request.
  113. //
  114. if ( oldNumberOfEntries == MaxNumberOfEntries ) {
  115. INTERNAL_ERROR(
  116. ERROR_LEVEL_EXPECTED,
  117. "SrvGrowTable: Unable to grow table at max size (%ld).",
  118. MaxNumberOfEntries,
  119. NULL
  120. );
  121. return FALSE;
  122. }
  123. //
  124. // If adding the requested number would put the table size over the
  125. // maximum, allocate to the maximum size.
  126. //
  127. if ( totalEntries > MaxNumberOfEntries ) {
  128. totalEntries = MaxNumberOfEntries;
  129. NumberOfNewEntries = totalEntries - oldNumberOfEntries;
  130. }
  131. newTableSize = (CSHORT)(totalEntries * sizeof(TABLE_ENTRY));
  132. //
  133. // Allocate space for the new table.
  134. //
  135. if ( TableHeader->Nonpaged ) {
  136. table = ALLOCATE_NONPAGED_POOL( newTableSize, BlockTypeTable );
  137. } else {
  138. table = ALLOCATE_HEAP( newTableSize, BlockTypeTable );
  139. }
  140. if ( table == NULL ) {
  141. INTERNAL_ERROR(
  142. ERROR_LEVEL_EXPECTED,
  143. "SrvGrowTable: Unable to allocate %d bytes from paged pool",
  144. sizeof( BLOCK_HEADER ) + newTableSize,
  145. NULL
  146. );
  147. return FALSE;
  148. }
  149. IF_DEBUG(HEAP) {
  150. SrvPrint1( "SrvGrowTable: Allocated new table at %lx\n", table );
  151. }
  152. //
  153. // Copy over the information from the old table. Zero the remainder
  154. // of the table.
  155. //
  156. RtlCopyMemory(
  157. table,
  158. TableHeader->Table,
  159. oldNumberOfEntries * sizeof(TABLE_ENTRY)
  160. );
  161. RtlZeroMemory(
  162. (PCHAR)table + (oldNumberOfEntries * sizeof(TABLE_ENTRY)),
  163. (totalEntries - oldNumberOfEntries) * sizeof(TABLE_ENTRY)
  164. );
  165. //
  166. // Free the old table.
  167. //
  168. SrvFreeTable( TableHeader );
  169. //
  170. // Initialize the new table locations in the free list of the table.
  171. //
  172. table[totalEntries-1].NextFreeEntry = -1;
  173. for ( i = (CSHORT)(totalEntries-2); i >= oldNumberOfEntries; i-- ) {
  174. table[i].NextFreeEntry = (SHORT)(i + 1);
  175. }
  176. //
  177. // Reinitialize the fields of the table header. It is assumed that
  178. // the table did not previously have any free entries.
  179. //
  180. TableHeader->Table = table;
  181. TableHeader->TableSize = totalEntries;
  182. TableHeader->FirstFreeEntry = oldNumberOfEntries;
  183. TableHeader->LastFreeEntry = (SHORT)(totalEntries-1);
  184. return TRUE;
  185. } // SrvGrowTable
  186. VOID
  187. SrvRemoveEntryTable (
  188. IN PTABLE_HEADER TableHeader,
  189. IN CSHORT Index
  190. )
  191. /*++
  192. Routine Description:
  193. This function removes an entry from a table.
  194. *** The lock controlling access to the table must be held when this
  195. function is called.
  196. Arguments:
  197. Table - Address of table header.
  198. Index - Index within table of entry to remove.
  199. Return Value:
  200. None.
  201. --*/
  202. {
  203. PTABLE_ENTRY entry;
  204. ASSERT( Index < TableHeader->TableSize );
  205. entry = &TableHeader->Table[Index];
  206. if ( TableHeader->LastFreeEntry >= 0 ) {
  207. //
  208. // Free list was not empty.
  209. //
  210. TableHeader->Table[TableHeader->LastFreeEntry].NextFreeEntry = Index;
  211. TableHeader->LastFreeEntry = Index;
  212. } else {
  213. //
  214. // Free list was empty.
  215. //
  216. TableHeader->FirstFreeEntry = Index;
  217. TableHeader->LastFreeEntry = Index;
  218. }
  219. entry->Owner = NULL;
  220. entry->NextFreeEntry = -1;
  221. return;
  222. } // SrvRemoveEntryTable