I have the following C++ code that retrieves header request information from an HttpContext instance:
public:
REQUEST_NOTIFICATION_STATUS
OnBeginRequest(
IN IHttpContext * pHttpContext,
IN IHttpEventProvider * pProvider
)
{
UNREFERENCED_PARAMETER(pHttpContext);
UNREFERENCED_PARAMETER(pProvider);
PCSTR header = pHttpContext->GetRequest()->GetHeader("Accept", NULL);
WriteEventViewerLog(header);
As you can see, the call:
pHttpContext->GetRequest()->GetHeader("Accept", NULL)**
Returns a PCSTR data type.
But I need to feed the WriteEventViewerLog with header as a "LPCWSTR", since one of the functions that I use inside the methods only accepts the string in that format.
From https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751%28v=vs.85%29.aspx, about these string definitions:
A pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters. For more information, see Character Sets Used By Fonts.
This type is declared in WinNT.h as follows:
typedef CONST CHAR *PCSTR;
And LPCWSTR:
A pointer to a constant null-terminated string of 16-bit Unicode characters. For more information, see Character Sets Used By Fonts.
This type is declared in WinNT.h as follows:
typedef CONST WCHAR *LPCWSTR;
I didn't find out a way of converting from these two data types. I tried casting header to char* and then using the function below to move from char* to LPCWSTR:
LPWSTR charArrayToLPWSTR(char *source)
{
// Get required buffer size in 'wide characters'
int nSize = MultiByteToWideChar(CP_ACP, 0, source, -1, NULL, 0);
LPWSTR outString = new WCHAR[nSize];
// Make conversion
MultiByteToWideChar(CP_ACP, 0, source, -1, outString, nSize);
return outString;
}
But that returned to me an invalid string (I don't have the complete input, but the Accept header value was trimmed to "x;ih").
First, let's clarify the meaning of these "obscure" Windows API string
typedefs:So, both are pointers to read-only NUL-terminated C-style strings.
The difference is that
PCSTRpoints to achar-based string;LPCWSTRpoints to awchar_t-based string.char-based strings can be of several "forms" (or encodings), e.g. simple ASCII, or Unicode UTF-8, or other "multi-byte" encodings.In case of your header string, I assume it can be simple ASCII, or UTF-8 (note that ASCII is a proper subset of UTF-8).
wchar_t-based strings in Visual C++ are Unicode UTF-16 strings (and this is the "native" Unicode encoding used by most Win32 APIs).So, what you have to do is to convert from a
char-based string to awchar_t-based one. Assuming that yourchar-based string represents a Unicode UTF-8 string (of which pure ASCII is a proper subset), you can use theMultiByteToWideChar()Win32 API to do the conversion.Or you can use some helper classes to simplify the conversion task, for example ATL conversion helpers. In particular, the
CA2Whelper with theCP_UTF8conversion flag can come in handy in your case: