1

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").

6
  • 2
    That function should work. Check what's happening in the debugger. Commented Mar 7, 2016 at 21:30
  • From the looks of things, charArrayToLPWSTR() should work, though I'd make it const char *source to match the type of PCSTR: LPWSTR wszHeader = charArrayToLPWSTR(header); /* Code using wszHeader. */ delete[] wszHeader;. Do you have more information such as sample input and output that works or doesn't work and maybe the actual section of code that requires usage of LPWSTR? Commented Mar 7, 2016 at 21:35
  • Try CP_UTF8 instead of CP_ACP Commented Mar 7, 2016 at 21:35
  • I suggest the use of convenient ATL conversion helpers around MultiByteToWideChar(), or write some function returning a CString or std::wstring, but do not return a raw owning pointer allocated with new[] inside the function body. This can be a leaktrocity if the caller doesn't pay much attention to deallocate the returned string. It's C++, not C. Commented Mar 7, 2016 at 23:35
  • 2
    That function doesn't check the return values. Please show an example of the input that leads to the bad output. Also be aware that that function requires the caller to free the buffer correctly, or it will leak. Commented Mar 8, 2016 at 0:23

1 Answer 1

3
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.

First, let's clarify the meaning of these "obscure" Windows API string typedefs:

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) ); 
Sign up to request clarification or add additional context in comments.

1 Comment

The use of CA2W solved the issue. I just had to #include <atlbase.h> #include <atlstr.h> in addition to atlconv.h to be able to use it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.