The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: RuiLoureiro on November 06, 2009, 06:56:58 PM

Title: GetOpenFileName causes an error
Post by: RuiLoureiro on November 06, 2009, 06:56:58 PM
Hi,
           When i try to open one file and then try to open another, and then
           try to open another repeatedly, there is one case where the prog is closed
           What closes it ? Why ? I tried Olly debugger without success

           Meanwhile i put 2 message box4es before and after GetOpenFileName

;##############
call  Test3
                invoke  GetOpenFileName, ADDR _ofn
call  Test4
;##############

           and i got that it calls GetOpenFileName and doesnt exit and
           closes the prog and i dont see Test4 window
           

           To open a file i call «AbreFile»

           Someone can help me and say me why it closes
           Is there any known problem with that API
           Thanks
           
           The procedure is this:
           Files attached
Quote
; Choose a File to open and then Open the file, get the length
; Read it to Text Buffer
AbreFile        proc

                ;
                ; Close the previous
                ; »»»»»»»»»»»»»»»»»»
                call      CloseAll

                mov       ebx, offset _FileName

                ; »»»»»»»»»»»»»»»»»»»»»
                ; Get File Name to open OPENFILENAME
                ; »»»»»»»»»»»»»»»»»»»»»
                mov     _ofn.lStructSize, SIZEOF _ofn
                push    _hWnd
                pop     _ofn.hWndOwner

                push    _hInstance
                pop     _ofn.hInstance
                mov     _ofn.lpstrFilter, OFFSET _FilterString
                mov     _ofn.lpstrFile, OFFSET _FileName
                mov     _ofn.nMaxFile, MAXSIZE
                mov     _ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or \
                                    OFN_HIDEREADONLY               
                mov     _ofn.lpstrTitle, OFFSET _OurTitle
                ;
                mov     _ofn.lCustData, NULL
                mov     _ofn.lpfnHook, NULL
                mov     _ofn.lpTemplateName, NULL               
                ;
;##############
call  Test3
;##############
                invoke  GetOpenFileName, ADDR _ofn
;#############
call  Test4
;#############
                cmp     eax, TRUE
                je      short @F
               
                ; »»»»»»»»»»»»»»»»»»»
                ; Change Window Title
                ; »»»»»»»»»»»»»»»»»»»               
                invoke    SetWindowText, _hWnd, addr _WindowName
                ret
               
                ; »»»»»»»»»
                ; Open File
                ; »»»»»»»»»
@@:             invoke    CreateFile, ebx, $ModoAberRd, $ShareFic, NULL,
                                           $AbreOuErro, $ArquivoAll, NULL
                cmp       eax, INVALID_HANDLE_VALUE
                je        _erro                                       ; erro
                ;
                ; Save the handle
                ; »»»»»»»»»»»»»»»
                mov       _hFile, eax
                ;
                ; Get the Length
                ; »»»»»»»»»»»»»»
                invoke    GetFileSize, eax, NULL
                cmp       eax, INVALIDO_SET_FILE_POINTER
                jne     short @F
                ;
                call      SendErro
                call      CloseAll               
                ret

                ; »»»»»»»»»»»»»»»»»»»»
                ; _lFile = File Length
                ; »»»»»»»»»»»»»»»»»»»»
@@:             mov       _lFile, eax
                cmp       eax, 0
                jne       short @F

                fn  MessageBox, _hWnd, "The File has nothing", "File Error", MB_OK
                call      CloseAll
                ret
               
                ; »»»»»»»»»»»»»»»»»»»»»»»»»»
                ; Alloc memory for eax bytes
                ; »»»»»»»»»»»»»»»»»»»»»»»»»»
@@:             invoke    AlocRclMem, eax
                jnc       short @F
               
                call      SendErro
                call      CloseAll
                ret
               
                ; »»»»»»»»»»»»»»»»»»»»
                ;      Read File
                ; »»»»»»»»»»»»»»»»»»»»
@@:             mov       _pTxtMem, eax
                mov       _pTxtBuf, edi
                ;
                call      FileRead
                jnc       short @F
                ;
                call      CloseAll
                ret

                ; »»»»»»»»»»»»»»»»»»»
                ;     Close File
                ; »»»»»»»»»»»»»»»»»»»
@@:             invoke    CloseHandle, _hFile
                mov       _hFile, 0
               
                ; »»»»»»»»»»»»»»»»»»»
                ; Change Window Title
                ; »»»»»»»»»»»»»»»»»»»
                invoke    SetWindowText, _hWnd, addr _FileName
                ret
                ;
