Here is my GetFileName function to retrieve filename from a complete path.
.386
.model flat,stdcall
option casemap:none
.code
GetFileName PROC source:DWORD,dest:DWORD
mov edx,source
mov ecx,edx
dec edx
dec ecx
@@:
add edx,1
mov al,BYTE PTR [edx]
test al,al
jz @f
cmp al,'\'
jne @b
mov ecx,edx
jmp @b
@@:
mov edx,dest
dec edx
@@:
add edx,1
add ecx,1
mov al,BYTE PTR [ecx]
mov BYTE PTR [edx],al
test al,al
jnz @b
ret
GetFileName ENDP
END
[attachment deleted by admin]
Vortex,
Thanx, first GetFilePath, now GetFileName; next is GetMillionDollars, right? Should be easy for you! :U
Seriously, these two functions will be very helpful.
Paul
Hi Paul,
I am glad that you liked my routines.
I modified the algo to remove some unnecessary instructions, new upload at the top.
Vortex,
Just a thought, I'm sure you have your reasons.. but why didn't you just scan through till you reach the null terminator, then go backwards till you reach the first \ character, checking if you reach the start of the string for when there is no path, and copying the contents from that point into the destination memory. Maybe something like:
.386
.model flat,stdcall
option casemap:none
INCLUDE \GeneSys\INCLUDE\GeneSys.INC
INCLUDELIB \GeneSys\LIB\GeneSys.LIB
.code
GetFileName PROC src:DWORD, dst:DWORD
mov ESI, src
; Scan to NULL terminator
@@: inc ESI
mov AL, BYTE PTR [ESI]
test EAX, EAX
jnz @B
mov AL, '\'
mov EDI, src
; Scan backwards to first '\'
@@: dec ESI
cmp ESI, EDI ; Reached beginning of string?
jz @F
mov AH, BYTE PTR [ESI]
cmp AL, AH
jnz @B
; Go to character after last '\' in filename
inc ESI
; Copy string into dst memory
@@: INVOKE StrCpy, dst, ESI
ret
GetFileName ENDP
I've not tried to optimize it, or even test it. But you get what I'm saying I'm sure :)
Just being inquisitive,
Bryant Keller
Synfire,
Your code works fine, thanks. I derived my version of GetFileName from my GetFilePath routine.
There also is PathFindFileNam. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/shlwapi/path/pathfileexists.asp
This one is by WhiteScorpion, makes the most sense to me...
GetFileName PROC lpszFilename:LPSTR
invoke lstrlen, lpszFilename
mov ecx, eax
mov eax, lpszFilename
add eax, ecx
next:
cmp byte ptr [eax],5Ch
jz contin
dec eax
jmp next
contin:
inc eax
ret
GetFileName ENDP
(Offset to file name in eax)
Ehtyar.
Be sure that the lpszFilename is not NULL
Just after "lstrlen" you have to test if the file length is less or equal than MAX_PATH.
If there is no ' \' just a file name without path.
And if the filename string is empty.
GetFileName PROC USES EDI,lpszFilename:LPSTR
mov eax,lpszFilename
test eax,eax
jz @Exit
mov edi,eax
INVOKE lstrlen, eax
test eax,eax
jz @Exit ; The filename is empty
cmp eax,MAX_PATH
jg @Error
mov ecx, eax
mov eax, lpszFilename
add eax, ecx
@Next :
cmp eax,edi
jl @Continue
cmp byte ptr [eax],5Ch
jz @Continue
dec eax
jmp @Next
@Continue :
inc eax
jmp @Exit
@Error :
xor eax,eax
@Exit :
ret
GetFileName ENDP
Now I think it is complete.
What about a file/path name like "c:myfile.txt"? Shouldn't we also search for the drive colon?
If that could append, I think it is to do. You have to search it, suppose someone using a network. That syntax will be very often used.
I suggest :
GetFileName PROC USES EBX EDI,lpszFilename:LPSTR
mov eax,lpszFilename
test eax,eax
jz @Exit
mov edi,eax
INVOKE lstrlen, eax
test eax,eax
jz @Exit ; The filename is empty
cmp eax,MAX_PATH
jg @Error
mov ecx, eax
MOV EBX,':\'
MOV EAX, EDI
add eax, ecx
@Next :
MOV DL,Byte Ptr [EAX]
cmp eax,edi
jl @Continue
CMP DL,BH
JE @Continue
CMP DL,BL
JE @Continue
SUB eax,1
JNZ @Next
@Continue :
ADD EAX,1
jmp @Exit
@Error :
xor eax,eax
@Exit :
ret
GetFileName ENDP
I made a big error. Replace
SUB eax,1
JNZ @Next
by
SUB eax,1
JMP @Next
GetFileName proc uses edi lpszFilename:dword
mov eax,lpszFilename
mov edi,eax
test eax,eax
jz done
INVOKE lstrlen,eax
test eax,eax
jz done
lea ecx,[eax+edi]
next: cmp ecx,edi
jb son
mov al,[ecx]
cmp al,'\'
jz son
cmp al,':'
jz son
sub ecx,1
jmp next
son: lea eax,[ecx+1]
done: ret
GetFileName endp
Now it seems to be OK !
Very nice and complete.
Paul
Just a question, what does it become now of this function ?
Do you think I should add it to the library? It certainly is useful! Good work should not be allowed to go to waste.
Paul
Oh Yes !
I don't know very well your project. I often have seen messages about it but I never tooke enougth time to see what it is. I would like to give my contributions to this project.
Thanks
Grincheux,
The project is still in its infancy but it works very well. I credit all contributions to the project. How would you like me to credit this? Shall I use Grincheux? Or an honorific?
I will also credit sinsi as he did some work on the algo, also.
By the way, like you, I am never satisfied. That is what it says below my user name.
Paul
Grincheux,
How does this look?
;------------------------------------------------------------;
; This algorythm was developed by Grincheux with help from ;
; sinsi. Grincheux has given permission to use this module ;
; to the users of The GeneSys Development System and is for ;
; educational or personal use only. Users are not allowed to ;
; use this module in commercial software. To use this module ;
; for any for profit purpose, the author must be contacted. ;
;------------------------------------------------------------;
GetFileName proc uses edi lpszFilename:dword
;---------------------------------------
mov eax, lpszFilename
mov edi, eax
test eax, eax
jz done
invoke lstrlen, eax
test eax, eax
jz done
lea ecx, [eax+edi]
next:
cmp ecx, edi
jb son
mov al, [ecx]
cmp al, '\'
jz son
cmp al, ':'
jz son
sub ecx, 1
jmp next
son:
lea eax, [ecx+1]
done:
ret
;---------------------------------------
GetFileName endp
Paul
[attachment deleted by admin]
Grincheux,
We would be pleased for any effort. Please feel free to contribute our project, you are always welcomed to contibute.