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.

386 lines
7.7 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. string.c
  5. Abstract:
  6. This module implements the string routines needed for the NT redirector
  7. Author:
  8. Colin Watson (ColinW) 02-Apr-1993
  9. Revision History:
  10. 14-Jun-1990 LarryO
  11. Created for Lanman Redirector
  12. 02-Apr-1993 ColinW
  13. Modified for NwRdr
  14. --*/
  15. #include "Procs.h"
  16. #ifdef ALLOC_PRAGMA
  17. #pragma alloc_text( PAGE, DuplicateStringWithString )
  18. #pragma alloc_text( PAGE, DuplicateUnicodeStringWithString )
  19. #pragma alloc_text( PAGE, SetUnicodeString )
  20. #pragma alloc_text( PAGE, MergeStrings )
  21. #endif
  22. NTSTATUS
  23. DuplicateStringWithString (
  24. OUT PSTRING DestinationString,
  25. IN PSTRING SourceString,
  26. IN POOL_TYPE PoolType
  27. )
  28. /*++
  29. Routine Description:
  30. This routine duplicates a supplied input string, storing the result
  31. of the duplication in the supplied string. The maximumlength of the
  32. new string is determined by the length of the SourceString.
  33. Arguments:
  34. OUT PSTRING DestinationString - Returns the filled in string.
  35. IN PSTRING SourceString - Supplies the string to duplicate
  36. IN POOLTYPE PoolType - Supplies the type of pool (PagedPool or
  37. NonPagedPool)
  38. Return Value:
  39. NTSTATUS - Status of resulting operation
  40. If !NT_SUCCESS then DestinationString->Buffer == NULL
  41. --*/
  42. {
  43. PAGED_CODE();
  44. DestinationString->Buffer = NULL;
  45. try {
  46. if (SourceString->Length != 0) {
  47. //
  48. // Allocate pool to hold the buffer (contents of the string)
  49. //
  50. DestinationString->Buffer = (PSZ )ALLOCATE_POOL(PoolType,
  51. SourceString->Length);
  52. }
  53. } except (EXCEPTION_EXECUTE_HANDLER) {
  54. return GetExceptionCode();
  55. }
  56. if (DestinationString->Buffer == NULL && SourceString->Length != 0) {
  57. //
  58. // The allocation failed, return failure.
  59. //
  60. return STATUS_INSUFFICIENT_RESOURCES;
  61. }
  62. DestinationString->MaximumLength = SourceString->Length;
  63. //
  64. // Copy the source string into the newly allocated
  65. // destination string
  66. //
  67. RtlCopyString(DestinationString, SourceString);
  68. return STATUS_SUCCESS;
  69. }
  70. NTSTATUS
  71. DuplicateUnicodeStringWithString (
  72. OUT PUNICODE_STRING DestinationString,
  73. IN PUNICODE_STRING SourceString,
  74. IN POOL_TYPE PoolType
  75. )
  76. /*++
  77. Routine Description:
  78. This routine duplicates a supplied input string, storing the result
  79. of the duplication in the supplied string. The maximumlength of the
  80. new string is determined by the length of the SourceString.
  81. Arguments:
  82. OUT PSTRING DestinationString - Returns the filled in string.
  83. IN PSTRING SourceString - Supplies the string to duplicate
  84. IN POOLTYPE PoolType - Supplies the type of pool (PagedPool or
  85. NonPagedPool)
  86. Return Value:
  87. NTSTATUS - Status of resulting operation
  88. If !NT_SUCCESS then DestinationString->Buffer == NULL
  89. --*/
  90. {
  91. PAGED_CODE();
  92. DestinationString->Buffer = NULL;
  93. try {
  94. if (SourceString->Length != 0) {
  95. //
  96. // Allocate pool to hold the buffer (contents of the string)
  97. //
  98. DestinationString->Buffer = (WCHAR *)ALLOCATE_POOL(PoolType,
  99. SourceString->Length);
  100. }
  101. } except (EXCEPTION_EXECUTE_HANDLER) {
  102. return GetExceptionCode();
  103. }
  104. if (DestinationString->Buffer == NULL && SourceString->Length != 0) {
  105. //
  106. // The allocation failed, return failure.
  107. //
  108. return STATUS_INSUFFICIENT_RESOURCES;
  109. }
  110. DestinationString->MaximumLength = SourceString->Length;
  111. //
  112. // Copy the source string into the newly allocated
  113. // destination string
  114. //
  115. RtlCopyUnicodeString(DestinationString, SourceString);
  116. return STATUS_SUCCESS;
  117. }
  118. #if 0
  119. VOID
  120. CopyUnicodeStringToUnicode (
  121. OUT PVOID *Destination,
  122. IN PUNICODE_STRING Source,
  123. IN BOOLEAN AdjustPointer
  124. )
  125. /*++
  126. Routine Description:
  127. This routine copies the specified source string onto the destination
  128. asciiz string.
  129. Arguments:
  130. OUT PUCHAR Destination, - Supplies a pointer to the destination
  131. buffer for the string.
  132. IN PSTRING String - Supplies the source string.
  133. IN BOOLEAN AdjustPointer - If TRUE, increment destination pointer
  134. Return Value:
  135. None.
  136. --*/
  137. {
  138. PAGED_CODE();
  139. RtlCopyMemory((*Destination), (Source)->Buffer, (Source)->Length);
  140. if (AdjustPointer) {
  141. ((PCHAR)(*Destination)) += ((Source)->Length);
  142. }
  143. }
  144. NTSTATUS
  145. CopyUnicodeStringToAscii (
  146. OUT PUCHAR *Destination,
  147. IN PUNICODE_STRING Source,
  148. IN BOOLEAN AdjustPointer,
  149. IN USHORT MaxLength
  150. )
  151. /*++
  152. Routine Description:
  153. This routine copies the specified source string onto the destination
  154. asciiz string.
  155. Arguments:
  156. OUT PUCHAR Destination, - Supplies the destination asciiz string.
  157. IN PUNICODE_STRING String - Supplies the source string.
  158. IN BOOLEAN AdjustPointer - If TRUE, increment destination pointer
  159. Return Value:
  160. Status of conversion.
  161. --*/
  162. {
  163. ANSI_STRING DestinationString;
  164. NTSTATUS Status;
  165. PAGED_CODE();
  166. DestinationString.Buffer = (*Destination);
  167. DestinationString.MaximumLength = (USHORT)(MaxLength);
  168. Status = RtlUnicodeStringToOemString(&DestinationString, (Source), FALSE);
  169. if (!NT_SUCCESS(Status)) {
  170. return Status;
  171. }
  172. if (AdjustPointer) {
  173. (*Destination) += DestinationString.Length;
  174. }
  175. return STATUS_SUCCESS;
  176. }
  177. #endif
  178. NTSTATUS
  179. SetUnicodeString (
  180. IN PUNICODE_STRING Destination,
  181. IN ULONG Length,
  182. IN PWCHAR Source
  183. )
  184. /*++
  185. Routine Description:
  186. This routine copies the specified source string onto the destination
  187. UNICODE string allocating the buffer.
  188. Arguments:
  189. Return Value:
  190. Status of conversion.
  191. --*/
  192. {
  193. UNICODE_STRING Temp;
  194. PAGED_CODE();
  195. Destination->Buffer = NULL;
  196. Destination->Length = 0;
  197. Destination->MaximumLength = 0;
  198. if (Length == 0) {
  199. return STATUS_SUCCESS;
  200. }
  201. Temp.MaximumLength =
  202. Temp.Length = (USHORT )Length;
  203. Temp.Buffer = Source;
  204. Destination->Buffer =
  205. ALLOCATE_POOL(NonPagedPool,
  206. Temp.MaximumLength+sizeof(WCHAR));
  207. if (Destination->Buffer == NULL) {
  208. Error(EVENT_NWRDR_RESOURCE_SHORTAGE, STATUS_INSUFFICIENT_RESOURCES, NULL, 0, 0);
  209. return STATUS_INSUFFICIENT_RESOURCES;
  210. }
  211. Destination->MaximumLength = (USHORT)Length;
  212. RtlCopyUnicodeString(Destination, &Temp);
  213. Destination->Buffer[(Destination->Length/sizeof(WCHAR))] = UNICODE_NULL;
  214. return STATUS_SUCCESS;
  215. }
  216. VOID
  217. MergeStrings(
  218. IN PUNICODE_STRING Destination,
  219. IN PUNICODE_STRING S1,
  220. IN PUNICODE_STRING S2,
  221. IN ULONG Type
  222. )
  223. /*++
  224. Routine Description:
  225. This routine Allocates space for Destination.Buffer and copies S1 followed
  226. by S2 into the buffer.
  227. Raises status if couldn't allocate buffer
  228. Arguments:
  229. IN PUNICODE_STRING Destination,
  230. IN PUNICODE_STRING S1,
  231. IN PUNICODE_STRING S2,
  232. IN ULONG Type - PagedPool or NonPagedPool
  233. Return Value:
  234. None.
  235. --*/
  236. {
  237. PAGED_CODE();
  238. //
  239. // Ensuring we don't cause overflow, corrupting memory
  240. //
  241. if ( ((ULONG)S1->Length + (ULONG)S2->Length) > 0xFFFF ) {
  242. ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
  243. }
  244. Destination->MaximumLength = S1->Length + S2->Length;
  245. Destination->Length = S1->Length + S2->Length;
  246. Destination->Buffer = ALLOCATE_POOL_EX( Type, Destination->MaximumLength );
  247. RtlCopyMemory( Destination->Buffer,
  248. S1->Buffer,
  249. S1->Length);
  250. RtlCopyMemory( (PUCHAR)Destination->Buffer + S1->Length,
  251. S2->Buffer,
  252. S2->Length);
  253. return;
  254. }