NSIS-RunAs

From NSIS Wiki
Jump to navigationJump to search

This is NSIS-RunAs, a dll to help NSIS installer scripts manage administrator permissions on the processes it launches.

Download

NSIS-RunAs.zip (13 KB)

About NSIS-RunAs

Sometimes, certain installers require administator privileges to be able to perform certain actions. For example to modify the registry or to install files in protected areas of the filesystem. Those installers will either tell you that you need to restart them as an administrator, or they will suggest you to enter an appropriate username/password combination. This is what NSIS-RunAs is meant to help you do.

The dll contains two functions: RunAsW and GetAdministrators. By creating approriate dialogs with, for example, the InstallOptions plugin, you could create a login page that will lead the installer to be restarted. Here is a visual example of such a login page:

RunAs.jpg

Interface

The interface to those functions are the following:

WINAPI DWORD RunAsW (WCHAR *uusername, WCHAR *upassword, WCHAR *ucommand, WCHAR **error);
WINAPI WCHAR **GetAdministrators (LPWSTR domain, LPDWORD read);

RunAsW takes 4 arguments: the username, the password, the command to execute and a pointer to an error string. It returns 1 on success, 0 on failure. The correct invocation with the System plugin would be

  StrCpy $1 $username
  StrCpy $2 $password
  StrCpy $3 $command
  StrCpy $4 0
  System::Call 'RunAs::RunAsW(w r1, w r2, w r3, *w .r4) i .r0 ? u'
  IntCmp $0 1 success
  [failure code]
success:
  [success code]

GetAdministrators is a bit more tricky to handle, since it will return an array of wide-char pointers. Its arguments are the domain to query (leave it to "" for the local machine) and a pointer to an integer that will receive the number of user-accounts returned in the array. The invocation of GetAdministrators would look like:

  StrCpy $0 0
  StrCpy $1 ""
  StrCpy $2 0
  StrCpy $3 0
  System::Call 'RunAs::GetAdministrators(w r1, *i .r0) i .r2 ? u'
  StrCpy $4 $2
loop:
  IntCmp $0 0 endloop
  System::Call '*$2(w .r3)'
  [code to handle the username in $3]
  System::Free $3   ; we free the memory used by the string
  IntOp $2 $2 + 4   ; pointers have a size of 4 on 32 bit machines
  IntOp $0 $0 - 1
  Goto Loop
endloop:
  System::Free $4   ; we free the memory used by the array

Bugs & Limitations

NSIS-RunAs is currently very basic. Since I don't run in a domain environment, I have not implemented what is needed to query all of possible administrators for a machine and its network domain. This it only supports only one domain at a time. This should not be difficult to enhance though and contributions are welcome :-).

Besides, I am using a wprintf statement during the GetAdministrators function. I still don't understand where this comes from but it avoids NSIS to crash during the process. This problem only occurs when the declared type is "w" and it works correctly with "t" vars. So I suspect this is rather a bug with the System plugin. Now, I want to keep the "w" vars since it provides better charset independence than then "t" type so I will keep this dirty work-around for now. ("w" is for wide-char strings, such as Unicode, while "t" is for byte-char strings, such as the ones from ISO-8859-XX).

Building

I avoid using proprietary software, especially when free equivalents exists. And I also encourage you to do so. Therefore I am using the GCC compiler ported to Win32 by the mingw project. You can download the MingW SDK from http://www.mingw.org/. Basically you need the GNU make utility, GCC and the Win32 interface files.

In the case you want to use another compiling environment, I have named the makefile "GNUmakefile" to avoid incompatibilities with other make utilities. GNU make will recognize it as a regular makefile. Also, you might want to replace the "__declspec(dllexport)" directive in the function declarations with a similar directive or pragma for your environment. If you do so, please send me your changes so that I can incorporate them in my tree.

Copyright

NSIS-RunAs is copyright (c) 2006 Wolfgang Sourdeau <Wolfgang_AT_NOSPAM_Contre.COM>

The NSIS-RunAs module is distributed under the GNU General Public License. You can find a copy of this license in the file "COPYING.txt" in the Source subdirectory of the distribution or at this address: http://www.gnu.org/licenses/gpl.html. An exception applies on the resulting RunAs.dll in the case you use it along your product installer since it would only impair you and would not be specially useful to your users either. This exception is documented in the header of the file "NSIS-RunAs.c" in the Source subdirectory.