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.

202 lines
6.8 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1995.
  5. //
  6. // File: thunktxt.c
  7. //
  8. // Contents: Support routines to thunk API parameters ANSI <-> UNICODE
  9. //
  10. // Functions: ConvertStrings()
  11. //
  12. // History: 2-03-95 davepl Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include <shellprv.h>
  16. #pragma hdrstop
  17. //+-------------------------------------------------------------------------
  18. //
  19. // Function: ConvertStrings
  20. //
  21. // Synopsis: Converts a series of XCHAR strings into TCHAR strings,
  22. // packed as a series of pointers followed by a contiguous
  23. // block of memory where the output strings are stored.
  24. //
  25. // Eg: ConvertStrings(4, "Hello", "", NULL, "World");
  26. //
  27. // Returns a pointer to a block of memory as follows:
  28. //
  29. // 4 bytes <address of L"Hello">
  30. // 4 bytes <address of L"">
  31. // 4 bytes NULL
  32. // 4 bytes <address of L"World">
  33. // 12 bytes L"Hello\0"
  34. // 2 bytes L"\0"
  35. // 12 bytes L"World\0"
  36. // ---------------------------------------------------
  37. // 42 bytes
  38. //
  39. // The strings may then be referenced as ThunkText.m_pStr[0],
  40. // [1], [2], and [3], where [2] is a NULL pointer.
  41. //
  42. // When the caller is finished with the strings, the entire
  43. // block should be freed via LocalAlloc().
  44. //
  45. // Arguments: [cCount] -- Number of strings passed, incl NULs
  46. // [pszOriginalString] -- The strings to convert
  47. // (... etc ...)
  48. //
  49. // Returns: Pointer to a ThunkText structure
  50. //
  51. // History: 2-03-95 davepl Created
  52. //
  53. // Notes: In UNICODE builds, converts ANSI to UNICODE. In ANSI
  54. // builds, converts to UNICODE (if present).
  55. //
  56. //--------------------------------------------------------------------------
  57. #ifdef UNICODE
  58. ThunkText * ConvertStrings(UINT cCount, ...)
  59. {
  60. ThunkText * pThunkText = NULL;
  61. UINT cTmp;
  62. LPXSTR pXChar;
  63. UINT cchResult;
  64. va_list vaListMarker;
  65. //
  66. // Byte count is size of fixed members plus cCount pointers. cbOffset
  67. // is the offset at which we will begin dumping strings into the struct
  68. //
  69. UINT cbStructSize = SIZEOF(ThunkText) + (cCount - 1) * SIZEOF(LPTSTR);
  70. UINT cbOffset = cbStructSize;
  71. //
  72. // Scan the list of input strings, and add their lengths (in bytes, once
  73. // converted to TCHARs, incl NUL) to the output structure size
  74. //
  75. cTmp = 0;
  76. va_start(vaListMarker, cCount);
  77. do
  78. {
  79. pXChar = va_arg(vaListMarker, LPXSTR);
  80. if (pXChar)
  81. {
  82. #ifdef UNICODE
  83. cchResult = MultiByteToWideChar(CP_ACP, // code page
  84. 0, // flags
  85. pXChar, // source XCHAR
  86. -1, // assume NUL term
  87. NULL, // no buffer yet, computing size
  88. 0 ); // no buffer yet, computing size
  89. #else
  90. cchResult = WideCharToMultiByte(CP_ACP, // code page
  91. 0, // flags
  92. pXChar, // source XCHAR
  93. -1, // assume NUL term
  94. NULL, // no buffer yet, computing size
  95. 0, // no buffer yet, computing size
  96. NULL, // default char
  97. NULL); // &fDefUsed
  98. #endif
  99. //
  100. // Even a NUL string returns a 1 character conversion, so 0 means
  101. // the conversion failed. Cleanup and bail.
  102. //
  103. if (0 == cchResult)
  104. {
  105. SetLastError((DWORD)E_FAIL);
  106. return NULL;
  107. }
  108. cbStructSize += cchResult * SIZEOF(TCHAR);
  109. }
  110. cTmp++;
  111. }
  112. while (cTmp < cCount);
  113. //
  114. // Allocate the output structure.
  115. //
  116. pThunkText = (ThunkText *) LocalAlloc(LMEM_FIXED, cbStructSize);
  117. if (NULL == pThunkText)
  118. {
  119. SetLastError((DWORD)E_OUTOFMEMORY);
  120. return NULL;
  121. }
  122. //
  123. // Convert each of the input strings into the allocated output
  124. // buffer.
  125. //
  126. cTmp = 0;
  127. va_start(vaListMarker, cCount);
  128. do
  129. {
  130. INT cchResult;
  131. pXChar = va_arg(vaListMarker, LPXSTR); // grab next src XSTR
  132. if (NULL == pXChar)
  133. {
  134. pThunkText->m_pStr[cTmp] = NULL;
  135. }
  136. else
  137. {
  138. pThunkText->m_pStr[cTmp] = (LPTSTR)(((LPBYTE)pThunkText) + cbOffset);
  139. #ifdef UNICODE
  140. cchResult = MultiByteToWideChar(CP_ACP, // code page
  141. 0, // flags
  142. pXChar, // source XCHAR
  143. -1, // assume NUL term
  144. pThunkText->m_pStr[cTmp], //outbuf
  145. (cbStructSize - cbOffset) / sizeof(WCHAR) ); //buflen
  146. #else
  147. cchResult = WideCharToMultiByte(CP_ACP, // code page
  148. 0, // flags
  149. pXChar, // source XCHAR
  150. -1, // assume NUL term
  151. pThunkText->m_pStr[cTmp], //outbuf
  152. (cbStructSize - cbOffset) / sizeof(CHAR), //buflen
  153. NULL, // default char
  154. NULL); // &fDefUsed
  155. #endif
  156. //
  157. // Even a NUL string returns a 1 character conversion, so 0 means
  158. // the conversion failed. Cleanup and bail.
  159. //
  160. if (0 == cchResult)
  161. {
  162. LocalFree(pThunkText);
  163. SetLastError((DWORD)E_FAIL);
  164. return NULL;
  165. }
  166. cbOffset += cchResult * SIZEOF(TCHAR);
  167. }
  168. cTmp++;
  169. } while (cTmp < cCount);
  170. return pThunkText;
  171. }
  172. #endif // UNICODE