News:

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

filename from path

Started by zemtex, April 24, 2012, 07:29:57 PM

Previous topic - Next topic

zemtex

I think I recall an API function for extracting filename from path, i'm not quite sure, I do think it exist.

I guess I could make my own routine to extract filename by searching from the end of the path and backwards until I find a '\' character. But the problem is that it is not reliable, you could encounter a case where the path is "c:file.ext" and that would be very bad indeed, a backslash is not a given. A solution to this could be to scan backwards as long as there are letters and not special characters, as soon as I encounter a special that would be the beginning of the filename.

But I want to avvoid all of this and just ask you people if there is a function for this in the masm32 library or any other libraries?
I have been puzzling with lego bricks all my life. I know how to do this. When Peter, at age 6 is competing with me, I find it extremely neccessary to show him that I can puzzle bricks better than him, because he is so damn talented that all that is called rational has gone haywire.

dedndave

not sure if there is an API function for this
but, you almost have it written   :P

start at the end of the string and work toward the beginning
if you encounter a backslash, slash, or colon, the previous character is the beginning of the filename
if you get to the beginning of the string, without encountering one of those, it is the beginning of the filename

the forward slash is not likely, but makes the routine compatible with devices, volumes, registry entries, or even URL's i guess
the colon is not likely, either
as far as i know, API functions that return a fully qualified path, always insert a backslash afer the colon
but - it again makes the routine compatible with user-entered paths, etc, that may not

zemtex

I could implement a safety mechanism, as soon as I have split the path and filename. I could check if the path exist, if it doesnt then I have splitted it badly.
I have been puzzling with lego bricks all my life. I know how to do this. When Peter, at age 6 is competing with me, I find it extremely neccessary to show him that I can puzzle bricks better than him, because he is so damn talented that all that is called rational has gone haywire.

dedndave

probably not a problem, but...
for that matter - check to see if the file exists - that verifies the path for you

hutch--

 :bg

There are times when I wonder why I write help files. MASM32 Library reference.


Path Functions


GetAppPath
NameFromPath
GetPathOnly
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

zemtex

Thanks that was exactly what I had in mind.  :U
I have been puzzling with lego bricks all my life. I know how to do this. When Peter, at age 6 is competing with me, I find it extremely neccessary to show him that I can puzzle bricks better than him, because he is so damn talented that all that is called rational has gone haywire.

sinsi

shlwapi has a lot of path functions, ones like PathFindFileName
Light travels faster than sound, that's why some people seem bright until you hear them.

jj2007

Quote from: sinsi on April 25, 2012, 05:58:30 AM
shlwapi has a lot of path functions, ones like PathFindFileName

OUTPUT:
==========
Search for the file in path        c:\path\file
Returns the file part of the path "file"

Search for the file in path       "c:\path"
Returns the file part of the path "path"

Search for the file in path       "c:\path\"
Returns the file part of the path "path\"

Search for the file in path       "c:\"
Returns the file part of the path "c:\"

Search for the file in path       "c:"
Returns the file part of the path "c:"

Search for the file in path       "path"
Returns the file part of the path "path"

Looks messy, but you can get Unicode mess, too  ::)

xandaz

    Zem.... maybe you should write your own.

lea esi,szPathFileName
cld
align_to_eos:
lodsb
or al,al
jnz align_to_eos
align_to_filename:
lodsb
cmp al,'\'
jne align_to_filename
inc esi
mov eax,esi
ret

i think this may work but should be tested

dedndave

i would think these should return NULL (i.e. a pointer to the null terminator at the end of the source string)

Search for the file in path       "c:\path\"
Returns the file part of the path "path\"

Search for the file in path       "c:\"
Returns the file part of the path "c:\"

Search for the file in path       "c:"
Returns the file part of the path "c:"

the other results are as expected

fearless

I have a couple functions that i use that might be what your looking for: JustFname and JustFnameExt, first one returns filename without extension, second one returns filename and extension - both strips out the path parts. Seems to work ok, havent verified for every eventuality. Pass in szFilePathName as the full path of file, and pass a buffer into szFileName

.data
szMyFilesFullPath db "c:\program files\common\somefile.ext",0
szFileNameBuffer db MAX_PATH dup 0
.code
Invoke JustFname, Addr szMyFilesFullPath, Addr szFileNameBuffer ; szFileNameBuffer should contain 'somefile'
Invoke JustFnameExt, Addr szMyFilesFullPath, Addr szFileNameBuffer ; szFileNameBuffer should contain 'somefile.ext'


.486                      ; force 32 bit code
.model flat, stdcall      ; memory model & calling convention
option casemap :none      ; case sensitive
include windows.inc
include kernel32.inc
includelib kernel32.lib
include masm32.inc
includelib masm32.lib