_erro:          call      CloseAll
                call      SendErro
                ret
AbreFile        endp
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Free memory alloc and close file
;
CloseAll        proc
                ;
                cmp       _pTxtMem, 0
                je        short @F
                ;
                invoke    GlobalFree, _pTxtMem
                mov       _pTxtMem, 0
                mov       _pTxtBuf, 0               
                ;
@@:             cmp       _hFile, 0
                je        short @F
               
                invoke    CloseHandle, _hFile
                mov       _hFile, 0
   
@@:             invoke    SetWindowText, _hWnd, addr _WindowName
                ;
                ret
CloseAll        endp
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
; Input:
;       _hFile  - file handle
;       _lFile  - file length
;
FileRead        proc

                mov     eax, _lFile
                mov     ebx, _pTxtBuf
               
                cmp     eax, dword ptr [ebx - 8]    ; max buffer length
                jbe     short @F

                fn  MessageBox, _hWnd, "The File is too long", "File Error", MB_OK
                ;
                ; File is too long
                ; »»»»»»»»»»»»»»»»
_erro:          mov       dword ptr [ebx - 4], 0      ; buffer length
                call      SendErro
                stc
                ret
                ;
@@:             invoke    ReadFile, _hFile, ebx, _lFile, addr _BytesRead, NULL
                cmp       eax, 0
                je        _erro

                mov       eax, _BytesRead
                cmp     eax, _lFile
                je        short @F
                ;
                call      SendErro               
                stc
                ret
                ;
@@:             mov     dword ptr [ebx - 4], eax
                ;
                add     eax, ebx
                mov     _LastTxtBuf, eax        ; points to the end address                               
                clc
                ret
FileRead        endp
 

Thanks     
Rui
Title: Re: GetOpenFileName causes an error
Post by: UtillMasm on November 07, 2009, 03:41:30 AM
ADDR _ofn???

what's this?
Title: Re: GetOpenFileName causes an error
Post by: jj2007 on November 07, 2009, 07:09:40 AM
Quote from: RuiLoureiro on November 06, 2009, 06:56:58 PM
           Files attached

Rui,
No files attached. Post the complete code, please.
Title: Re: GetOpenFileName causes an error
Post by: sinsi on November 07, 2009, 07:14:18 AM
Check that your _ofn structure is the right version for the windows you are testing on, zero all of the structure members first and make sure it's aligned to 4.
Title: Re: GetOpenFileName causes an error
Post by: jj2007 on November 07, 2009, 07:36:38 AM
Quote from: sinsi on November 07, 2009, 07:14:18 AM
Check that your _ofn structure is the right version for the windows you are testing on

mov _ofn.lStructSize, SIZEOF _ofn should tell Windows the version, right?

Quote
, zero all of the structure members first and make sure it's aligned to 4.

