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.

373 lines
7.1 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. string.c
  5. Abstract:
  6. The string stack portion of the un-assembler
  7. Author:
  8. Stephane Plante
  9. Environment:
  10. Any
  11. Revision History:
  12. --*/
  13. #include "pch.h"
  14. NTSTATUS
  15. StringStackAllocate(
  16. OUT PSTRING_STACK *StringStack
  17. )
  18. /*++
  19. Routine Description:
  20. This routine allocates memory and returns a string stack object
  21. Arguments:
  22. String Stack - Where to store a pointer to the stack
  23. Return Value:
  24. NTSTATUS
  25. --*/
  26. {
  27. PSTRING_STACK tempStack;
  28. NTSTATUS status = STATUS_SUCCESS;
  29. //
  30. // Make sure that we have some place to store the stack pointer
  31. //
  32. ASSERT( StringStack != NULL );
  33. //
  34. // Allocate a block of memory for the stack
  35. //
  36. tempStack = MEMORY_ALLOCATE(
  37. sizeof(STRING_STACK) + ( STRING_GROWTH_RATE - 1 )
  38. );
  39. if (tempStack == NULL) {
  40. status = STATUS_INSUFFICIENT_RESOURCES;
  41. goto StringStackAllocateExit;
  42. }
  43. //
  44. // Setup the control block of the stack
  45. //
  46. tempStack->Signature = (ULONG) STRING_SIGNATURE;
  47. tempStack->StackSize = STRING_GROWTH_RATE;
  48. tempStack->TopOfStack = 0;
  49. //
  50. // Zero out the current elements on the stack
  51. //
  52. MEMORY_ZERO( tempStack->Stack, STRING_GROWTH_RATE );
  53. //
  54. // Return the stack pointer
  55. //
  56. StringStackAllocateExit:
  57. *StringStack = tempStack;
  58. return status;
  59. }
  60. NTSTATUS
  61. StringStackClear(
  62. IN OUT PSTRING_STACK *StringStack
  63. )
  64. /*++
  65. Routine Description:
  66. This routine wipes out the contents of the stack and
  67. restarts it as if it was new allocated. Saves some from
  68. freeing and reallocating a stack
  69. Arguments:
  70. StringStack - Where to find a pointer to the stack
  71. Return Value:
  72. NTSTATUS
  73. --*/
  74. {
  75. PSTRING_STACK localStack;
  76. //
  77. // Make sure that we point to something
  78. //
  79. ASSERT( StringStack != NULL && *StringStack != NULL );
  80. ASSERT( (*StringStack)->Signature == STRING_SIGNATURE );
  81. //
  82. // Zero out the stack
  83. //
  84. localStack = *StringStack;
  85. MEMORY_ZERO( localStack->Stack, localStack->StackSize );
  86. //
  87. // Reset the TOS to the root
  88. //
  89. localStack->TopOfStack = 0;
  90. //
  91. // Done
  92. //
  93. return STATUS_SUCCESS;
  94. }
  95. NTSTATUS
  96. StringStackFree(
  97. IN OUT PSTRING_STACK *StringStack
  98. )
  99. /*++
  100. Routine Description:
  101. This routine frees the string stack
  102. Arguments:
  103. StringStack - Where to find a pointer to the stack
  104. Return Value:
  105. NTSTATUS
  106. --*/
  107. {
  108. //
  109. // Make sure that we point to something
  110. //
  111. ASSERT( StringStack != NULL && *StringStack != NULL );
  112. ASSERT( (*StringStack)->Signature == STRING_SIGNATURE );
  113. //
  114. // Free the stack
  115. //
  116. MEMORY_FREE( *StringStack );
  117. //
  118. // Point the stack to nowhere
  119. //
  120. *StringStack = NULL;
  121. return STATUS_SUCCESS;
  122. }
  123. NTSTATUS
  124. StringStackPop(
  125. IN OUT PSTRING_STACK *StringStack,
  126. IN ULONG NumBytes,
  127. OUT PUCHAR *String
  128. )
  129. /*++
  130. Routine Description:
  131. This routine returns a pointer to the requested offset from the end
  132. of the stack
  133. Note: String points to memory that can be freed at any time. It is the
  134. caller's responsibility to make a copy
  135. Arguments:
  136. StringStack - Where to find a pointer to the stack
  137. NumBytes - Number of bytes to pop off
  138. String - Pointer to the bytes.
  139. Return Value:
  140. NTSTATUS
  141. --*/
  142. {
  143. PSTRING_STACK localStack;
  144. //
  145. // Make sure that we point to something
  146. //
  147. ASSERT( StringStack != NULL );
  148. ASSERT( (*StringStack)->Signature == STRING_SIGNATURE );
  149. ASSERT( String != NULL );
  150. //
  151. // Is there an item that we can remove from the stack?
  152. //
  153. localStack = *StringStack;
  154. if ( localStack->TopOfStack == 0 ||
  155. localStack->TopOfStack < NumBytes) {
  156. return STATUS_FAIL_CHECK;
  157. }
  158. //
  159. // Return a pointer to the requested bytes
  160. //
  161. localStack->TopOfStack -= NumBytes;
  162. *String = &( localStack->Stack[ localStack->TopOfStack ] );
  163. return STATUS_SUCCESS;
  164. }
  165. NTSTATUS
  166. StringStackPush(
  167. IN OUT PSTRING_STACK *StringStack,
  168. IN ULONG StringLength,
  169. IN PUCHAR String
  170. )
  171. /*++
  172. Routine Description:
  173. This routine obtains a pointer for an object on the top of the stack
  174. and increments the top to point to something that can be then be used
  175. again.
  176. Arguments:
  177. StringStack - Where to find a pointer to the stack
  178. String - String to push onto stack
  179. StringLength - How many bytes to push onto the stack
  180. Return Value:
  181. NTSTATUS
  182. --*/
  183. {
  184. PSTRING_STACK localStack;
  185. PSTRING_STACK tempStack;
  186. ULONG newSize;
  187. //
  188. // Make sure that we point to something
  189. //
  190. ASSERT( StringStack != NULL );
  191. ASSERT( String != NULL );
  192. //
  193. // Find the stack pointer and make sure that the signature is still
  194. // valid
  195. //
  196. localStack = *StringStack;
  197. ASSERT( localStack->Signature == STRING_SIGNATURE );
  198. //
  199. // Do we have enough space on the stack?
  200. //
  201. if ( localStack->TopOfStack + StringLength > localStack->StackSize ) {
  202. //
  203. // Figure out how many bytes by which to grow the stack and how
  204. // large the total stack should be
  205. //
  206. newSize = sizeof(STRING_STACK) + localStack->StackSize +
  207. STRING_GROWTH_RATE - 1;
  208. //
  209. // Grow the stack
  210. //
  211. tempStack = MEMORY_ALLOCATE( newSize );
  212. if (tempStack == NULL) {
  213. return STATUS_INSUFFICIENT_RESOURCES;
  214. }
  215. //
  216. // Empty the new stack and copy the old one to it
  217. //
  218. MEMORY_ZERO( tempStack->Stack, newSize - sizeof(STRING_STACK) + 1);
  219. MEMORY_COPY( tempStack, localStack , newSize - STRING_GROWTH_RATE);
  220. //
  221. // Make sure that the new stack has the correct size
  222. //
  223. tempStack->StackSize += STRING_GROWTH_RATE;
  224. //
  225. // Free the old stack
  226. //
  227. StringStackFree( StringStack );
  228. //
  229. // Set the stack to point to the new one
  230. //
  231. *StringStack = localStack = tempStack;
  232. }
  233. //
  234. // Grab a pointer to the part that we will return to the caller
  235. //
  236. MEMORY_COPY(
  237. &(localStack->Stack[ localStack->TopOfStack] ),
  238. String,
  239. StringLength
  240. );
  241. //
  242. // Find the new Top of Stack
  243. //
  244. localStack->TopOfStack += StringLength;
  245. //
  246. // Done
  247. //
  248. return STATUS_SUCCESS;
  249. }
  250. NTSTATUS
  251. StringStackRoot(
  252. IN OUT PSTRING_STACK *StringStack,
  253. OUT PUCHAR *RootElement
  254. )
  255. /*++
  256. Routine Description:
  257. This routine returns the topmost stack location that is in current use
  258. Arguments:
  259. Stack - Where the stack is located
  260. RootElement - Where to store the pointer to the root stack element
  261. Return Value:
  262. NTSTATUS
  263. --*/
  264. {
  265. ASSERT( StringStack != NULL && *StringStack != NULL );
  266. ASSERT( (*StringStack)->Signature == STRING_SIGNATURE );
  267. //
  268. // Grab the top stack location
  269. //
  270. *RootElement = (PUCHAR) (*StringStack)->Stack;
  271. //
  272. // Done
  273. //
  274. return STATUS_SUCCESS;
  275. }