Archive: System plugin and passing parameters to dll


System plugin and passing parameters to dll
Hello.

I've got problem with passing parameters to DLL.
I need to pass something like char** (just like parameters table in regular c++), but after some tries I've given up.
I'm sure that this is not correct way:

  System::Call '*(t R3) i.R2'
System::Call '*(i R2) i.R1'
System::Call 'advapi32::StartServiceA(i r5, i $R4, i $R1) i.r6 ? e'
System::Free $R1
System::Free $R2
Pop $0 ; error code

In StartServiceA:
$R1 should be a pointer to table of pointers to null-terminated strings.
$R4 should contain number of strings.

How can I make structure like this and how can I count $R4 value (assuming I have only regular string with spaces in $R7)?

And another question. Option '? e' pops an error code to stack. Is the order of 'Pop' and 'Free' important (in other words: does '::Call*(...)' and '? e' use the same stack)?

Thanks,

Maybe this way:

  System::Call '*(t R3, n) i.R1'
System::Call 'advapi32::StartServiceA(i r5, i $R4, i $R1) i.r6 ? e'
System::Free $R1
$R3 contains first (and only one in this example) parameter.
$R4 = 1

If there will be more parameters, this will looks like:
  System::Call '*(t R3, R6, R7, R8, n) i.R1'
Am I wrong?

I've tried to start notepad as a service (successful), but the parameter is ignored. The idea was to run notepad with filename :
  c:\windows\system32\notepad.exe c:\test.txt

The notepad is starting just fine, but the file isn't opening (the parameter isn't recognized).

Any ideas?

Almost. You need to use specify a type for each member of the structure. Use `t` before R6, R7 and R8. There's also no need for that last `n`.

  System::Call '*(t R3, t R6, t R7, t R8) i.R1'
The order of System::Free and Pop is not important, even though they use the same stack. System::Free only pops on item from the stack, so it won't pop the error.

Thanks for help :)

And what about creating tables of structures?
For example I want to create structure like this:

typedef struct {
int a;
char t[10];
__int64 b;
double x;
char *p;
} myStruct;

Is the only way to do that this way (just 2-elements array):
System::Call '*(i 1, t&10 "asdfb", l 100, ???, t* n, i 7, t&10 "qwerty", l 1991, ???, t* r2) i.r1'

And what about float numbers?

I've successfully used this method to pass address of int[][] to dll, but is there any simplier method?

2 weeks isn't enough to fully explore NSIS' capabilities... ;)

Thanks again,

2 weeks isn't enough to fully explore NSIS' capabilities...
believe me: 2 years aren't either :D

It depends if you're defining an array of structs or struct pointers. If those are pointers, allocate each structure using the same method you allocate the array and allocate the array with all of the pointers. If it's just an array, the method you've shown should work. Just don't forget to mind alignments.

Probably the easiest method of seeing where everything should be placed is writing a simple C program that'd print the offsets of every member.


OK, and how can I System::Call with float parameter, please?


You can't. It doesn't support floats. The Math plug-in, however, has support for floats.


So there is no way how to System::Call my DLL exported 'float func(float x)' without writing some "wrapper"?


That's correct.


Sad but true. And why can't System plugin convert from string to float and pass it to function?


Because it doesn't that functionality built-in. Floats are a pin to handle.