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
ADDR _ofn???
what's this?
Quote from: RuiLoureiro on November 06, 2009, 06:56:58 PM
Files attached
Rui,
No files attached. Post the complete code, please.
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.
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
We don't need the full code, we need a stripped down simple testcase.
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
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
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" ;-)
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 INVALID
O_...
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
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
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
Vista Ultimate 32-bit english with SP2: cann't get the error.
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.
UtillMasm,
Thank you for trying it :U
JJ,
Please give me the file MasmBasic.inc
You use «include \masm32\MasmBasic\MasmBasic.inc»
Thanks
Rui
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.libTry ...
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
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
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
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
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)