GetErrDescription in Masm32.lib looks like this:
.data
ErrMsgTmpl db 'Error Code %i',13,10
db 'Description: %s',0
Unknown db 'UnKnownError',0
.code
GetErrDescription proc uses ebx edi ErrNum:DWORD
LOCAL hLocal:DWORD
LOCAL Buffer[256]:BYTE
mov eax,ErrNum
or eax,eax
jne WeAlreadyKnowIt
invoke GetLastError
WeAlreadyKnowIt:
mov edi,eax
invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER or \
FORMAT_MESSAGE_FROM_SYSTEM,
0, ; GetItFromSystem
edi,0, ; ErrNum,Default language
addr hLocal, ; where to send the address of string from system
0,0 ; any size, no arguments
or eax,eax
mov ebx,offset UnKnown
je UnKnown
invoke LocalLock,hLocal
mov ebx,eax
UnKnown:
invoke wsprintf,addr Buffer,offset ErrMsgTmpl,edi,ebx
invoke MessageBox,0,addr Buffer,0,0
cmp ebx,offset UnKnown
je @F
invoke LocalFree,hLocal
@@:
ret
GetErrDescription endp
Refering to the item 'UnKnown' it is defined twice, once in a data statement, and once as a label. If I try to do something similar, I get "error A2005: symbol redefinition : "
Why doesn't this code get the error? (and as a sub-question, why would anyone ever code like this? It took me 10 minutes to notice that UnKnown was declared twice, I thought the code was moving the address of the label into ebx which made no sense at all!).
Unknown the variable is spelled with a lowercase "k". UnKnown the label is spelled with an uppercase "K". MASM is case-sensitive, so both symbols are considered different and do not conflict with each other.
Yes, bad style.
Duh... Thanks, I even looked for that and couldn't see it!
But.... Then he is actually loading the address of the label, not the data statement, and the data is not being used at all. Now I'm really confused. What's the purpose of the data statement?
Hello,
There is no need of the data statement,have a look at the code below.
The function retrieve the windows error message with the code of the last error.
The message can be in your native langage.
The last error code is provide by the system and all you have to do is provide a title for the messagebox,that's all.
ToutEnMasm
; ########################################################################
RetrouveMessageErreur proc lpTitle:DWORD
LOCAL lpMsgBuffer : DWORD
; calculate language ID, asm version of MAKELANGID
mov cx, SUBLANG_DEFAULT
shl ecx, 10
;or cx, LANG_NEUTRAL ; LANG_NEUTRAL = 0, nothing necessary
; Setup parameters for FormatMessage, normal pushing to use some
; params directly (e.g. GetLastError returns the ID in eax, but I
; can't use this register in "invoke")
push NULL ; we don't need this
push 0 ; min. size of output buffer if we use
; FORMAT_MESSAGE_ALLOCATE_BUFFER
lea eax, lpMsgBuffer ; get address of our buffer
push eax ; address of buffer
push ecx ; our language ID, calculated above
invoke GetLastError ; get error number
push eax ; push return value = error ID
push NULL ; can be used to format a string, we don't need it
mov edx, FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM
push edx ; some flags, check your doc for more
call FormatMessage ; here we go
; Display error-message
invoke MessageBox, NULL, lpMsgBuffer, lpTitle, MB_OK or MB_ICONSTOP
; free memory
invoke LocalFree, lpMsgBuffer
ret
Hello ToutEnMasm,
You can simplify things a little bit, the SHL for example can be made at compile: :wink
errorBox proc lpTitle:DWORD
LOCAL errorBuffer:DWORD
invoke GetLastError
lea edx, errorBuffer
invoke FormatMessage, (FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM), NULL, eax, (SUBLANG_DEFAULT SHL 10), \
edx, NULL, NULL
invoke MessageBox, NULL, errorBuffer, lpTitle, MB_OK or MB_ICONSTOP
invoke LocalFree, errorBuffer
ret
errorBox endp
Ok, getting back to the original masm32.lib routine--
I believe that that the line-
mov ebx,offset UnKnown
should have been-
mov ebx,offset Unknown
so that if FormatMessage return a zero, meaning it can't make the error comment, the string 'UnKnownError',0 will be used.
I think the author shot himself in the foot here using the same id for the data statement and the label and screwed it up.
Hutch-- please consider this fix for the next release (and change the label to @@ or something!).
Jim,
Signs of senile decay is I don't even remember who wrote it, I remember Iczelion using this technique and vagualy I remember Ernie Murphy having done a version but for the life of me, I don't know who wrote this one.