News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Calculate lenght of a part from a path name

Started by Yoshi, November 25, 2013, 02:15:32 AM

Previous topic - Next topic

Yoshi

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"

dedndave

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

qWord

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
MREAL macros - when you need floating point arithmetic while assembling!

Yoshi

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

qWord

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.
MREAL macros - when you need floating point arithmetic while assembling!

Yoshi


dedndave

however you do it, you want to account for "unusual" cases, for example:
'\\x\y\\\z\\\\',0

Yoshi

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.

dedndave

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
why not use it ?

Yoshi

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.

dedndave

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

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 ?

Yoshi

i send you a pm for the reason i cant use that api.

however a work around will be very difficult i guess

jj2007


Adamanteus

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;
};