203 lines
6.6 KiB
C
203 lines
6.6 KiB
C
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1994 - 1995.
|
|
//
|
|
// File: thunktxt.c
|
|
//
|
|
// Contents: Support routines to thunk API parameters ANSI <-> UNICODE
|
|
//
|
|
// Functions: ConvertStrings()
|
|
//
|
|
// History: 2-03-95 davepl Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include <shellprv.h>
|
|
#pragma hdrstop
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: ConvertStrings
|
|
//
|
|
// Synopsis: Converts a series of XCHAR strings into TCHAR strings,
|
|
// packed as a series of pointers followed by a contiguous
|
|
// block of memory where the output strings are stored.
|
|
//
|
|
// Eg: ConvertStrings(4, "Hello", "", NULL, "World");
|
|
//
|
|
// Returns a pointer to a block of memory as follows:
|
|
//
|
|
// 4 bytes <address of L"Hello">
|
|
// 4 bytes <address of L"">
|
|
// 4 bytes NULL
|
|
// 4 bytes <address of L"World">
|
|
// 12 bytes L"Hello\0"
|
|
// 2 bytes L"\0"
|
|
// 12 bytes L"World\0"
|
|
// ---------------------------------------------------
|
|
// 42 bytes
|
|
//
|
|
// The strings may then be referenced as ThunkText.m_pStr[0],
|
|
// [1], [2], and [3], where [2] is a NULL pointer.
|
|
//
|
|
// When the caller is finished with the strings, the entire
|
|
// block should be freed via LocalAlloc().
|
|
//
|
|
// Arguments: [cCount] -- Number of strings passed, incl NULs
|
|
// [pszOriginalString] -- The strings to convert
|
|
// (... etc ...)
|
|
//
|
|
// Returns: Pointer to a ThunkText structure
|
|
//
|
|
// History: 2-03-95 davepl Created
|
|
//
|
|
// Notes: In UNICODE builds, converts ANSI to UNICODE. In ANSI
|
|
// builds, converts to UNICODE (if present).
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#ifdef UNICODE
|
|
|
|
ThunkText * ConvertStrings(UINT cCount, ...)
|
|
{
|
|
ThunkText * pThunkText = NULL;
|
|
UINT cTmp;
|
|
LPXSTR pXChar;
|
|
UINT cchResult;
|
|
|
|
va_list vaListMarker;
|
|
|
|
//
|
|
// Byte count is size of fixed members plus cCount pointers. cbOffset
|
|
// is the offset at which we will begin dumping strings into the struct
|
|
//
|
|
|
|
UINT cbStructSize = SIZEOF(ThunkText) + (cCount - 1) * SIZEOF(LPTSTR);
|
|
UINT cbOffset = cbStructSize;
|
|
|
|
//
|
|
// Scan the list of input strings, and add their lengths (in bytes, once
|
|
// converted to TCHARs, incl NUL) to the output structure size
|
|
//
|
|
|
|
cTmp = 0;
|
|
va_start(vaListMarker, cCount);
|
|
do
|
|
{
|
|
pXChar = va_arg(vaListMarker, LPXSTR);
|
|
if (pXChar)
|
|
{
|
|
#ifdef UNICODE
|
|
|
|
cchResult = MultiByteToWideChar(CP_ACP, // code page
|
|
0, // flags
|
|
pXChar, // source XCHAR
|
|
-1, // assume NUL term
|
|
NULL, // no buffer yet, computing size
|
|
0 ); // no buffer yet, computing size
|
|
#else
|
|
|
|
cchResult = WideCharToMultiByte(CP_ACP, // code page
|
|
0, // flags
|
|
pXChar, // source XCHAR
|
|
-1, // assume NUL term
|
|
NULL, // no buffer yet, computing size
|
|
0, // no buffer yet, computing size
|
|
NULL, // default char
|
|
NULL); // &fDefUsed
|
|
#endif
|
|
|
|
//
|
|
// Even a NUL string returns a 1 character conversion, so 0 means
|
|
// the conversion failed. Cleanup and bail.
|
|
//
|
|
|
|
if (0 == cchResult)
|
|
{
|
|
SetLastError((DWORD)E_FAIL);
|
|
return NULL;
|
|
}
|
|
|
|
cbStructSize += cchResult * SIZEOF(TCHAR);
|
|
}
|
|
cTmp++;
|
|
}
|
|
while (cTmp < cCount);
|
|
|
|
//
|
|
// Allocate the output structure.
|
|
//
|
|
|
|
pThunkText = (ThunkText *) LocalAlloc(LMEM_FIXED, cbStructSize);
|
|
if (NULL == pThunkText)
|
|
{
|
|
SetLastError((DWORD)E_OUTOFMEMORY);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Convert each of the input strings into the allocated output
|
|
// buffer.
|
|
//
|
|
|
|
cTmp = 0;
|
|
va_start(vaListMarker, cCount);
|
|
do
|
|
{
|
|
INT cchResult;
|
|
|
|
pXChar = va_arg(vaListMarker, LPXSTR); // grab next src XSTR
|
|
|
|
if (NULL == pXChar)
|
|
{
|
|
pThunkText->m_pStr[cTmp] = NULL;
|
|
}
|
|
else
|
|
{
|
|
pThunkText->m_pStr[cTmp] = (LPTSTR)(((LPBYTE)pThunkText) + cbOffset);
|
|
|
|
|
|
|
|
#ifdef UNICODE
|
|
|
|
cchResult = MultiByteToWideChar(CP_ACP, // code page
|
|
0, // flags
|
|
pXChar, // source XCHAR
|
|
-1, // assume NUL term
|
|
pThunkText->m_pStr[cTmp], //outbuf
|
|
(cbStructSize - cbOffset) / sizeof(WCHAR) ); //buflen
|
|
#else
|
|
|
|
cchResult = WideCharToMultiByte(CP_ACP, // code page
|
|
0, // flags
|
|
pXChar, // source XCHAR
|
|
-1, // assume NUL term
|
|
pThunkText->m_pStr[cTmp], //outbuf
|
|
(cbStructSize - cbOffset) / sizeof(CHAR), //buflen
|
|
NULL, // default char
|
|
NULL); // &fDefUsed
|
|
#endif
|
|
|
|
//
|
|
// Even a NUL string returns a 1 character conversion, so 0 means
|
|
// the conversion failed. Cleanup and bail.
|
|
//
|
|
|
|
if (0 == cchResult)
|
|
{
|
|
LocalFree(pThunkText);
|
|
SetLastError((DWORD)E_FAIL);
|
|
return NULL;
|
|
}
|
|
|
|
cbOffset += cchResult * SIZEOF(TCHAR);
|
|
}
|
|
cTmp++;
|
|
} while (cTmp < cCount);
|
|
|
|
return pThunkText;
|
|
}
|
|
|
|
#endif // UNICODE
|