Valhalla Legends Forums Archive | C/C++ Programming | FormatMessage returning garbage

AuthorMessageTime
Eli_1
I'm not sure what I'm doing is called. I'm making a class that does all the dirty winsock work for me, so I can make apps much quicker. Is that what a wrapper is?

Anyway, I'm trying to use FormatMessage to get a error description from the error number returned by WSAGetLastError.

clswinsock2.h:

[code]
...

if (connect(sck, (sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) {
      isconnected = false;
      char errorbuff[512];
      if (WSAGetLastError() != 0) {
         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)errorbuff, 512, NULL);
         event_error(errorbuff);

...
[/code]
Sorry that looks so messy, the forum wraps it all.

main.cpp:

[code]
clswinsock2 mysck;

...

int main() {
mysck._connect("1.1.1.a", 6112);
}

...

clswinsock2::event_error(char *description) {
printf("Error: %s\n", description);
}
[/code]

In clswinsock2::event_error, description ends up being four unprintable characters:
1.) up-side-down pie symbol
2.) box
3.) \
4.) smiley face

Any ideas?
June 12, 2004, 3:41 AM
Mephisto
I'm not entirely sure what your question is. Can you clarify and specifically state your question/problem?
June 12, 2004, 4:18 AM
Eli_1
Why is FormatMessage returning four random characters instead of a sentence describing the error number I passed to it.
June 12, 2004, 4:21 AM
Toodles
I'm not sure if winsock makes u format the connection a certain way but i know i call the port than the server... That might have a sumthing to do with it...
June 12, 2004, 4:54 AM
Grok
[quote author=Eli_1 link=board=30;threadid=7211;start=0#msg64772 date=1087014112]
Why is FormatMessage returning four random characters instead of a sentence describing the error number I passed to it.
[/quote]

errorbuff is already a pointer.
June 12, 2004, 5:03 AM
Mephisto
You might also find formal documentation of the function useful: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/formatmessage.asp.

If you still have problems try to debug and see what is happening. It could be a simple error you have causing it. If you continue you to have problems post them on this thread.
June 12, 2004, 5:30 AM
Zeller
[quote author=Grok link=board=30;threadid=7211;start=0#msg64777 date=1087016593]
[quote author=Eli_1 link=board=30;threadid=7211;start=0#msg64772 date=1087014112]
Why is FormatMessage returning four random characters instead of a sentence describing the error number I passed to it.
[/quote]

errorbuff is already a pointer.
[/quote]

I dont see any problems with errorbuff AFAIK. Can you show me exactly were the mistake is.
June 12, 2004, 5:48 AM
Eli_1
[quote author=Toodles link=board=30;threadid=7211;start=0#msg64775 date=1087016090]
I'm not sure if winsock makes u format the connection a certain way but i know i call the port than the server... That might have a sumthing to do with it...
[/quote]

No, the order you set them doesn't matter.

[quote]You might also find formal documentation of the function useful: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/formatmessage.asp.

If you still have problems try to debug and see what is happening. It could be a simple error you have causing it. If you continue you to have problems post them on this thread. [/quote]

MSDN was the first place I went for the function's prototype. Even their example isn't working for me.

[quote]I dont see any problems with errorbuff AFAIK. Can you show me exactly were the mistake is. [/quote]

If for some reason, connect() fails, then I would get a description of the error that occured with FormatMessage. The error I'm trying to force is by connecting to an ip like "1.1.1.a", which is "Authoritive answer: Host not found."
June 12, 2004, 1:19 PM
Arta
FormatMessage takes a pointer to a pointer. It's easier just to have the system allocate the buffer for the message:

[code]
class CException
{
private:
   // ...
   LPSTR Message;
   //...
}

// In class body...
LPCSTR CException::GetMessage()
{   
   if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
         NULL, Code, 0, (char*)&Message, 0, NULL))
   {
      Message = (char*)LocalAlloc(LHND, 48);
      sprintf(Message, "Unable to provide message for error 0x%8.8X\n", Code);
   }

   return Message;
}
[/code]

Remember to call LocalFree() on the buffer when you're done with it.
June 12, 2004, 2:38 PM
Moonshine
Eli, yes that's called a wrapper. And also, I think your problem is you forgot to put WSAStartup() in main(), unless of course you were doing that on purpose to test errors. Moreover, your buffer size in FormatMessage ought to be:

(sizeof(errbuf) / sizeof(TCHAR)) - 1

Instead of 512 I believe, since FormatMessage is dealing with TCHARs (possible buffer overflow with specifying 512 TCHARs in a byte sized buffer?)

[quote]nSize

[in] If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies the maximum number of TCHARs that can be stored in the output buffer.[/quote]

Note that you need a pointer to a pointer if you specify FORMAT_MESSAGE_ALLOCATE_BUFFER, and only a pointer if you do not specify the aforementioned flag.

Edit: I suggest using the same method Arta posted; it's a lot less error-prone.
June 12, 2004, 2:47 PM
Eli_1
[quote author=Moonshine link=board=30;threadid=7211;start=0#msg64821 date=1087051640]
Eli, yes that's called a wrapper. And also, I think your problem is you forgot to put WSAStartup() in main(), unless of course you were doing that on purpose to test errors. Moreover, your buffer size in FormatMessage ought to be:

(sizeof(errbuf) / sizeof(TCHAR)) - 1

Instead of 512 I believe, since FormatMessage is dealing with TCHARs (possible buffer overflow with specifying 512 TCHARs in a byte sized buffer?)

[quote]nSize

[in] If the FORMAT_MESSAGE_ALLOCATE_BUFFER flag is not set, this parameter specifies the maximum number of TCHARs that can be stored in the output buffer.[/quote]

Note that you need a pointer to a pointer if you specify FORMAT_MESSAGE_ALLOCATE_BUFFER, and only a pointer if you do not specify the aforementioned flag.

Edit: I suggest using the same method Arta posted; it's a lot less error-prone.
[/quote]

Just walked in the house...

WSAStartup is part of the clswinsock2 contructor, Everything works, accept generating an error description from the number. I'll test some of the responses posted and get back to you.
June 12, 2004, 9:52 PM
Eli_1
Boo, nothing is working yet. :'(
June 12, 2004, 10:21 PM
Adron
[quote author=Eli_1 link=board=30;threadid=7211;start=0#msg64913 date=1087078913]
Boo, nothing is working yet. :'(
[/quote]

[code]
void printerror(int errcode)
{
   char errorbuff[512];
   if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)errorbuff, 512, NULL))
      printf("Error: %s\n", errorbuff);
   else {
      int err = GetLastError();
      printf("Error message not available for %d! (%d)\n", errcode, err);
      if(err != errcode) printerror(err);
   }
}

int main()
{
   printerror(5);
   printerror(75);
   return 0;
}
[/code]

[quote]
Error: Åtkomst nekad.

Error message not available for 75! (317)
Error message not available for 317! (87)
Error: Felaktig parameter.
[/quote]
June 12, 2004, 10:29 PM
Moonshine
Eli, it's probably not the best design to put WSAStartup() in your socket class' constructor. You only need to call WSAStartup() once in the application, and if you create multiple instances of your socket class, you'll be WSAStartup()'ing several times unnecessarily.
June 12, 2004, 10:49 PM
Mephisto
Making function calls in your constructor == not good. At least this is what I have come to learn from experience. The only way I use my constructor is to initalize variables (not static class variables) and a couple statements even.
June 12, 2004, 10:52 PM
Eli_1
[quote author=Moonshine link=board=30;threadid=7211;start=0#msg64920 date=1087080547]
... and if you create multiple instances of your socket class, you'll be WSAStartup()'ing several times unnecessarily.
[/quote]

Oops, I never thought about that. Thanks, moon.

[quote]...
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)errorbuff, 512, NULL)
...
[/quote]

