.386
.model flat, stdcall
option casemap: none
include windows.inc
;;;;;
include kernel32.inc
include user32.inc
include masm32.inc
;;;;;
includelib kernel32.lib
includelib user32.lib
includelib masm32.lib
.data
;;;;;
szCapt db "App", 0
szErrAllocFailed db "Memory alloc failed.", 0
szFile db "C:\Program Files\ZWCAD 2009 Chs\ZWCAD.EXE", 0
szErrReadFailed db "File read failed.", 0
szErrMemAllocFailed db "Memory alloc failed.", 0
.data?
;;;;;
pFile dd ?
nFileLen dd ?
hGlobal dd ?
pGlobal dd ?
.code
;;;;;
DoThing proc
invoke read_disk_file, addr szFile, addr pFile, addr nFileLen
.if eax == 0
invoke MessageBox, NULL, addr szErrReadFailed, addr szCapt, MB_OK
ret
.endif
invoke GlobalFree, pFile
invoke IntMul, nFileLen, 3
invoke GlobalAlloc, GMEM_FIXED, eax
.if eax == NULL
invoke MessageBox, NULL, addr szErrMemAllocFailed, addr szCapt, MB_OK
ret
.endif
mov hGlobal, eax
invoke GlobalLock, hGlobal
.if eax == NULL
invoke GlobalFree, hGlobal
invoke MessageBox, NULL, NULL, NULL, MB_OK
ret
.endif
mov pGlobal, eax
;;;;; while the follwing function will cause memory written error???
;;;;;
invoke bin2hex, pFile, nFileLen, pGlobal
invoke GlobalFree, hGlobal
ret
DoThing endp
;;;;;
start:
;;;;;
invoke DoThing
invoke ExitProcess, 0
;;;;;
end start
Maybe the invoke GlobalFree, pFile comes a bit too early??
QuoteMaybe the invoke GlobalFree, pFile comes a bit too early??
No, he returns before the call if the result is NULL.
There is no need to lock global memory that has been allocated using GMEM_FIXED. Outside of that a quick look at the code shows no glaring errors in logic. I would remove that line and try it again. If that is not the problem start to take a hard look at what the bin2hex function is expecting, not familiar with that API.
Quote from: donkey on July 24, 2009, 03:39:06 AM
QuoteMaybe the invoke GlobalFree, pFile comes a bit too early??
No, he returns before the call if the result is NULL.
Explain, please.
Quote invoke GlobalFree, pFile
...
invoke bin2hex, pFile, nFileLen, pGlobal
bin2hex is a masm32 function who translate binary code in ascii caracters.
Quote
Comments
The output data is approximately 3 times longer than the source data as it uses 2 characters plus a space for every byte in HEX format. The destination buffer should be at least 3 times the length of the source buffer to hold the result
This mean that you have to verify this,that is a very bad method.Dynamic allocation of memory here will be a good thing with a function who return a pointer on the allocated memory .
An alternative could be
get the file size, multiply it by four (instead of three).This will made (perhaps) an enough secure coefficient who grant no writing outside the buffer.
I couldnt help but notice this, so i thought i'd ask...
Quote
Insert Quote
.386
.model flat, stdcall
option casemap: none
include windows.inc
;;;;;
include kernel32.inc
include user32.inc
include masm32.inc
;;;;;
includelib kernel32.lib
includelib user32.lib
includelib masm32.lib
.data
;;;;;
szCapt db "App", 0
szErrAllocFailed db "Memory alloc failed.", 0
szFile db "C:\Program Files\ZWCAD 2009 Chs\ZWCAD.EXE", 0
szErrReadFailed db "File read failed.", 0
szErrMemAllocFailed db "Memory alloc failed.", 0
.data?
;;;;;
pFile dd ?
nFileLen dd ?
hGlobal dd ?
pGlobal dd ?
.code
;;;;;
DoThing proc
invoke read_disk_file, addr szFile, addr pFile, addr nFileLen
.if eax == 0
invoke MessageBox, NULL, addr szErrReadFailed, addr szCapt, MB_OK
ret
.endif
invoke GlobalFree, pFile ;Why are you freeing this memory here....
invoke IntMul, nFileLen, 3
invoke GlobalAlloc, GMEM_FIXED, eax
.if eax == NULL
invoke MessageBox, NULL, addr szErrMemAllocFailed, addr szCapt, MB_OK
ret
.endif
mov hGlobal, eax
invoke GlobalLock, hGlobal
.if eax == NULL
invoke GlobalFree, hGlobal
invoke MessageBox, NULL, NULL, NULL, MB_OK
ret
.endif
mov pGlobal, eax
;;;;; while the follwing function will cause memory written error???
;;;;;
invoke bin2hex, pFile, nFileLen, pGlobal When you are trying to use the memory here?
invoke GlobalFree, hGlobal
ret
DoThing endp
;;;;;
start:
;;;;;
invoke DoThing
invoke ExitProcess, 0
;;;;;
end start
About Bin2Hex, i dont see that you'd need more memory once you've multiplied it x3, we can see that this is the logical amount needed. Like the comment says, it requires 3 bytes for each single byte of hex that it converts, so the only discrepancy i can see would be the NULL terminator to finish the string. I can't honestly see other way to use more than the prescribed 3:1 ratio. What are your thoughts?
HR,
Ghandi
Quote from: Ghandi on July 25, 2009, 05:14:00 AM
I couldnt help but notice this, so i thought i'd ask...
Quote
invoke GlobalFree, pFile ;Why are you freeing this memory here....
I have already asked above (http://www.masm32.com/board/index.php?topic=11920.msg90471#msg90471) but Donkey says no problem.
Quote from: jj2007 on July 25, 2009, 06:20:15 AM
Quote from: Ghandi on July 25, 2009, 05:14:00 AM
I couldnt help but notice this, so i thought i'd ask...
Quote
invoke GlobalFree, pFile ;Why are you freeing this memory here....
I have already asked above (http://www.masm32.com/board/index.php?topic=11920.msg90471#msg90471) but Donkey says no problem.
Since I don't use MASM or the MASM32 library I don't know the pre-req's for its functions so I was probably better not to comment but I hadn't realized there were so many lib functions in the app. This is yet another reason I tend to use a "roll your own" approach to assembly language.
Quote from: donkey on July 25, 2009, 06:38:46 AM
Since I don't use MASM or the MASM32 library I don't know the pre-req's for its functions
Both Ghandi and myself have noticed that zjw uses a pointer after discarding it with GlobalFree. That has nothing to do with the Masm32 library.
@jj2007: I thought you may have meant the same thing, i just wasnt sure, which is why i posted.
@donkey: I agree with jj2007, freeing memory before using it is a bad thing to be doing, no matter what language it is written in.
I am curious about your statement that you prefer to 'roll your own' solutions. I also like to code my own solutions whenever possible, but looking at this code example there are only 2 calls to non Win32 API functions. Although it is possible, i dont feel that i'd gain anything by rewriting MessageBox or any of the memory functions, what functionality in this example can be 'home rolled'? :)
As a sidenote, i've realized that i am wrong about Bin2Hex only needing 3x the amount of bytes that the raw hex occupies once i looked at the code. Every 8 bytes of hex converted gets "- " appended and every 16 bytes gets a CRLF appended. This means that for every 16 bytes of hex will require 36 bytes of buffer for the ascii. If this is being used on a larger file, then the size discrepency will be significant.
ToutEnMasm was correct, an output buffer that is 4x the size of the input data will be sufficient to hold the outputted ascii.
You could replace:
invoke IntMul, nFileLen, 3
with:
MOV EAX,nFileLen
SHL EAX,2
HR,
Ghandi
Thank everybody for help me.
.386
.model flat, stdcall
option casemap: none
include C:\masm32\include\windows.inc
;;;;;
include C:\masm32\include\kernel32.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\masm32.inc
;;;;;
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\masm32.lib
.data
;;;;;
szCapt db "App", 0
szErrAllocFailed db "Memory alloc failed.", 0
szFile db "C:\Program Files\ZWCAD 2009 Chs\ZWCAD.EXE", 0
szErrReadFailed db "File read failed.", 0
szErrMemAllocFailed db "Memory alloc failed.", 0
.data?
;;;;;
pFile dd ?
nFileLen dd ?
hGlobal dd ?
pGlobal dd ?
.code
;;;;;
DoThing proc
invoke read_disk_file, addr szFile, addr pFile, addr nFileLen
.if eax == 0
invoke MessageBox, NULL, addr szErrReadFailed, addr szCapt, MB_OK
ret
.endif
invoke GlobalFree, pFile
;;;; Replace 3 with 4, it works!
invoke IntMul, nFileLen, 4
invoke GlobalAlloc, GMEM_FIXED, eax
.if eax == NULL
invoke MessageBox, NULL, addr szErrMemAllocFailed, addr szCapt, MB_OK
ret
.endif
mov hGlobal, eax
invoke GlobalLock, hGlobal
.if eax == NULL
invoke GlobalFree, hGlobal
invoke MessageBox, NULL, NULL, NULL, MB_OK
ret
.endif
mov pGlobal, eax
;;;;; while the follwing function will cause memory written error???
;;;;;
invoke bin2hex, pFile, nFileLen, pGlobal
invoke GlobalFree, hGlobal
ret
DoThing endp
;;;;;
start:
;;;;;
invoke DoThing
invoke ExitProcess, 0
;;;;;
end start
i haven't tried it with global or local allocation functions
but with the heap functions, you can use the block after it has been freed
of course, you are asking for trouble, as that memory may be allocated elsewhere and cause a conflict - lol
but, i thought it was interesting that you could still access that memory without an access violation
i guess, afterall, the memory in the heap DOES belong to your process
Hehe, Some thing in ASM was funny.
That's the reason I learnit, I can know Windows deeper.
Trying to use allocated memory that has already been freed is at best a risky business, if nothing else has happened it often works but it may be allocated for something else then you get a CRASH !!!! Apply the normal law of gravity here, what goes up must come down, allocate memory where you need it, use it THEN deallocate it when you no longer need it.
Oh, Thanks.
My English is very poor.
Sometimes I can not express what I want to say.