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.

170 lines
5.2 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. va_list vaListMarker;
  64. //
  65. // Byte count is size of fixed members plus cCount pointers. cbOffset
  66. // is the offset at which we will begin dumping strings into the struct
  67. //
  68. UINT cbStructSize = SIZEOF(ThunkText) + (cCount - 1) * SIZEOF(LPTSTR);
  69. UINT cbOffset = cbStructSize;
  70. //
  71. // Scan the list of input strings, and add their lengths (in bytes, once
  72. // converted to TCHARs, incl NUL) to the output structure size
  73. //
  74. cTmp = 0;
  75. va_start(vaListMarker, cCount);
  76. do
  77. {
  78. pXChar = va_arg(vaListMarker, LPXSTR);
  79. if (pXChar)
  80. {
  81. cbStructSize += (lstrlenX(pXChar) + 1) * SIZEOF(TCHAR);
  82. }
  83. cTmp++;
  84. }
  85. while (cTmp < cCount);
  86. //
  87. // Allocate the output structure.
  88. //
  89. pThunkText = (ThunkText *) LocalAlloc(LMEM_FIXED, cbStructSize);
  90. if (NULL == pThunkText)
  91. {
  92. SetLastError((DWORD)E_OUTOFMEMORY);
  93. return NULL;
  94. }
  95. //
  96. // Convert each of the input strings into the allocated output
  97. // buffer.
  98. //
  99. cTmp = 0;
  100. va_start(vaListMarker, cCount);
  101. do
  102. {
  103. INT cchResult;
  104. pXChar = va_arg(vaListMarker, LPXSTR); // grab next src XSTR
  105. if (NULL == pXChar)
  106. {
  107. pThunkText->m_pStr[cTmp] = NULL;
  108. }
  109. else
  110. {
  111. pThunkText->m_pStr[cTmp] = (LPTSTR)(((LPBYTE)pThunkText) + cbOffset);
  112. #ifdef UNICODE
  113. cchResult = MultiByteToWideChar(CP_ACP, // code page
  114. 0, // flags
  115. pXChar, // source XCHAR
  116. -1, // assume NUL term
  117. pThunkText->m_pStr[cTmp], //outbuf
  118. (cbStructSize - cbOffset) / sizeof(WCHAR) ); //buflen
  119. #else
  120. cchResult = WideCharToMultiByte(CP_ACP, // code page
  121. 0, // flags
  122. pXChar, // source XCHAR
  123. -1, // assume NUL term
  124. pThunkText->m_pStr[cTmp], //outbuf
  125. (cbStructSize - cbOffset) / sizeof(CHAR), //buflen
  126. NULL, // default char
  127. NULL); // &fDefUsed
  128. #endif
  129. //
  130. // Even a NUL string returns a 1 character conversion, so 0 means
  131. // the conversion failed. Cleanup and bail.
  132. //
  133. if (0 == cchResult)
  134. {
  135. LocalFree(pThunkText);
  136. SetLastError((DWORD)E_FAIL);
  137. return NULL;
  138. }
  139. cbOffset += cchResult * SIZEOF(TCHAR);
  140. }
  141. cTmp++;
  142. } while (cTmp < cCount);
  143. return pThunkText;
  144. }
  145. #endif // UNICODE