News:

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

Main Menu

Calling invoke 2 times

Started by Shintaro, August 17, 2014, 09:43:56 PM

Previous topic - Next topic

Shintaro

Hi,

When I call the following invoke's, one straight after the other, the different strings (szDeskTop and szAddDataDir)  end up with the same contents.

szDeskTop LPWSTR ?
szAppDataDir LPWSTR ?

      invoke SHGetFolderPath,0,CSIDL_DESKTOP,0,0,ADDR szDeskTop

      invoke SHGetFolderPath,0,CSIDL_APPDATA,0,0,ADDR szAppDataDir

Am I meant to reset or clear something between invoke calls?

Regards.
"Wyrd bið ful āræd. Fate is inexorable."

qWord

You are passing the address of a pointer-variable, but the function expect the address of a char. buffer. (length=MAX_PATH)
MREAL macros - when you need floating point arithmetic while assembling!

Shintaro

Thank you for your help.

Is the following:
szDeskTop db dup 260 (0)

the same as
sz[MAX_PATH]:CHAR

Or is there some bounds checking in MAX_PATH?

So how do I determine if the string of chars being returned from the API call is greater than 260?

Regards.
"Wyrd bið ful āræd. Fate is inexorable."

dedndave

szDeskTop db dup 260 (0)
incorrect syntax - and you can put it in the .DATA? section, if you use...
szDeskTop db 260 dup(?)
or
szDeskTop db MAX_PATH dup(?)
this allocates space in the uninitialized data section
it is "valid" for the lifetime of the process

sz[MAX_PATH]:CHAR
again, incorrect syntax
    LOCAL szDeskTop[MAX_PATH]:CHAR
this allocates space inside a PROC, on the stack
it is only valid for the life of the call

when working with pathnames, i find it's better to use the UNICODE version of the function
it's a little bit of a headache, as many functions require it to be prepended with "\\?\"
but, the length limit is extended to 32768 TCHAR's (64 KB)
and, it will handle non-ascii characters   :t
i would then use either a heap allocated or a stack allocated buffer (after probing the stack)

Shintaro

Thanks for that.

I thought that

.data
szDeskTop db dup 260 (0)


meant that the 260 bytes would be allocated at compile time (making the binary bigger) and that the whole 260 bytes would contain 0 (zero's). I remember a class in C telling me to initialize variables/types etc with known values and not leave them in an unknown state.


So in C I would use something like SizeOf() before data was moved to a variable, hence not allowing a buffer overflow. Not sure how I accomplish that in Asm.

I would appreciate it if you could point me to any relevant doc.
I don't think Iczelions docs are enough. Is there example code in the masm directory that I have overlooked?

I appreciate your help.

Kind regards.
"Wyrd bið ful āræd. Fate is inexorable."

qWord

Quote from: aparsons on August 22, 2014, 01:17:30 AMI remember a class in C telling me to initialize variables/types etc with known values and not leave them in an unknown state.
This applies to local variables (on stack). Variables in the .data?-segment (BSS) are zero initialized and are not allowed to have any other initial value. If none-zero values are required, use .data or .const.

Quote from: aparsons on August 22, 2014, 01:17:30 AMSo in C I would use something like SizeOf() before data was moved to a variable, hence not allowing a buffer overflow.
It is a good sign that worry about that, but in this case it is that the function SHGetFolderPath does not -- by definition -- write more than MAX_PATH characters to the buffer (otherwise it will fail --> eax != S_OK).
MREAL macros - when you need floating point arithmetic while assembling!

Grincheux

An other version of

Quote
szDeskTop LPWSTR ?
szAppDataDir LPWSTR ?
      invoke SHGetFolderPath,0,CSIDL_DESKTOP,0,0,ADDR szDeskTop
      invoke SHGetFolderPath,0,CSIDL_APPDATA,0,0,ADDR szAppDataDir

could be :

Quote
             push OFSFET szAppDataDir
             push 0
             push 0
             push CSIDL_APPDATA
             push 0
             push OFFSET @NextAddr
             push OFFSET szDesktop
             push 0
             push 0
             push CSIDL_DESKTOP
             push 0
             push OFFSET ShGetFolderPath
             jmp ShGetFolderPath


@NextAddr :
No time spend for coming back to your code and then make an other call!
Shorter than 2 calls.

If szDesktop was local, replace :

Quote
             push OFFSET szDesktop
by :
Quote
             lea eax,szDesktop
             push eax

This is for the 32 bit version.
In 64 bits after the first call is made, don't correct the stack.
just modify "ADDR szAppDataDir" by "szDesktop"
then issue the call without passing the other parameters.
This is good if RCX, RDX, R8 and R9 are not modified.
After you correct the stack

I used this technique for creating children windows. Only in 5 lines for the second child.

guga

Hi Grincheux, did you got my msg ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

Grincheux

Yes I made the answers.
And in my answers I was speaking about this post.

qWord

This thread is 1 year old!

Quote from: Grincheux on December 24, 2015, 06:21:26 AM
[...]
This is for the 32 bit version.
In 64 bits after the first call is made, don't correct the stack.
just modify "ADDR szAppDataDir" by "szDesktop"
then issue the call without passing the other parameters.
This is good if RCX, RDX, R8 and R9 are not modified.
After you correct the stack

I used this technique for creating children windows. Only in 5 lines for the second child.
Buggy technique, because called functions can modify parameters on stack.
MREAL macros - when you need floating point arithmetic while assembling!

Grincheux

If it was 5 five years old I made my post, the time is not a problem.
Does it mean that after one year it is forbidden to read/answer to a post?