The MASM Forum

General => The Workshop => Topic started by: Yoshi on November 25, 2013, 02:15:32 AM

Title: Calculate lenght of a part from a path name
Post by: Yoshi on November 25, 2013, 02:15:32 AM
hi masm forum

I got the following question. How do i calculate the lenght of bytes between a "\" (0x5C) of a path.

So in example, i need to know the lenght of each colored string.

pathname db "C:\Users\Name\Desktop\example.exe"
Title: Re: Calculate lenght of a part from a path name
Post by: dedndave on November 25, 2013, 02:59:04 AM
i guess you'd want a routine that filled a structure with element lengths
you could write it so, if you call the routine with a null structure, it returns the size of the required structure
same if the structure passed is too small

if the passed structure is large enough, return -1 in EAX, and fill the structure (or array)

you could just fill it with length dword's, or length and offset dword pairs
Title: Re: Calculate lenght of a part from a path name
Post by: qWord on November 25, 2013, 03:10:25 AM
you need to parse the string whereas the result could be stored in the stack (to avoid two parsing passes).
e.g. similar to this one:
include \masm32\include\masm32rt.inc
.const
    sz db "C:\Users\Name\Desktop\example.exe",0
.code
main proc
LOCAL n:DWORD
    lea esi,sz
    ; skip all char. before the first '\'
    .while 1
        movzx eax,TCHAR ptr [esi]
        .break .if !eax || eax == '\'
        add esi,TCHAR
    .endw
    .if eax
        add esi,TCHAR
        xor edi,edi
        .while 1
            xor ecx,ecx
            .while 1
                movzx eax,TCHAR ptr [esi+ecx*TCHAR]
                .break .if !eax || eax == '\'
                add ecx,1
            .endw
            push esi
            push ecx
            add edi,1
            lea esi,[esi+ecx*TCHAR+TCHAR]
            .break .if !eax
        .endw
        ;... result on stack (reversed order), EDI = N
       
        mov ebx,rv(GetStdHandle,STD_OUTPUT_HANDLE)
        mov esi,edi
        .while esi
            fn crt_printf,"%.3i:",DWORD ptr [esp+esi*8-8]
            mov ecx,DWORD ptr [esp+esi*8-8]
            mov edx,DWORD ptr [esp+esi*8-8][4]
            fn WriteFile,ebx,edx,ecx,ADDR n,0
            print chr$(13,10)
            sub esi,1
        .endw
        ;...
       
        lea esp,[esp+edi*8]
    .else
        ; error?
    .endif
    inkey
    exit
main endp
end main
Title: Re: Calculate lenght of a part from a path name
Post by: Yoshi on November 25, 2013, 03:29:05 AM
thanks both for a reply :)

also thanks both for the information. But i am sorry, i was not so clear what i whant to do. I want to check for the lenght of each string of the constant string path.

see this example:

sz db "C:\Users\Name\Desktop\example.exe",0

calc lengt of only "Users"  -> 5 bytes
calc lenght of only "Name" -> 4 bytes
calc lenght of only "Desktop" -> 7 bytes
calc lenght of only "example.exe" -> 11 bytes
Title: Re: Calculate lenght of a part from a path name
Post by: qWord on November 25, 2013, 03:49:31 AM
Quote from: Yoshi on November 25, 2013, 03:29:05 AMsee this example:

sz db "C:\Users\Name\Desktop\example.exe",0

calc lengt of only "Users"  -> 5 bytes
calc lenght of only "Name" -> 4 bytes
calc lenght of only "Desktop" -> 7 bytes
calc lenght of only "example.exe" -> 11 bytes
--> see above code.
Title: Re: Calculate lenght of a part from a path name
Post by: Yoshi on November 25, 2013, 03:57:08 AM
please wait, gonna test and edit this post
Title: Re: Calculate lenght of a part from a path name
Post by: dedndave on November 25, 2013, 04:37:55 AM
however you do it, you want to account for "unusual" cases, for example:
'\\x\y\\\z\\\\',0
Title: Re: Calculate lenght of a part from a path name
Post by: Yoshi on November 25, 2013, 04:42:13 AM
well atually i am a bit playing with qWord's his source. So far all working  so that is good :)

so i am still playing/ try to modify the source. Because my actually goal is to check if each part is > 8 chars long, if not then copy to buffer else add a "~" to it.
In other words, i try to recode the API GetShortPathName. but till now i got no luck to recode it.
Title: Re: Calculate lenght of a part from a path name
Post by: dedndave on November 25, 2013, 04:50:57 AM
1) trying to recreate what the OS does when it creates short names is not very likely
it assigns numbers to repeat strings
you would have a hard time recreating the same algorithm used to assign the numbers
and, thus, your numbers may not match the ones assigned by the OS

if you have 2 folders, C:\My Folder1 and C:\My Folder2
"C:\My Folder1" may be shortened to "C:\MYFOLD~1" or "C:\MYFOLD~2"
you have no good way to match the OS assignment

furthermore, if you delete C:\My Folder2, the assignment made by the OS for C:\My Folder1
may or may not have already been made
it may be "C:\MYFOLD~2", even though there is no longer a "C:\MYFOLD~1" folder

2) there is an API function to do it for you - GetShortPathName
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364989%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364989%28v=vs.85%29.aspx)
why not use it ?
Title: Re: Calculate lenght of a part from a path name
Post by: Yoshi on November 25, 2013, 05:11:10 AM
for a specific reason i cant use that api so i need to recode it manually.

also i thought GetShortNamePath is only checking if a part of the path-name is >8 in lenght, if true then assign a '~' and a number to it.
Title: Re: Calculate lenght of a part from a path name
Post by: dedndave on November 25, 2013, 05:26:14 AM
you might want to read up on how NTFS partitions store shortened names...

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx#short_vs._long_names (http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx#short_vs._long_names)

if you can't use the API function - try to find a work-around so you can
that's what you should be addressing in here...
what is the problem with using the API ?
Title: Re: Calculate lenght of a part from a path name
Post by: Yoshi on November 25, 2013, 05:40:25 AM
i send you a pm for the reason i cant use that api.

however a work around will be very difficult i guess
Title: Re: Calculate lenght of a part from a path name
Post by: jj2007 on November 25, 2013, 05:44:32 AM
Quote from: dedndave on November 25, 2013, 05:26:14 AM
what is the problem with using the API ?

Not part of Kernel32, of course...
Title: Re: Calculate lenght of a part from a path name
Post by: Adamanteus on November 25, 2013, 06:47:53 AM
For parsing paths, possible use function (that's on C++), that returns part of path by index, if it is (so task will simplyfy) :
Code (c) Select
bool fnpart (const char* path, char* part, short index) {
char* substr;
char* trail;
size_t len;
*part = '\0';
substr = (char*)path;
index--;
while (index)
{
substr = strchr(substr, '\\');
if ( ! substr) return false;
substr++;
index--;
};
if (trail = strchr(substr, '\\')) len = trail - substr;
else len = strlen(substr);
strncpy(part, substr, len);
return len ? true : false;
};

Title: Re: Calculate lenght of a part from a path name
Post by: Yoshi on November 25, 2013, 07:00:13 AM
Thank you all guys  :t
Title: Re: Calculate lenght of a part from a path name
Post by: MichaelW on November 25, 2013, 03:21:31 PM
You could use the CRT strtok function, specifying chr$("\",13,10) for the delimiters, then simply get the length of each of the returned tokens.
Title: Re: Calculate lenght of a part from a path name
Post by: Yoshi on November 25, 2013, 06:13:08 PM
Thanks gonna try it.  :t