• Welcome to Valhalla Legends Archive.
 

FormatMessage returning garbage

Started by Eli_1, June 11, 2004, 10:41 PM

Previous topic - Next topic

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:


...

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);

...

Sorry that looks so messy, the forum wraps it all.

main.cpp:


clswinsock2 mysck;

...

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

...

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


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?

Mephisto

I'm not entirely sure what your question is.  Can you clarify and specifically state your question/problem?

Eli_1

Why is FormatMessage returning four random characters instead of a sentence describing the error number I passed to it.

Toodles

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

Grok

Quote from: Eli_1 on June 11, 2004, 11:21 PM
Why is FormatMessage returning four random characters instead of a sentence describing the error number I passed to it.

errorbuff is already a pointer.

Mephisto

#5
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.

Zeller

Quote from: Grok on June 12, 2004, 12:03 AM
Quote from: Eli_1 on June 11, 2004, 11:21 PM
Why is FormatMessage returning four random characters instead of a sentence describing the error number I passed to it.

errorbuff is already a pointer.

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

Eli_1

#7
Quote from: Toodles on June 11, 2004, 11:54 PM
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...

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

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

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

QuoteI dont see any problems with errorbuff AFAIK. Can you show me exactly were the mistake is.

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

Arta

#8
FormatMessage takes a pointer to a pointer. It's easier just to have the system allocate the buffer for the message:


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;
}


Remember to call LocalFree() on the buffer when you're done with it.

Moonshine

#9
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?)

QuotenSize

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

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.

Eli_1

Quote from: Moonshine on June 12, 2004, 09:47 AM
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?)

QuotenSize

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

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.

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.

Eli_1

Boo, nothing is working yet.  :'(

Adron

Quote from: Eli_1 on June 12, 2004, 05:21 PM
Boo, nothing is working yet.  :'(


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;
}


Quote
Error: Åtkomst nekad.

Error message not available for 75! (317)
Error message not available for 317! (87)
Error: Felaktig parameter.

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.

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.