GetOpenFileName() Fails If lpstrFile Buffer Is Not NULL Terminated (http://support.microsoft.com/kb/222003)
GetOpenFileName() fails under Windows 95/98/NT/ME due to incorrect OPENFILENAME structure size (http://support.embarcadero.com/article/35754)

Again, full code please. Maybe we should add to the forum rules that detailed requests for help are only allowed if the full code is attached :bg
Title: Re: GetOpenFileName causes an error
Post by: BlackVortex on November 07, 2009, 01:07:58 PM
We don't need the full code, we need a stripped down simple testcase.
Title: Re: GetOpenFileName causes an error
Post by: RuiLoureiro on November 07, 2009, 02:26:29 PM
My thanks to sinsi, Jochen, BlackVortex 

Hi,
         Meanwhile i found the solution: before calling GetOpenFileName
         i call CloseAll which calls GlobalFree to Free memory
         previously allocated if _pTxtMem != 0. In some
         cases it doesnt free the memory and i call GetOpenFileName
         In this case a proc inside ntdll.dll doesnt work properly
         and closes the prog or sends EXCEPTION_ACCESS_VIOLATION.
               
         What to do ? Instead of using GlobalAlloc after GetOpenFileName
         i decided to allocte memory when the prog starts. In this
         way i dont need to use GlobalFree-GlobalAlloc between
         GetOpenFileName and the probelm is solved.
         Thanks for all

Jochen,
         NEW forum rules: who helps must give a complete  working example ! :green2
         Sorry, i forgot to upload the files.
         See it on «printing a file on my printer». Files: PrintIt.zip

         If you want see the original say and i will post it here, ok
:thumbu
Rui
Title: Re: GetOpenFileName causes an error
Post by: jj2007 on November 07, 2009, 02:38:10 PM
Quote from: RuiLoureiro on November 07, 2009, 02:26:29 PM
Jochen,
         NEW forum rules: who helps must give a complete  working example ! :green2

Rui,
         that rule is too strict. After all, people post here because their examples are not working, hehe!
:bg
Title: Re: GetOpenFileName causes an error
Post by: jj2007 on November 07, 2009, 02:52:26 PM
Quote from: RuiLoureiro on November 07, 2009, 02:26:29 PM

         See it on «printing a file on my printer». Files: PrintIt.zip


Works fine and assembles fine, even with "INVALIDO_SET_FILE_POINTER" ;-)
Title: Re: GetOpenFileName causes an error
Post by: RuiLoureiro on November 07, 2009, 04:28:37 PM
Quote from: jj2007 on November 07, 2009, 02:52:26 PM
Works fine and assembles fine, even with "INVALIDO_SET_FILE_POINTER" ;-)
              Thanks Jochen for trying it and for your helps
               I upload it again bcause i added a little detail: the words «Print It» on the screen
               I know you have INVALID_... so i define INVALIDO_...

               Now i remember you can test Printer12 to get the error  i post in this Topic. Printer12 is in «printing a file on my printer» topic
               Try Choose File, Choose File, ..., repeately until the error (but choose a file !)

     LATER: UtillMasm,
                                 _ofn is the OPENFILENAME structure defined like this:
                                _ofn         OPENFILENAME <?>       
                                 in .data? section
Thank you all
and stay well
Rui

           
Title: Re: GetOpenFileName causes an error
Post by: Slugsnack on November 07, 2009, 06:08:56 PM
Actually I'm not sure it's your fault. I recall experiencing this before too. The program would run perfectly when run without a debugger and there was no SEH/VEH but upon running in OllyDbg it would crash.

If you google 'GetOpenFileName OllyDbg' you'll see other people have had this happen too
Title: Re: GetOpenFileName causes an error
Post by: RuiLoureiro on November 07, 2009, 06:22:23 PM
Quote from: Slugsnack on November 07, 2009, 06:08:56 PM
Actually I'm not sure it's your fault. I recall experiencing this before too. The program would run perfectly when run without a debugger and there was no SEH/VEH but upon running in OllyDbg it would crash.

If you google 'GetOpenFileName OllyDbg' you'll see other people have had this happen too

Slugsnack,
                Thank you for your info. It help us  too :U
RuiLoureiro
Title: Re: GetOpenFileName causes an error
Post by: UtillMasm on November 08, 2009, 08:34:58 AM
Vista Ultimate 32-bit english with SP2: cann't get the error.
Title: Re: GetOpenFileName causes an error
Post by: jj2007 on November 08, 2009, 09:40:34 AM
Quote from: RuiLoureiro on November 07, 2009, 04:28:37 PM
               Now i remember you can test Printer12 to get the error  i post in this Topic. Printer12 is in «printing a file on my printer» topic

Rui,
After a lot of fumbling, I got printer12 running. The error is there, but GetOpenFilename is innocent: it happens somewhere in the readfile etc. section below.
Title: Re: GetOpenFileName causes an error
Post by: RuiLoureiro on November 08, 2009, 11:18:59 AM
UtillMasm,
                    Thank you for trying it  :U
JJ,
          Please give me the file MasmBasic.inc
          You use «include \masm32\MasmBasic\MasmBasic.inc»
Thanks
Rui
Title: Re: GetOpenFileName causes an error
Post by: jj2007 on November 08, 2009, 12:30:44 PM
Quote from: RuiLoureiro on November 08, 2009, 11:18:59 AM
JJ,
          Please give me the file MasmBasic.inc
          You use «include \masm32\MasmBasic\MasmBasic.inc»

