News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

GetFileName

Started by Vortex, December 06, 2006, 07:40:50 PM

Previous topic - Next topic

Vortex

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]

PBrennick

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
The GeneSys Project is available from:
The Repository or My crappy website

Vortex

Hi Paul,

I am glad that you liked my routines.

Vortex

I modified the algo to remove some unnecessary instructions, new upload at the top.

Synfire

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

Vortex

Synfire,

Your code works fine, thanks. I derived my version of GetFileName from my GetFilePath routine.

Grincheux

Kenavo

Grincheux
_____________________________________________________
http://www.phrio.biz

Ehtyar

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.

Grincheux

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.
Kenavo

Grincheux
_____________________________________________________
http://www.phrio.biz

sinsi

What about a file/path name like "c:myfile.txt"? Shouldn't we also search for the drive colon?
Light travels faster than sound, that's why some people seem bright until you hear them.

Grincheux

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
Kenavo

Grincheux
_____________________________________________________
http://www.phrio.biz

Grincheux

I made a big error. Replace

   SUB eax,1
   JNZ @Next

by

   SUB eax,1
   JMP @Next

Kenavo

Grincheux
_____________________________________________________
http://www.phrio.biz

sinsi


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
Light travels faster than sound, that's why some people seem bright until you hear them.

Grincheux

Now it seems to be OK !
Kenavo

Grincheux
_____________________________________________________
http://www.phrio.biz

PBrennick

Very nice and complete.
Paul
The GeneSys Project is available from:
The Repository or My crappy website