The procedure "NameFromPath" (NAMEFPTH.ASM in M32LIB)
extracts the File Name from a Full Path to an output buffer.
I found that the procedure in my copy of M32LIB also moves
some of the data AFTER the File Name to the output buffer.
Maybe this has been corrected in the latest version.
I'm using masm vers 8.0.
It's a small procedure, easy to fix.
Hello Earl, are you saying that it copies data past the terminating null?
Try this (untested):
invoke GetModuleFileName,0,addr lpCfgPath,255
.if eax==0 ; problem?
jmp error
.else ; get filename in result
mov edx, offset lpCfgPath ; destination string offset in edx
@@: ; loop to find end of string
mov al, byte ptr [edx] ; get byte into al
inc edx ; increment pointer offset
cmp al, 00 ; at end yet?
jnz @B ; if not, loop
@@:
dec edx ; decrement pointer offset
mov al, byte ptr [edx] ; get byte into al
cmp al, "\" ; at last slash?
jnz @B ; if not, loop
inc edx ; edx is now a pointer to just the filename
.endif
Its hard to fix something that works as specified. Perhaps you could show us what you were pointing at the procedure. Here is a working example of how to use the procedure acording to its documentation.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
.code
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
call main
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
LOCAL pbuf :DWORD
LOCAL rslt :DWORD
LOCAL buffer[260]:BYTE
LOCAL result[260]:BYTE
mov pbuf, ptr$(buffer)
mov rslt, ptr$(result)
invoke GetModuleFileName,rv(GetModuleHandle,NULL),pbuf,260
print pbuf,13,10
invoke NameFromPath,pbuf,rslt
print rslt,13,10
ret
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
include \masm32\include\masm32rt.inc
.data
s1 db "foo\\bar",0,"0123456789",0
s2 db "AAAAAAAAAAAAAAAAAAAAAAA",0
.code
start:
invoke NameFromPath, ADDR s1, ADDR s2
print "path copied : "
print ADDR s2
print " ",13,10
print "also copied : "
print ADDR s2 + 4
print " ",13,10
invoke ExitProcess, 0
end start
NameFromPath copies twice the length it should, because of this:
sub ecx, lpPath ; length in ecx
add ecx, edx ; create exit condition <-- edx also contains length
Also, it would probably be a good idea to do something more graceful than crash in case there is no '\' in the source string (initialize edx before the first loop).
If your output buffer is the same size as your input buffer there is NO problem
with NameFromPath. I was not aware of the fact that additional data was
moved AFTER the file name and it was a problem in my application.
I wasn't intending to criticize the procedure. I'm grateful for all these masm
supplied procedures. They've helped me a lot.
Quote from: Mr EarlIf your output buffer is the same size as your input buffer there is NO problem
with NameFromPath. I was not aware of the fact that additional data was
moved AFTER the file name and it was a problem in my application.
It means it reads past the end of the input buffer, which is a problem. Also, writing past the end of what is supposed to be copied is hardly what most people would expect.
Quote from: MASM32 Library ReferenceThe buffer to receive the filename must be large enough to acept the filename. For safety reasons if dealing with both long path and file name, the buffer can be made the same length as the source buffer.
In the current version it always writes the full source strings length to the destination buffer.
Don't excuse for pointing out bugs .. excuse for making bugs :U.
Mr Earl,
Try this version, it seems to be more tamper proof than the last one that was designed for system path returns. This much, with a bug report I need to know what was pointed at it, not smart arse comments from the peanut gallery after. The general drift of fixing problem is being able to reproduce the problem.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
nfp PROTO :DWORD,:DWORD
.data
pth1 db "z:\nowhere\directory\filename.ext",0,"xxxxxxxxxxxxxxxxxxxxxxx"
;; pth1 db "not a real path",0
buf1 db 16 dup ("z")
.code
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
call main
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
invoke nfp,ADDR pth1,ADDR buf1
.if eax == 0
print ADDR buf1,13,10
.else
print "path error",13,10
.endif
ret
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
nfp proc src:DWORD,dst:DWORD
push esi
push edi
mov esi, src
mov ecx, esi
mov edx, -1
xor eax, eax
@@:
add edx, 1
cmp BYTE PTR [esi+edx], 0 ; test for terminator
je @F
cmp BYTE PTR [esi+edx], "\" ; test for "\"
jne @B
mov ecx, edx
jmp @B
@@:
cmp ecx, esi ; test if ECX has been modified
je error ; exit on error if it is the same
lea ecx, [ecx+esi+1] ; add ESI to ECX and increment to following character
mov edi, dst ; load destination address
mov edx, -1
@@:
add edx, 1
mov al, [ecx+edx] ; copy file name to destination
mov [edi+edx], al
test al, al ; test for written terminator
jnz @B
sub eax, eax ; return value zero on success
jmp nfpout
error:
mov eax, -1 ; invalid path no "\"
nfpout:
pop edi
pop esi
ret
nfp endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Hi Hutch,
Thank you for an excellent solution and a very quick response. :thumbu
I think that 'smart arse comments from the peanut gallery' is a little heavy handed? I think they were just trying to help you.
Paul