Does anyone know why the function always fails when I pass errors returned by WSAGetLastError to it?

And why do you typecast to LPSTR and not LPTSTR? Are they the same, or is there some magical pointer thing that I'm still not grasping?

I don't understand all these different types!
*pulls out hair*
June 13, 2004, 12:06 AM
Moonshine
I tried using FormatMessage on WSAGetLastError(), and it worked for me:

A test on the fly I did:

[code]
#include <winsock2.h>
#include <iostream>

using namespace std;

int main( void ) {
WSADATA WSAData;
WSAStartup(MAKEWORD(2,0), &WSAData);

sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("1.1.1.a");
addr.sin_port = htons(6112);

char szBuffer[512];

SOCKET mysock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (mysock != INVALID_SOCKET) {

if (connect(mysock, (sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL,
SUBLANG_DEFAULT), szBuffer, (sizeof(szBuffer) / sizeof(TCHAR)) - 1, NULL);

cout << "Error Msg: " << szBuffer << endl;
}
}

WSACleanup();

return (0);
}
[/code]

Typecasting the buffer to LPTSTR or LPSTR when inputting it to FormatMessage() won't effect it I don't think; it'll treat the buffer as a TCHAR* regardless (unless you specify the local allocate flag of course)

Also again be careful about that maximum buffer size parameter, it takes in the number of TCHARs (2-bytes in size?) NOT bytes maximum.

PS: LPTSTR is a TCHAR* ; LPSTR is char*
June 13, 2004, 12:11 AM
Eli_1
I compiled your code in a different project and got this output:

[quote]
Error Msg:
[/quote]

My computer hates me or something... :-\
June 13, 2004, 12:40 AM
Moonshine
[quote author=Eli_1 link=board=30;threadid=7211;start=15#msg64934 date=1087087242]
I compiled your code in a different project and got this output:

[quote]
Error Msg:
[/quote]

My computer hates me or something... :-\
[/quote]

Realllly? What compiler are you using? I'm using Microsoft Visual C++ .NET (2003), and I received an error message (too lazy to check what it was again), works for me..
June 13, 2004, 12:46 AM
Eli_1
Whatever the free Borland compiler is. But remember, I'm recieving an error message when I pass an error code of 5, but not 10049 (WSAGetLastError).
June 13, 2004, 1:52 AM
Moonshine
[quote author=Eli_1 link=board=30;threadid=7211;start=15#msg64952 date=1087091522]
Whatever the free Borland compiler is. But remember, I'm recieving an error message when I pass an error code of 5, but not 10049 (WSAGetLastError).
[/quote]

Eww @ Borland :P
June 13, 2004, 2:30 AM

Search