Andrew Peters Andrew Peters - 3 months ago 30
C++ Question

Unicode version of InternetOpenUrl returns error 12002

Basically I am converting my program from multibyte to unicode so that I can advertise it commercial to people in other countries as well (basically its a live stream application). I've been experiencing many issues during this conversion. But recently, I've ran into one that's just been tearing my eyes open.

I have the following code (including the function from

Remy Lebeau
's answer):

void get_user_request(const wchar_t *url)
{
LPVOID hi, hu;

hi = InternetOpenW(SUBSCRIBER_USER_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);

if(hi==NULL)
{
WinInetError(L"InternetOpenW");
}
else
{
hu = InternetOpenUrlW(hi, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);

if(hu==NULL)
{
WinInetError("InternetOpenUrlW");
}
else
{
MessageBoxW ( 0, "We're in", 0, 0 );
InternetCloseHandle(hu);
}
InternetCloseHandle(hi);
}
}


EDIT 1 START

I call the function like so:

get_user_request(request_url);


where
request_url
is:

WCHAR *request_url; // its a global variable
request_url = L"http://example-site.com/user/<user-id>/";


I assign the value by concatenating the strings necessary for the request into it, the concatenation is somewhat like this:

wsprintfW ( request_url, L"?id=%s", string);


Prior to this concatenation.
request_url
is also concatenated to wstring like so:
lstrcatW(request_url, myWString.c_Str());


EDIT 1 END

Basically, before my conversion to unicode; this function worked fine. After the conversion. I get the following error on the
hu = InternetOpenUrlW()
line:

Setting a breakpoint right after returns
error 12002
- after looking this error up the description from MSDN is as follows:

12002 ERROR_INTERNET_TIMEOUT
The request has timed out.


If the request timed out, i assumed that the url passed to the function may have been malformed somehow. After that I inserted a breakpoint in my windows debugger at that parameter. It appears that the only string that is passed to that parameter is
'h'
... That is strange because I look back in my code and i pass the entire url to the function as a
const wchar_t*
just as it takes according to my paramter.

After that, I inserted the
MessageBoxW()
to show me the value of the
url
string that is passed to the function, just before. The output (surprisingly enough), was the exact same string that I originally pass into the
url
variable...

So my question is as follows:

"What the ****?"

P.S. All input to this scenario is greatly appreciated.

Answer

Your error handling inside of get_user_request() is wrong, and your concatenation of request_url is also wrong. The code should look more like this instead:

void DisplayWinInetError(LPCWSTR FuncName)
{
    DWORD dwErrorCode = GetLastError();
    DWORD dwLen;

    std::wostringstream ErrorMsg;
    ErrorMsg << FuncName << L" failed!";

    if (dwErrorCode == ERROR_INTERNET_EXTENDED_ERROR)
    {
        dwLen = 0;
        if (!InternetGetLastResponseInfo(&dwErrorCode, NULL, &dwLen) &&
            (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
        {
            ++dwLen;
            std::vector<wchar_t> msg(dwLen);
            if (InternetGetLastResponseInfo(&dwErrorCode, &msg[0], &dwLen))
                ErrorMsg << L'\n' << std::wstring(&msg[0], dwLen);
            else
                ErrorMsg << L"\nUnable to retrieve WinInet error message! Error: " << GetLastError();
        }
        else
            ErrorMsg << L"\nUnable to retrieve WinInet error message! Error: " << GetLastError();
    }
    else
    {
        ErrorMsg << L" WinInet Error: " << dwErrorCode;

        LPWSTR lpMsg = NULL;
        dwLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwErrorCode, 0, (LPWSTR)&lpMsg, 0, NULL);
        if (dwLen > 0)
        {
            ErrorMsg << L'\n' << std::wstring(lpMsg, dwLen);
            LocalFree(lpMsg);
        }
        else
            ErrorMsg << L"\nUnable to retrieve System error message! Error: " << GetLastError();
    }

    MessageBoxW(NULL, ErrorMsg.str().c_str(), L"WinInet error", MB_OK);
}

void get_user_request(LPCWSTR url)
{
    HINTERNET hInet, hUrl;

    hInet = InternetOpenW(SUBSCRIBER_USER_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (hInet == NULL)
    {
        DisplayWinInetError(L"InternetOpenW");
    }
    else
    {
        MessageBoxW(NULL, url, "Opening url", MB_OK);

        hUrl = InternetOpenUrlW(hInet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
        if (hUrl == NULL)
        {
            DisplayWinInetError(L"InternetOpenUrlW");
        }
        else
        {
            MessageBoxW(NULL, "We're in", L"OK", MB_OK);

            // ...

            InternetCloseHandle(hUrl);
        }

        InternetCloseHandle(hInet);
    }
}

std::wstring request_url = L"http://example-site.com/user/<user-id>/?id=" + string;
get_user_request(request_url.c_str());