Search code examples
nsis

Whats this line mean? (system:call getfreediskex)


System::Call '${sysGetDiskFreeSpaceEx}(r0,.,,.r1)'

If i'm right, r0: directoryname, free bytes, number of bytes, number oof free bytes, but what actually means the r0,.,.,r1? Thx for the help!


Solution

  • ${...} is a define so when you want to know how some things work then the first thing you should do is to find out what the define does: !error "${sysGetDiskFreeSpaceEx}" will print !error: kernel32::GetDiskFreeSpaceEx(t, *l, *l, *l) i

    In the System readme you will find this nugget:

    PARAMS, RETURN and OPTIONS can be repeated many times in one Get/Call line. When repeating, a lot can be omitted, and only what you wish to change can be used. Type, source and/or destination can be omitted for each parameter, even the return value. Options can be added or removed. This allows you to define function prototypes and save on some typing.

    So ${sysGetDiskFreeSpaceEx} is a prototype that specifies the parameter count and types but it does not specify parameter source and destination.

    What is the parameter syntax?

    The parameters list is separated by commas. Each parameter is combined of three values: type, source and destination. Type can be an integer, a string, etc. Source, which is the source of the parameter value, can be a NSIS register ($0, $1, $INSTDIR), the NSIS stack, a concrete value (5, "test", etc.) or nothing (null). Destination, which is the destination of the parameter value after the call returns, can be a NSIS register, the NSIS stack or nothing which means no output is required. Either one of source or destination can also be a dot (`.') if it is not needed.

    We can now expand the entire call !error 'System::Call "${sysGetDiskFreeSpaceEx}(r0,.,,.r1)"' and this gives us !error: System::Call 'kernel32::GetDiskFreeSpaceEx(t, *l, *l, *l) i(r0,.,,.r1)'

    If we merge the repeated parameter definitions we get kernel32::GetDiskFreeSpaceEx(tr0, *l., *l, *l.r1)i.

    So parameter 1 is a string (LPTSTR on MSDN) with the source r0 (NSIS register $0).

    Parameter 2 and 3 have no source and no destination, only parameter 2 uses a . (dot) but the end result is the same; no input and no output. The only important part here is *l so the system plugin knows how large the parameter is.

    The final parameter is a pointer (*) to a 64 bit number (l) with no input (.) and we request the output to be stored in $1 (r1).

    The system plugin calls the native Windows API so it is often useful to look at MSDN to see what it has to say about the function you are calling.