CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Dec 2021
    Posts
    4

    [RESOLVED] How to "FormatMessage()" my "WSAGetLastError()"

    I'm trying to generate a message string from a WSAGetLastError()) error code (Winsock2).
    My first attempt:

    DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;
    LPSTR lpBuffer = NULL;
    DWORD size = FormatMessage(flags, NULL, WSAGetLastError(), 0, (LPSTR)&lpBuffer, 0, NULL);

    FormatMessage fails with error 1813 (ERROR_RESOURCE_TYPE_NOT_FOUND).

    My next attempt:

    DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE;
    HMODULE hInst = AfxLoadLibrary(ws2_32.dll);
    LPSTR lpBuffer = NULL;
    DWORD size = FormatMessage(flags, hInst, WSAGetLastError(), 0, (LPSTR)&lpBuffer, 0, NULL);

    FormatMessage fails with error 15100 (ERROR_MUI_FILE_NOT_FOUND).

    What am I missing here?

    /Ove

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: How to "FormatMessage()" my "WSAGetLastError()"

    Quote Originally Posted by \Ove View Post
    I'm trying to generate a message string from a WSAGetLastError()) error code (Winsock2).
    My first attempt:

    DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;
    LPSTR lpBuffer = NULL;
    DWORD size = FormatMessage(flags, NULL, WSAGetLastError(), 0, (LPSTR)&lpBuffer, 0, NULL);

    FormatMessage fails with error 1813 (ERROR_RESOURCE_TYPE_NOT_FOUND).
    This code worked for me:
    Code:
    	DWORD dwErr = GetLastError();
    	LPVOID lpMsgBuf;
    	FormatMessage( 
    					FORMAT_MESSAGE_ALLOCATE_BUFFER | 
    					FORMAT_MESSAGE_FROM_SYSTEM | 
    					FORMAT_MESSAGE_IGNORE_INSERTS,
    					NULL,
    					dwErr,
    					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    					(LPTSTR) &lpMsgBuf,
    					0,
    					NULL );
    	CString strMess = (LPTSTR) lpMsgBuf;
    	// Free the buffer.
    	LocalFree( lpMsgBuf );
    	//	add message with dll name:
    	strMess += _T("\r\n\'") + strPath + _T('\'');
    	AfxMessageBox( strMess, MB_OK | MB_ICONSTOP );
    Victor Nijegorodov

  3. #3
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: How to "FormatMessage()" my "WSAGetLastError()"

    Quote Originally Posted by \Ove View Post
    ...
    My next attempt:

    DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE;
    HMODULE hInst = AfxLoadLibrary(ws2_32.dll);
    LPSTR lpBuffer = NULL;
    DWORD size = FormatMessage(flags, hInst, WSAGetLastError(), 0, (LPSTR)&lpBuffer, 0, NULL);

    FormatMessage fails with error 15100 (ERROR_MUI_FILE_NOT_FOUND).

    What am I missing here?

    /Ove
    Sorry, I never used this flag (FORMAT_MESSAGE_FROM_HMODULE).
    Have a look at these threads:
    https://forums.codeguru.com/showthre...ODULE-argument
    https://forums.codeguru.com/showthre...or-description
    Victor Nijegorodov

  4. #4
    Join Date
    Dec 2021
    Posts
    4

    Re: How to "FormatMessage()" my "WSAGetLastError()"

    Quote Originally Posted by \Ove View Post
    I'm trying to generate a message string from a WSAGetLastError()) error code (Winsock2).
    My first attempt:

    DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;
    LPSTR lpBuffer = NULL;
    DWORD size = FormatMessage(flags, NULL, WSAGetLastError(), 0, (LPSTR)&lpBuffer, 0, NULL);

    FormatMessage fails with error 1813 (ERROR_RESOURCE_TYPE_NOT_FOUND).

    My next attempt:

    DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE;
    HMODULE hInst = AfxLoadLibrary(ws2_32.dll);
    LPSTR lpBuffer = NULL;
    DWORD size = FormatMessage(flags, hInst, WSAGetLastError(), 0, (LPSTR)&lpBuffer, 0, NULL);

    FormatMessage fails with error 15100 (ERROR_MUI_FILE_NOT_FOUND).

    What am I missing here?

    /Ove
    Maybe I should add that I'm using Windows 10 with VS 2019.

    \Ove

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: How to "FormatMessage()" my "WSAGetLastError()"

    This is what I used when I did Windows programming:

    Code:
    #define WIN32_LEAN_AND_MEAN
    #define NOMINMAX
    #include <windows.h>
    
    #include <string>
    #include <iostream>
    
    DWORD WinError(std::string& werror, DWORD p_dwError) {
    	LPSTR MessageBuffer;
    
    	werror.clear();
    
    	if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, p_dwError,
    		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&MessageBuffer, 0, NULL) > 0) {
    		werror = MessageBuffer;
    		free(MessageBuffer);
    		return 0;
    	}
    
    	return GetLastError();
    }
    
    int main() {
    	std::string msg;
    
    	if (auto ret{ WinError(msg, 995) }; !ret)
    		std::cout << msg << '\n';
    	else
    		std::cout << "Error - " << ret << '\n';
    }
    Code:
    The I/O operation has been aborted because of either a thread exit or an application request.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #6
    Join Date
    Dec 2021
    Posts
    4

    Re: How to "FormatMessage()" my "WSAGetLastError()"

    Quote Originally Posted by 2kaud View Post
    This is what I used when I did Windows programming:

    Code:
    #define WIN32_LEAN_AND_MEAN
    #define NOMINMAX
    #include <windows.h>
    
    #include <string>
    #include <iostream>
    
    DWORD WinError(std::string& werror, DWORD p_dwError) {
    	LPSTR MessageBuffer;
    
    	werror.clear();
    
    	if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, p_dwError,
    		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&MessageBuffer, 0, NULL) > 0) {
    		werror = MessageBuffer;
    		free(MessageBuffer);
    		return 0;
    	}
    
    	return GetLastError();
    }
    
    int main() {
    	std::string msg;
    
    	if (auto ret{ WinError(msg, 995) }; !ret)
    		std::cout << msg << '\n';
    	else
    		std::cout << "Error - " << ret << '\n';
    }
    Code:
    The I/O operation has been aborted because of either a thread exit or an application request.
    Thanks for your answer 2kaud and VictorN, but your solution is for messages retrieved with '::GetLastError()'. Unfortunately it does not work for Messages retrieved with 'WSAGetLastError()' because these messages are stored in a different module than the deafult (here ws2_32.dll").

    Best
    \Ove

  7. #7
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: How to "FormatMessage()" my "WSAGetLastError()"

    Quote Originally Posted by \Ove View Post
    Thanks for your answer 2kaud and VictorN, but your solution is for messages retrieved with '::GetLastError()'. Unfortunately it does not work for Messages retrieved with 'WSAGetLastError()' because these messages are stored in a different module than the deafult (here ws2_32.dll").

    Best
    \Ove
    Well, did you try any of suggestion from these discussions in CG:
    Victor Nijegorodov

  8. #8
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: How to "FormatMessage()" my "WSAGetLastError()"

    it does not work for Messages retrieved with 'WSAGetLastError()'
    Well it seems to! eg WSA error code WSAEDESTADDRREQ (10039) is "Destination required"

    if you use 10039 in my code above, it shows:

    A required address was omitted from an operation on a socket.

    and 10040 (message too long) gives:

    A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was
    smaller than the datagram itself.

    So it seems to work...

    What issues are you getting? What wsa error code are you getting that isn't handled properly by FormatMessage() ??
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  9. #9
    Join Date
    Dec 2021
    Posts
    4

    Re: How to "FormatMessage()" my "WSAGetLastError()"

    Quote Originally Posted by 2kaud View Post
    Well it seems to! eg WSA error code WSAEDESTADDRREQ (10039) is "Destination required"

    if you use 10039 in my code above, it shows:

    A required address was omitted from an operation on a socket.

    and 10040 (message too long) gives:

    A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was
    smaller than the datagram itself.

    So it seems to work...

    What issues are you getting? What wsa error code are you getting that isn't handled properly by FormatMessage() ??

    Hmm. I tried your code again, and now it works! I just restarted the workstation. Could it be VS itself who caused the problem?.
    Anyway, the bottom line is: If you have *any* problem - reboot!

    Thank you for helping me out.

    \Ove

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured