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.

166 lines
3.5 KiB

  1. /*++
  2. Module Name:
  3. STRING.C
  4. Abstract:
  5. Environment:
  6. kernel mode only
  7. Notes:
  8. Revision History:
  9. --*/
  10. #include <ntddk.h>
  11. #include <stdarg.h>
  12. #include <ntddser.h>
  13. #include "mxenum.h"
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text (PAGE, MxenumInitMultiString)
  16. #endif
  17. NTSTATUS
  18. MxenumInitMultiString(PUNICODE_STRING MultiString,
  19. ...)
  20. /*++
  21. This routine will take a null terminated list of ascii strings and combine
  22. them together to generate a unicode multi-string block
  23. Arguments:
  24. MultiString - a unicode structure in which a multi-string will be built
  25. ... - a null terminated list of narrow strings which will be
  26. combined together. This list must contain at least a
  27. trailing NULL
  28. Return Value:
  29. NTSTATUS
  30. --*/
  31. {
  32. ANSI_STRING ansiString;
  33. NTSTATUS status;
  34. PCSTR rawString;
  35. ULONG multiLength = 0;
  36. UNICODE_STRING unicodeString;
  37. va_list ap;
  38. ULONG i;
  39. PAGED_CODE();
  40. va_start(ap,MultiString);
  41. //
  42. // Make sure that we won't leak memory
  43. //
  44. // ASSERT(MultiString->Buffer == NULL);
  45. rawString = va_arg(ap, PCSTR);
  46. while (rawString != NULL) {
  47. RtlInitAnsiString(&ansiString, rawString);
  48. multiLength += RtlAnsiStringToUnicodeSize(&(ansiString));
  49. rawString = va_arg(ap, PCSTR);
  50. }
  51. va_end( ap );
  52. if (multiLength == 0) {
  53. //
  54. // Done
  55. //
  56. RtlInitUnicodeString(MultiString, NULL);
  57. return STATUS_SUCCESS;
  58. }
  59. //
  60. // We need an extra null
  61. //
  62. multiLength += sizeof(WCHAR);
  63. MultiString->MaximumLength = (USHORT)multiLength;
  64. MultiString->Buffer = ExAllocatePool(PagedPool, multiLength);
  65. MultiString->Length = 0;
  66. if (MultiString->Buffer == NULL) {
  67. return STATUS_INSUFFICIENT_RESOURCES;
  68. }
  69. #if DBG
  70. RtlFillMemory(MultiString->Buffer, multiLength, 0xff);
  71. #endif
  72. unicodeString.Buffer = MultiString->Buffer;
  73. unicodeString.MaximumLength = (USHORT) multiLength;
  74. va_start(ap, MultiString);
  75. rawString = va_arg(ap, PCSTR);
  76. while (rawString != NULL) {
  77. RtlInitAnsiString(&ansiString,rawString);
  78. status = RtlAnsiStringToUnicodeString(&unicodeString, &ansiString, FALSE);
  79. //
  80. // We don't allocate memory, so if something goes wrong here,
  81. // its the function that's at fault
  82. //
  83. // ASSERT(NT_SUCCESS(status));
  84. //
  85. // Check for any commas and replace them with NULLs
  86. //
  87. // ASSERT(unicodeString.Length % sizeof(WCHAR) == 0);
  88. for (i = 0; i < (unicodeString.Length / sizeof(WCHAR)); i++) {
  89. if (unicodeString.Buffer[i] == L'\x2C' ||
  90. unicodeString.Buffer[i] == L'\x0C' ) {
  91. unicodeString.Buffer[i] = L'\0';
  92. }
  93. }
  94. //
  95. // Move the buffers along
  96. //
  97. unicodeString.Buffer += ((unicodeString.Length / sizeof(WCHAR)) + 1);
  98. unicodeString.MaximumLength -= (unicodeString.Length + sizeof(WCHAR));
  99. unicodeString.Length = 0;
  100. //
  101. // Next
  102. //
  103. rawString = va_arg(ap, PCSTR);
  104. } // while
  105. va_end(ap);
  106. // ASSERT(unicodeString.MaximumLength == sizeof(WCHAR));
  107. //
  108. // Stick the final null there
  109. //
  110. unicodeString.Buffer[0] = L'\0';
  111. //
  112. // Include the nulls in the length of the string
  113. //
  114. MultiString->Length = (USHORT)multiLength;
  115. MultiString->MaximumLength = MultiString->Length;
  116. return STATUS_SUCCESS;
  117. }