-1

FormatMessage() doesn't work for me no matter what I do. When I have error 12002, lpBuffer returns as NULL all the time. This is my code:

LPTSTR lpBuffer = NULL;
DWORD dwError = GetLastError();
int nResult = 0;
if (dwError >= 12000 && dwError <= 12174)
{
    nResult = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE, 
        GetModuleHandle("wininet.dll"), dwError, 0, (LPTSTR)&lpBuffer, 0, NULL);
}
else
{
    nResult = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
        NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpBuffer, 0, NULL);
}

Does anyone have any ideas?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
user3259383
  • 149
  • 1
  • 9
  • are `wininet.dll` is loaded already ? what is `GetLastError();` after `FormatMessage` fail ? can assume that `GetModuleHandle("wininet.dll")` fail – RbMm Aug 08 '18 at 13:21
  • FormatMessage works correctly. It's your code that doesn't work. It's worth being clear about this in question titles. – David Heffernan Aug 08 '18 at 13:25
  • Your code works, if `GetModuleHandle("wininet.dll");` doesn't return NULL. If I link against the lib and call InternetOpen it works for me. – Retired Ninja Aug 08 '18 at 13:32
  • ^^ what @RbMm says. When faced with a problem like this, your first thought should be to simplify the code by taking out the GetModuleHandle() call and loading into a temp var. on a separate line so that you can easily check its result. Using multiple system API calls in one statement might look cool, but is actually just difficult to follow and debug:( – Martin James Aug 08 '18 at 13:32
  • anyway - if `FormatMessage` fail - look and post here `GetLastError()` after this. for not guess. – RbMm Aug 08 '18 at 13:34
  • Yes, I see the problem is that GetModuleHandle("wininet.dll") returns NULL, but I have no idea why – user3259383 Aug 08 '18 at 13:48
  • if this not typo in name *wininet* - this mean that this dll yet not loaded. if you replace `GetModuleHandle` to `LoadLibrary` will be ok ? you say that call `InternetOpen` - are you not use delay load for wininet.dll ? – RbMm Aug 08 '18 at 14:05
  • `LoadLibrary("wininet.dll");` works to get the module handle as well. – Retired Ninja Aug 08 '18 at 14:09
  • Ok. thanks for the answers. I will try LoadLibrary instead – user3259383 Aug 08 '18 at 14:39
  • @RbMm if the error code comes from WinInet to begin with, then obviously the WinInet DLL is loaded. Even the [WinInet documentation](https://learn.microsoft.com/en-us/windows/desktop/WinInet/appendix-c-handling-errors) says to use `GetModuleHandle()` when calling `FormatMessage()`. – Remy Lebeau Aug 08 '18 at 17:06
  • Related: [Why is FormatMessage() failing to find a message for WinINet errors?](https://stackoverflow.com/questions/2159458/) – Remy Lebeau Aug 08 '18 at 17:09
  • @RemyLebeau - in this case unclear how *I see the problem is that `GetModuleHandle("wininet.dll")` returns NULL* – RbMm Aug 08 '18 at 17:13
  • @RbMm maybe the OP is using WinHTTP instead of WinInet? We don't know, the OP didn't say one way or the other. That would be the only logical reason I can think of for why `GetModuleHandle("wininet.dll")` would fail. – Remy Lebeau Aug 08 '18 at 18:39

1 Answers1

2

Per WinInet's documentation:

Handling Errors

To get the error text for an error, call the FormatMessage function, passing it an HMODULE handle to Wininet.dll, which can be obtained using the GetModuleHandle function.

Which is in contrast to Microsoft's system documentation:

System Error Codes (12000-15999)

The following list describes system error codes (errors 12000 to 15999). They are returned by the GetLastError function when many functions fail. To retrieve the description text for the error in your application, use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag.

That would logically include WinInet error codes in the 12000-12175 range, but in reality it only works for a few select WinInet errors.

Note also that WinInet and WinHTTP share the same 12xxx range of error codes. Error code 12002 is a WinHTTP error code:

ERROR_WINHTTP_TIMEOUT

12002

This error can be returned as a result of TCP/IP time-out behavior, regardless of time-out values set in Windows HTTP Services.

As well as a WinInet error code:

ERROR_INTERNET_TIMEOUT

12002

The request has timed out.

You did not indicate which library you are using. Make sure you are using the correct module when calling FormatMessage(). If you get an error from a WinInet function, use wininet.dll. If you get an error from a WinHTTP function, use winhttp.dll.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770