Source code of Windows XP (NT5)
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.

239 lines
4.2 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. spmemory.c
  5. Abstract:
  6. Memory allocation routines for text setup.
  7. Author:
  8. Ted Miller (tedm) 29-July-1993
  9. Revision History:
  10. --*/
  11. #include "spprecmp.h"
  12. #pragma hdrstop
  13. PVOID
  14. SpMemAlloc(
  15. IN SIZE_T Size
  16. )
  17. {
  18. return(SpMemAllocEx(Size,'pteS', PagedPool));
  19. }
  20. PVOID
  21. SpMemAllocNonPagedPool(
  22. IN SIZE_T Size
  23. )
  24. {
  25. return(SpMemAllocEx(Size,'pteS', NonPagedPool));
  26. }
  27. PVOID
  28. SpMemAllocEx(
  29. IN SIZE_T Size,
  30. IN ULONG Tag,
  31. IN POOL_TYPE Type
  32. )
  33. /*++
  34. Routine Description:
  35. This function is guaranteed to succeed.
  36. Arguments:
  37. Return Value:
  38. --*/
  39. {
  40. PSIZE_T p;
  41. //
  42. // Add space for storing the size of the block.
  43. //
  44. #if defined(SETUP_TEST_USERMODE)
  45. p = RtlAllocateHeap(RtlProcessHeap(), 0, Size + (2 * sizeof(SIZE_T)));
  46. #else
  47. p = ExAllocatePoolWithTag(Type, Size + (2 * sizeof(SIZE_T)), Tag);
  48. #endif
  49. if(!p) {
  50. SpOutOfMemory();
  51. }
  52. //
  53. // Store the size of the block, and return the address
  54. // of the user portion of the block.
  55. //
  56. *p = Tag;
  57. *(p + 1) = Size;
  58. return(p + 2);
  59. }
  60. PVOID
  61. SpMemRealloc(
  62. IN PVOID Block,
  63. IN SIZE_T NewSize
  64. )
  65. /*++
  66. Routine Description:
  67. This function is guaranteed to succeed.
  68. Arguments:
  69. Return Value:
  70. --*/
  71. {
  72. PSIZE_T NewBlock;
  73. SIZE_T OldSize;
  74. ULONG OldTag;
  75. //
  76. // Get the size of the block being reallocated.
  77. //
  78. OldTag = (ULONG)((PSIZE_T)Block)[-2];
  79. OldSize = ((PSIZE_T)Block)[-1];
  80. //
  81. // Allocate a new block of the new size.
  82. //
  83. NewBlock = SpMemAllocEx(NewSize, OldTag, PagedPool);
  84. ASSERT(NewBlock);
  85. //
  86. // Copy the old block to the new block.
  87. //
  88. if (NewSize < OldSize) {
  89. RtlCopyMemory(NewBlock, Block, NewSize);
  90. } else {
  91. RtlCopyMemory(NewBlock, Block, OldSize);
  92. }
  93. //
  94. // Free the old block.
  95. //
  96. SpMemFree(Block);
  97. //
  98. // Return the address of the new block.
  99. //
  100. return(NewBlock);
  101. }
  102. VOID
  103. SpMemFree(
  104. IN PVOID Block
  105. )
  106. /*++
  107. Routine Description:
  108. Arguments:
  109. Return Value:
  110. --*/
  111. {
  112. extern PWSTR CommonStrings[11];
  113. unsigned long i;
  114. if (Block == NULL)
  115. return;
  116. for( i = 0; i < sizeof(CommonStrings)/sizeof(PWSTR); i++ ) {
  117. if( (PWSTR)Block == CommonStrings[i] ) {
  118. return;
  119. }
  120. }
  121. //
  122. // Free the block at its real address.
  123. //
  124. #if defined(SETUP_TEST_USERMODE)
  125. RtlFreeHeap(RtlProcessHeap(), 0, (PULONG_PTR)Block - 2);
  126. #else
  127. ExFreePool((PULONG_PTR)Block - 2);
  128. #endif
  129. }
  130. VOID
  131. SpOutOfMemory(
  132. VOID
  133. )
  134. {
  135. KdPrintEx((DPFLTR_SETUP_ID, DPFLTR_ERROR_LEVEL, "SETUP: Out of memory\n"));
  136. #if !defined(SETUP_TEST_USERMODE)
  137. if(VideoInitialized) {
  138. if(KbdLayoutInitialized) {
  139. ULONG ValidKeys[2] = { KEY_F3,0 };
  140. //
  141. // We run a high risk of getting into an infinite loop
  142. // here because SpStartScreen will result in a call to
  143. // SpMemAlloc(), which will fail and call SpOutOfMemory
  144. // again. In order to get around this, we'll jettison
  145. // some memory that we won't need anymore (since we're
  146. // about to die). These should give us enough memory
  147. // to display the messages below.
  148. //
  149. SpFreeBootVars();
  150. SpFreeArcNames();
  151. while(1) {
  152. SpStartScreen(SP_SCRN_OUT_OF_MEMORY,5,0,FALSE,TRUE,DEFAULT_ATTRIBUTE);
  153. SpDisplayStatusOptions(
  154. DEFAULT_STATUS_ATTRIBUTE,
  155. SP_STAT_F3_EQUALS_EXIT,
  156. 0
  157. );
  158. if(SpWaitValidKey(ValidKeys,NULL,NULL) == KEY_F3) {
  159. SpDone(0,FALSE,TRUE);
  160. }
  161. }
  162. } else {
  163. //
  164. // we haven't loaded the layout dll yet, so we can't prompt for a keypress to reboot
  165. //
  166. SpStartScreen(SP_SCRN_OUT_OF_MEMORY_RAW,5,0,FALSE,TRUE,DEFAULT_ATTRIBUTE);
  167. SpDisplayStatusOptions(DEFAULT_STATUS_ATTRIBUTE, SP_STAT_KBD_HARD_REBOOT, 0);
  168. while(TRUE); // Loop forever
  169. }
  170. } else {
  171. SpDisplayRawMessage(SP_SCRN_OUT_OF_MEMORY_RAW, 2);
  172. while(TRUE); // loop forever
  173. }
  174. #endif
  175. }