Reputation: 36
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").
Upvotes: 1
Views: 2413
Reputation: 42924
pHttpContext->GetRequest()->GetHeader("Accept", NULL);
returns a
PCSTR
data type.But I need to feed the
WriteEventViewerLog
with header as aLPCWSTR
, since one of the functions that I use inside the methods only accepts the string in that format.
First, let's clarify the meaning of these "obscure" Windows API string typedef
s:
PCSTR: const char *
LPCWSTR: const wchar_t *
So, both are pointers to read-only NUL-terminated C-style strings.
The difference is that PCSTR
points to a char
-based string; LPCWSTR
points to a wchar_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 a wchar_t
-based one. Assuming that your char
-based string represents a Unicode UTF-8 string (of which pure ASCII is a proper subset), you can use the MultiByteToWideChar()
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 CA2W
helper with the CP_UTF8
conversion flag can come in handy in your case:
#include <atlconv.h> // for CA2W
...
// Get the header string in Unicode UTF-8
PCSTR header = pHttpContext->GetRequest()->GetHeader("Accept", nullptr);
// Convert the header string from UTF-8 to Unicode UTF-16
WriteEventViewerLog( CA2W(header, CP_UTF8) );
Upvotes: 3