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"
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
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
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
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.
please wait, gonna test and edit this post
however you do it, you want to account for "unusual" cases, for example:
'\\x\y\\\z\\\\',0
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.
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 ?
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.
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 ?
i send you a pm for the reason i cant use that api.
however a work around will be very difficult i guess
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...
For parsing paths, possible use function (that's on C++), that returns part of path by index, if it is (so task will simplyfy) :
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;
};
Thank you all guys :t
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.
Thanks gonna try it. :t