Rui,
The file is part of MasmBasic (http://www.masm32.com/board/index.php?topic=12460), and I used it only because the library has a very powerful debugging macro. Replace the include with include \masm32\include\masm32rt.inc, and the code will assemble fine. Masm32rt.inc substiutes all lines from .586 to comdlg32.lib

Try ...
                invoke  GetOpenFileName, ADDR _ofn
         
                stc
                ret


... and you will see that you can call GetOpenFileName as often as you want, no crashes. The problem is below these lines...

EDIT: I have put lots of deb calls into your code; you can uncomment them if you have MasmBasic installed. From what I see, the crash happens in the GetOpenFileName call, but only if the section below has been processed before.
You should urgently check your usage of ebx, esi and edi. I have added a uses ebx to AbreFile, but this was not sufficient to prevent the crash. The deb macro is really useful for that...

Quotedeb usage:
   deb 1, "The first loop", ecx, esi$, edi$, MyReal10, ST(1)
   deb 2, "Second loop:", al, ecx, esi$, $My$

Rem   the debug macro preserves registers and flags
   can show FPU registers but trashes ST(6) and ST(7)
   the string content of registers (i.e. the memory pointed at) can be shown by using eax$, ecx$, esi$ etc.
   global and local variables can be shown as strings by using e.g. $buffer
   cancelling deb 1, ... does not cancel deb 2, ..., so you can test several loops in one go
   deb 1, ... deb 4, ... are being displayed, while deb 5, writes to a file:
   deb 5, "ToFile", eax, esi$, edi$ saves contents (without showing them) to DebLog.txt
Title: Re: GetOpenFileName causes an error
Post by: RuiLoureiro on November 08, 2009, 03:47:25 PM
Jochen,
           1. Thanks for reply
Quote
           You should urgently check your usage of ebx, esi and edi.
           2. EDI usage: ONLY defined inside NxtLinFrm and GetNxtLin
                         never modified in any other place.
                         There, i have «mov edi, _pFrmBuf». _pFrmBuf is
                         defined when the prog starts (Mem is allocated ...)

              ESI usage: is modified in FindCRLF but have a limit in _LastTxtBuf

           I am quite sure theres not any problems with that registers and
           we dont need to preserve them.           

         3. Please, now, Try PrinterJJ.asm i attached. What happen ?
            I tried and i got «Memory was not freed»
           
            I did this:
Quote
; Free memory alloc and close file
CloseAll        proc
                pushfd
                ;
                cmp       _pTxtMem, 0
                je        short _n
                ;
                invoke    GlobalFree, _pTxtMem
                cmp       eax, NULL
                je        short @F               
;##############################################################################
       fn  MessageBox, _hWnd, "Memory was not freed", "Memory Error", MB_OK
;##############################################################################
@@:             mov       _pTxtMem, 0
                ;
_n:             cmp       _hFile, 0
                je        short @F               
                invoke    CloseHandle, _hFile
                mov       _hFile, 0
 
@@:             popfd
                ret
CloseAll        endp
Rui
Title: Re: GetOpenFileName causes an error
Post by: jj2007 on November 08, 2009, 09:06:20 PM
Quote from: RuiLoureiro on November 08, 2009, 03:47:25 PM
           2. EDI usage: ONLY defined inside NxtLinFrm and GetNxtLin
Rui,

esi, edi and ebx are being used by Windows APIs. You can use them only if you preserve them:
push esi
mov esi, 123
...
pop esi


If you modify them, e.g. in the WndProc or a proc called from inside the WndProc, then your code is bound to crash.

Quote
         3. Please, now, Try PrinterJJ.asm i attached. What happen ?

It crashes silently.

Will be offline for some days - I hope you can solve the mystery :thumbu
Title: Re: GetOpenFileName causes an error
Post by: RuiLoureiro on November 08, 2009, 09:27:58 PM
Quote from: jj2007 on November 08, 2009, 09:06:20 PM
esi, edi and ebx are being used by Windows APIs. You can use them only if you preserve them:
               As far as i know Windows APIs preserve them. It means i dont need to preserve
               that registers when i call a wAPI. As far as i know MS doesnt say
               you need to preserve it unless Windows APIs doesnt work properly. In
               other words, if you dont preserve them Windows APIs doesnt work properly.
Quote
I hope you can solve the mystery
               I solved it, i allocate memory when the prog starts. It is done in PrintIt
Quote
Will be offline for some days
               Jochen, thanks, and have a nice days :thumbu

 
Title: Re: GetOpenFileName causes an error
Post by: qWord on November 08, 2009, 10:14:19 PM
Quote from: RuiLoureiro on November 08, 2009, 09:27:58 PM
               As far as i know Windows APIs preserve them. It means i dont need to preserve
               that registers when i call a wAPI. As far as i know MS doesnt say
               you need to preserve it unless Windows APIs doesnt work properly. In
               other words, if you dont preserve them Windows APIs doesnt work properly.
You must save them only inside callbacks (e.g. WndProc)