.code

;**************************************************************************
; Strip path name to just filename Without extention
;**************************************************************************
JustFname PROC szFilePathName:DWORD, szFileName:DWORD
LOCAL LenFilePathName:DWORD
LOCAL nPosition:DWORD

Invoke szLen, szFilePathName
mov LenFilePathName, eax
mov nPosition, eax

.IF LenFilePathName == 0
mov byte ptr [edi], 0
ret
.endif

mov esi, szFilePathName
add esi, eax

mov eax, nPosition
.WHILE eax != 0
movzx eax, byte ptr [esi]
.IF al == '\' || al == ':' || al == '/'
inc esi
.BREAK
.endif
dec esi
dec nPosition
mov eax, nPosition
.ENDW
mov edi, szFileName
mov eax, nPosition
.WHILE eax != LenFilePathName
movzx eax, byte ptr [esi]
.IF al == '.' ; found our full stop - so stop here
    mov byte ptr [edi], 0h
    .BREAK
.endif
mov byte ptr [edi], al
inc edi
inc esi
inc nPosition
mov eax, nPosition
.ENDW
ret
JustFname ENDP

end


.486                      ; force 32 bit code
.model flat, stdcall      ; memory model & calling convention
option casemap :none      ; case sensitive
include windows.inc
include kernel32.inc
includelib kernel32.lib
include masm32.inc
includelib masm32.lib

.code

;**************************************************************************
; Strip path name to just filename with extention
;**************************************************************************
JustFnameExt PROC szFilePathName:DWORD, szFileName:DWORD
LOCAL LenFilePathName:DWORD
LOCAL nPosition:DWORD

Invoke szLen, szFilePathName
mov LenFilePathName, eax
mov nPosition, eax

.IF LenFilePathName == 0
mov byte ptr [edi], 0
ret
.endif

mov esi, szFilePathName
add esi, eax

mov eax, nPosition
.WHILE eax != 0
movzx eax, byte ptr [esi]
.IF al == '\' || al == ':' || al == '/'
inc esi
.BREAK
.endif
dec esi
dec nPosition
mov eax, nPosition
.ENDW
mov edi, szFileName
mov eax, nPosition
.WHILE eax != LenFilePathName
movzx eax, byte ptr [esi]
mov byte ptr [edi], al
inc edi
inc esi
inc nPosition
mov eax, nPosition
.ENDW
mov byte ptr [edi], 0h ; null out filename
ret
JustFnameExt ENDP


end
ƒearless

zemtex

Quote from: xandaz on April 25, 2012, 10:04:33 PM
    Zem.... maybe you should write your own.

lea esi,szPathFileName
cld
align_to_eos:
lodsb
or al,al
jnz align_to_eos
align_to_filename:
lodsb
cmp al,'\'
jne align_to_filename
inc esi
mov eax,esi
ret

i think this may work but should be tested


Yes  :P

I have written routines like this before, I always find myself in need of this type of function again, even though I have written it in the past, I've forgotten where I put it and what language it was.
I ended up using masm32 library call "NameFromPath". The only thing I couldn't find in the masm32 library was a function to retrieve file type extension "exe" for example.

It can be achieved with a few instruction though:

cld
lea edi, szFileName
mov ecx, MAX_PATH
mov eax, 2Eh
repne scasb
mov eax, edi

eax now points to the first character in the file extension. Assuming it doesn't have double extensions.
I have been puzzling with lego bricks all my life. I know how to do this. When Peter, at age 6 is competing with me, I find it extremely neccessary to show him that I can puzzle bricks better than him, because he is so damn talented that all that is called rational has gone haywire.

dedndave

again - you should start from the end of the string
periods are allowed in folder names, as well

zemtex

Like I said, it's not entirely safe, but fast. ( I didn't say you ought to start from the beginning of the string in my first post, you must have misread something )

Here is a safer way:

cld
lea edi, szFileName
mov ecx, MAX_PATH
mov eax, 2Eh
repne scasb
mov eax, [edi]
and eax, 0FF000000h
jz match
; IF YOU REACH THIS POINT, PERFORM A ROBUST EXTRACTION OF FILE EXTENSION METHOD FROM THIS POINT (slower), but chances are you will succeed in 99% of cases without reaching this place

match:
edi now points to file extension
I have been puzzling with lego bricks all my life. I know how to do this. When Peter, at age 6 is competing with me, I find it extremely neccessary to show him that I can puzzle bricks better than him, because he is so damn talented that all that is called rational has gone haywire.

hutch--

Most of you path API functions return the length of the string so you just add it to the start offset to get the end, then scan backwards to get either the "\", "." or the start of the string if neither are present.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php