hello, everybody.

here is a GetLastError Handling proc submitted by JimmClif.
if can't openport, it crashed.
how use the handleError proc ? please help.

regards.
		.486 

.model flat, stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include \masm32\include\windows.inc
include \masm32\include\shell32.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\user32.inc
include \masm32\include\gdi32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib

include \masm32\Macros\Macros.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
my_OpenPort proto
HandleError PROTO :DWORD
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
szPortName db "COM1",0
parf db "COM1: baud=9600 parity=N data=8 stop=1",0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hcomm dd ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code

start:
;-----------------------------------------------------------------------------
invoke my_OpenPort
.if eax==FALSE
jmp @f
.endif
invoke MessageBox,NULL,chr$("Passed: open port."),chr$("COMX_TEST."),MB_OK or MB_ICONEXCLAMATION ;

@@:
invoke ExitProcess,NULL

;------------------------------------------------------------------------------
my_OpenPort proc

invoke CreateFile,addr szPortName,GENERIC_READ or GENERIC_WRITE,0,NULL,OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL,NULL
invoke HandleError,eax

.if eax==INVALID_HANDLE_VALUE
invoke MessageBox, NULL, chr$("Cannot open Communication Port.Please\nQuit the program and Re-start your PC. Com Port Error"), chr$("COMX_TEST."),MB_OK or MB_ICONERROR
;invoke MessageBox, NULL, str$(eax), chr$("COMX_TEST."), MB_OK
mov eax,FALSE
jmp fret
.endif
mov hcomm,eax
mov eax,TRUE
fret: ret

my_OpenPort endp
;------------------------------------------------------------------------------
HandleError proc lpTitle:DWORD

LOCAL lpMsgBuffer : LPVOID ;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
HandleError endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

end start

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Posted on 2004-12-07 08:43:20 by dcskm4200
That HandleError proc does not "handle" the error, it just displays the error message at human readable format.

After error call HandleError as follows:

invoke HandleError, ADDR TitleBarText
Posted on 2004-12-07 11:24:07 by SamiP
Code Warrior SamiP:

Thank you very much.
now, i understood .
here, "lpMsgBuffer" is the character address corresponding error id that provided by windows system;
"lpTitle" is the character address corresponding a Title provided by user.
HandleError proc not only handle api calling error, but also handle api calling succeed.

regards.
Posted on 2004-12-07 23:15:29 by dcskm4200
Yeah, it also "handles" success. but in normal cases you only wan't to call HandleError when error occurs.
Posted on 2004-12-08 01:43:04 by SamiP
Hi dcskm4200,

Maybe "HandleError" was a little mis-named. "Handling" an error generally indicates that you will correct the situation that caused the error or exit gracefully from the program. This is called "Structured Exception Handling" or SEH and can be used effectively to display errors or even recover from them. You might want to check out Jeremy Gordon's tutorial on SEH at the following URL:

http://www.jorgon.freeserve.co.uk/ExceptFrame.htm
Posted on 2004-12-08 02:00:37 by donkey
Code Warrior SamiP and ASS-embler donkey:
thanks your guidances.

During code, I used to check a proc running at API called before i found the HandleError proc. i think the HandleError proc is better.

of course. on the name of the HandleError proc, I comprehended a mistake. if changed his name to "DspErrorMsg" , I easily understand. in most case, for avoiding to display any message when API called succeedly, i modified follow:



.486
.model flat, stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include \masm32\include\windows.inc
include \masm32\include\shell32.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comctl32.inc
include \masm32\include\comdlg32.inc
include \masm32\include\user32.inc
include \masm32\include\gdi32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib

include \masm32\Macros\Macros.asm
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
my_OpenPort proto
HandleError PROTO :DWORD
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
pzCaption db "COMX_TEST.",0
szPortName db "COM1",0
parf db "COM1: baud=9600 parity=N data=8 stop=1",0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hcomm dd ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code

start:
;-----------------------------------------------------------------------------
invoke my_OpenPort
.if eax==FALSE
jmp @f
.endif
invoke MessageBox,NULL,chr$("Passed: open port."),chr$("COMX_TEST."),MB_OK or MB_ICONEXCLAMATION ;
@@:
invoke ExitProcess,NULL

;------------------------------------------------------------------------------
my_OpenPort proc

invoke CreateFile,addr szPortName,GENERIC_READ or GENERIC_WRITE,0,NULL,OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL,NULL
push eax
invoke HandleError, addr pzCaption
pop eax
.if eax==INVALID_HANDLE_VALUE
mov eax,FALSE
jmp fret
.endif
mov hcomm,eax
mov eax,TRUE
fret: ret

my_OpenPort endp
;------------------------------------------------------------------------------
HandleError proc lpTitle:DWORD

LOCAL lpMsgBuffer:LPVOID ;dword
.if eax <= 0
; 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_ICONINFORMATION

; free memory
invoke LocalFree, lpMsgBuffer
.endif
ret
HandleError endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

end start

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

but a problem happen, when a process opened "com1" port, my code can't display any message. if I don't modify it, my code display "refuse access" . at one time, if succeedly opened "com1" port, it also display "succeed" that I don't need.
;=====================================================================
although i have read Jeremy Gordon's tutorial on SEH twice, but i understand a little. when coding, Error or Exception may be happen. Error affected a proc running. Exception not only affected a proc running, but also affected system running. so must be handle by system .
my question is follow:
in the windows system, no matter what Error or Exception. system give a user nothing information besides Error or Exception id (it is only a number). why can't give a user more information?

best regards
Posted on 2004-12-08 07:55:03 by dcskm4200
You should leave HandleError proc as it was and change my_OpenPort proc.

Firstly MSDN says CreateFiles returnvalues are:
Return Values
If the function succeeds, the return value is an open handle to the specified file. If the specified file exists before the function call and dwCreationDisposition is CREATE_ALWAYS or OPEN_ALWAYS, a call to GetLastError returns ERROR_ALREADY_EXISTS (even though the function has succeeded). If the file does not exist before the call, GetLastError returns zero.

If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

So my_OpenPort proc should be


my_OpenPort proc

invoke CreateFile,addr szPortName,GENERIC_READ or GENERIC_WRITE,0,NULL,OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL,NULL
.if eax == INVALID_HANDLE_VALUE
invoke HandleError
mov eax, FALSE
.else
mov hcomm, eax
mov eax, TRUE
.endif

fret: ret

my_OpenPort endp
Posted on 2004-12-08 09:07:07 by SamiP
Code Warrior SamiP:

Thank you very much.
Posted on 2004-12-08 10:31:42 by dcskm4200