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.

209 lines
5.5 KiB

  1. /*--------------------------------------------------------------------------
  2. *
  3. * Copyright (C) Cyclades Corporation, 2000-2001.
  4. * All rights reserved.
  5. *
  6. * Cyclades-Z Enumerator Driver
  7. *
  8. * This file: string.c
  9. *
  10. * Description: This module contains the functions used to parse the
  11. * PNP COM ID and save it in the appropriate
  12. * UNICODE STRINGS. The main function that is called
  13. * is Cycladz_ParseData. All other functions are called
  14. * by this main function.
  15. *
  16. * Notes: This code supports Windows 2000 and Windows XP,
  17. * x86 and ia64 processors.
  18. *
  19. * Complies with Cyclades SW Coding Standard rev 1.3.
  20. *
  21. *--------------------------------------------------------------------------
  22. */
  23. /*-------------------------------------------------------------------------
  24. *
  25. * Change History
  26. *
  27. *--------------------------------------------------------------------------
  28. * Initial implementation based on Microsoft sample code.
  29. *
  30. *--------------------------------------------------------------------------
  31. */
  32. #include "pch.h"
  33. #define MAX_DEVNODE_NAME 256 // Total size of Device ID
  34. #ifdef ALLOC_PRAGMA
  35. #pragma alloc_text (PAGE, Cycladz_InitMultiString)
  36. #endif
  37. NTSTATUS
  38. Cycladz_InitMultiString(PFDO_DEVICE_DATA FdoData, PUNICODE_STRING MultiString,
  39. ...)
  40. /*++
  41. This routine will take a null terminated list of ascii strings and combine
  42. them together to generate a unicode multi-string block
  43. Arguments:
  44. MultiString - a unicode structure in which a multi-string will be built
  45. ... - a null terminated list of narrow strings which will be
  46. combined together. This list must contain at least a
  47. trailing NULL
  48. Return Value:
  49. NTSTATUS
  50. --*/
  51. {
  52. ANSI_STRING ansiString;
  53. NTSTATUS status;
  54. PCSTR rawString;
  55. PWSTR unicodeLocation;
  56. ULONG multiLength = 0;
  57. UNICODE_STRING unicodeString;
  58. va_list ap;
  59. ULONG i;
  60. PAGED_CODE();
  61. #if !DBG
  62. UNREFERENCED_PARAMETER(FdoData);
  63. #endif
  64. Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE,
  65. ("Entering Cycladz_InitMultiString\n"));
  66. va_start(ap,MultiString);
  67. //
  68. // Make sure that we won't leak memory
  69. //
  70. ASSERT(MultiString->Buffer == NULL);
  71. rawString = va_arg(ap, PCSTR);
  72. while (rawString != NULL) {
  73. RtlInitAnsiString(&ansiString, rawString);
  74. multiLength += RtlAnsiStringToUnicodeSize(&(ansiString));
  75. rawString = va_arg(ap, PCSTR);
  76. }
  77. va_end( ap );
  78. if (multiLength == 0) {
  79. //
  80. // Done
  81. //
  82. RtlInitUnicodeString(MultiString, NULL);
  83. Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE,
  84. ("Leaving Cycladz_InitMultiString (1)\n"));
  85. return STATUS_SUCCESS;
  86. }
  87. //
  88. // We need an extra null
  89. //
  90. multiLength += sizeof(WCHAR);
  91. MultiString->MaximumLength = (USHORT)multiLength;
  92. MultiString->Buffer = ExAllocatePool(PagedPool, multiLength);
  93. MultiString->Length = 0;
  94. if (MultiString->Buffer == NULL) {
  95. Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE,
  96. ("Leaving Cycladz_InitMultiString (2)\n"));
  97. return STATUS_INSUFFICIENT_RESOURCES;
  98. }
  99. Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE,
  100. ("Allocated %lu bytes for buffer\n", multiLength));
  101. #if DBG
  102. RtlFillMemory(MultiString->Buffer, multiLength, 0xff);
  103. #endif
  104. unicodeString.Buffer = MultiString->Buffer;
  105. unicodeString.MaximumLength = (USHORT) multiLength;
  106. va_start(ap, MultiString);
  107. rawString = va_arg(ap, PCSTR);
  108. while (rawString != NULL) {
  109. RtlInitAnsiString(&ansiString,rawString);
  110. status = RtlAnsiStringToUnicodeString(&unicodeString, &ansiString, FALSE);
  111. //
  112. // We don't allocate memory, so if something goes wrong here,
  113. // its the function that's at fault
  114. //
  115. ASSERT(NT_SUCCESS(status));
  116. //
  117. // Check for any commas and replace them with NULLs
  118. //
  119. ASSERT(unicodeString.Length % sizeof(WCHAR) == 0);
  120. for (i = 0; i < (unicodeString.Length / sizeof(WCHAR)); i++) {
  121. if (unicodeString.Buffer[i] == L'\x2C' ||
  122. unicodeString.Buffer[i] == L'\x0C' ) {
  123. unicodeString.Buffer[i] = L'\0';
  124. }
  125. }
  126. Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE, ("unicode buffer: %ws\n",
  127. unicodeString.Buffer));
  128. //
  129. // Move the buffers along
  130. //
  131. unicodeString.Buffer += ((unicodeString.Length / sizeof(WCHAR)) + 1);
  132. unicodeString.MaximumLength -= (unicodeString.Length + sizeof(WCHAR));
  133. unicodeString.Length = 0;
  134. //
  135. // Next
  136. //
  137. rawString = va_arg(ap, PCSTR);
  138. } // while
  139. va_end(ap);
  140. ASSERT(unicodeString.MaximumLength == sizeof(WCHAR));
  141. //
  142. // Stick the final null there
  143. //
  144. Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE, ("unicode buffer last addr: "
  145. "%x\n", unicodeString.Buffer));
  146. unicodeString.Buffer[0] = L'\0';
  147. //
  148. // Include the nulls in the length of the string
  149. //
  150. MultiString->Length = (USHORT)multiLength;
  151. MultiString->MaximumLength = MultiString->Length;
  152. Cycladz_KdPrint(FdoData, SER_DBG_SS_TRACE,
  153. ("Leaving Cycladz_InitMultiString (3)\n"));
  154. return STATUS_SUCCESS;
  155. }