Error-handling in Win32, by Dracon
==================================

Hunting bugs is very annoying, especially if you use a Win32-Api function 
and it doesn't work for some reason. There is a way to get a nice formated 
error-message which will help in most cases.

Almost every api function sets, in case of failure, the global error 
variable to a special value. You can retrieve it with a call to 
"GetLastError()". This value alone is not very usefull, but you can use it 
to translate it into an error-string with "FormatMessage()". This function 
is quite complex, I will only concentrate on the things that are important 
for us:

DWORD FormatMessage(
  DWORD dwFlags,      // source and processing options
  LPCVOID lpSource,   // pointer to  message source
  DWORD dwMessageId,  // requested message identifier
  DWORD dwLanguageId, // language identifier for requested message
  LPTSTR lpBuffer,    // pointer to message buffer
  DWORD nSize,        // maximum size of message buffer
  va_list *Arguments  // pointer to array of message inserts
);

dwFlags:
	* FORMAT_MESSAGE_ALLOCATE_BUFFER will cause the function to allocate
	enough memory to hold the error string (LocalAlloc is used).
	
	* FORMAT_MESSAGE_FROM_SYSTEM will allow you to translate the result
	of GetLastError() into a string.
	
	* many more, check the doc

lpSource:
	not necessary for us, check the doc
	
dwMessageId:
	32-bit message identifier, the value returned by "GetLastError()"
	
dwLanguageId:
	- specify the language ID; primary and sublanguage ID must be combined
	  via the MAKELANGID macro (explained in the doc)
	- you can use SUBLANG_DEFAULT and LANG_NEUTRAL, but other languages are
	  possible too
	
lpBuffer:
	- pointer to a buffer OR 
	- the address of a variable where the pointer of a newly created buffer
	  will be stored (as in our case)
	
nSize:
	- maximum number of bytes if lpBuffer is provided OR
	- minimum number of bytes if the buffer should be allocated
	
Arguments:
	- check the doc, not necessary for us
	
RETURN value:
	- number of bytes stored in the output buffer
	- zero in case of failure

Even an example is given in the doc how to use it in conjunction with 
GetLastError(). I have ported my old C-Code to asm which will display a nice 
messagebox with the error message. The only parameter is the title of the 
messagebox, usually the name of the function that has caused the error. 

Sometimes the error message will be very strange, here are two examples and 
their meanings (unfortunately, I only know the german ones, but I have 
translated them roughly):

1) "The process was executed." (Der Vorgang wurde ausgefhrt.)
- no error has occured, everything is fine

2) "This is only possible in Win32 mode."
- In most cases you have used an invalid windows handle.


Check out "example.asm" for a short example how you can use "HandleError". I make use of the nice high-level features that Masm provides so you shouldn't have a problem to understand this "masterpiece". ;-)

Comments, hints or bugs can go to: andreas.theDragon@gmx.net

Greetings
=========
- Iczelion (win32asm.cjb.net)
- Knotty Dread (dread99.cjb.net)
