Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/admin
diff options
context:
space:
mode:
authorKlaas Freitag <freitag@owncloud.com>2012-04-02 15:44:24 +0400
committerKlaas Freitag <freitag@owncloud.com>2012-04-02 15:44:24 +0400
commit95f6f90cb5232054d723d633564e3dbdee240d47 (patch)
tree9b50860202be63b6dcde213054be0112a0ddcced /admin
parent43a9d1dcd04c1483e06dd4f77e6ced9b7c9e4586 (diff)
Add win32 packaging with nsi
Diffstat (limited to 'admin')
-rw-r--r--admin/win/docmake.sh19
-rw-r--r--admin/win/nsi/.directory3
-rw-r--r--admin/win/nsi/RELEASE_NOTES.txt0
-rw-r--r--admin/win/nsi/installer.icobin0 -> 2998 bytes
-rwxr-xr-xadmin/win/nsi/nsis_processes/bin/Processes.dllbin0 -> 36352 bytes
-rwxr-xr-xadmin/win/nsi/nsis_processes/license.rtf35
-rwxr-xr-xadmin/win/nsi/nsis_processes/readme.txt122
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/StdAfx.cpp8
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/StdAfx.h34
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/exdll.c37
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/exdll.h136
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/processes.cpp411
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/processes.h49
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/processes.ncbbin0 -> 44032 bytes
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/processes.rc103
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/processes.sln21
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/processes.txt122
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/processes.vcproj222
-rwxr-xr-xadmin/win/nsi/nsis_processes/src/resource.h15
-rwxr-xr-xadmin/win/nsi/nsis_uac/History.txt102
-rwxr-xr-xadmin/win/nsi/nsis_uac/License.txt14
-rwxr-xr-xadmin/win/nsi/nsis_uac/NSISUtil.h149
-rwxr-xr-xadmin/win/nsi/nsis_uac/Release/A/UAC.dllbin0 -> 17408 bytes
-rwxr-xr-xadmin/win/nsi/nsis_uac/Release/U/UAC.dllbin0 -> 18432 bytes
-rwxr-xr-xadmin/win/nsi/nsis_uac/RunAs.cpp277
-rwxr-xr-xadmin/win/nsi/nsis_uac/UAC Readme.html222
-rwxr-xr-xadmin/win/nsi/nsis_uac/UAC.nsh191
-rwxr-xr-xadmin/win/nsi/nsis_uac/UAC_AdminOnly.nsi62
-rwxr-xr-xadmin/win/nsi/nsis_uac/UAC_AllowLUA.nsi45
-rwxr-xr-xadmin/win/nsi/nsis_uac/UAC_GetUserShellFolderPath.nsi30
-rwxr-xr-xadmin/win/nsi/nsis_uac/UAC_RealWorldFullyLoadedDualModeExample.nsi242
-rwxr-xr-xadmin/win/nsi/nsis_uac/UAC_Uninstaller.nsi49
-rwxr-xr-xadmin/win/nsi/nsis_uac/resource.h24
-rwxr-xr-xadmin/win/nsi/nsis_uac/resource.rc109
-rwxr-xr-xadmin/win/nsi/nsis_uac/uac.cpp1518
-rwxr-xr-xadmin/win/nsi/nsis_uac/uac.h169
-rw-r--r--admin/win/nsi/page_header_oc.bmpbin0 -> 34254 bytes
-rw-r--r--admin/win/nsi/page_header_oc.xcfbin0 -> 4562 bytes
-rw-r--r--admin/win/nsi/tomahawk.ini21
-rw-r--r--admin/win/nsi/welcome_oc.bmpbin0 -> 206038 bytes
40 files changed, 4561 insertions, 0 deletions
diff --git a/admin/win/docmake.sh b/admin/win/docmake.sh
new file mode 100644
index 000000000..f11923dcc
--- /dev/null
+++ b/admin/win/docmake.sh
@@ -0,0 +1,19 @@
+# %_mingw32_qt4_platform win32-g++-cross
+
+export QT_BINDIR=/usr/bin
+export BIN_PRE=i686-w64-mingw32
+
+/usr/bin/mingw32-cmake \
+ -DCMAKE_BUILD_TYPE="Debug" \
+ -DQMAKESPEC=win32-g++-cross \
+ -DQT_MKSPECS_DIR:PATH=/usr/i686-w64-mingw32/sys-root/mingw/share/qt4/mkspecs \
+ -DQT_QT_INCLUDE_DIR=/usr/i686-w64-mingw32/sys-root/mingw/include \
+ -DQT_PLUGINS_DIR=/usr/i686-w64-mingw32/sys-root/mingw/lib/qt4/plugins \
+ -DQT_QMAKE_EXECUTABLE=${QT_BINDIR}/${BIN_PRE}-qmake \
+ -DQT_MOC_EXECUTABLE=${QT_BINDIR}/${BIN_PRE}-moc \
+ -DQT_RCC_EXECUTABLE=${QT_BINDIR}/${BIN_PRE}-rcc \
+ -DQT_UIC_EXECUTABLE=${QT_BINDIR}/${BIN_PRE}-uic \
+ -DQT_LRELEASE_EXECUTABLE=${QT_BINDIR}/${BIN_PRE}-lrelease \
+ -DQT_DBUSXML2CPP_EXECUTABLE=${QT_BINDIR}/qdbusxml2cpp \
+ -DQT_DBUSCPP2XML_EXECUTABLE=${QT_BINDIR}/qdbuscpp2xml ../../mirall
+
diff --git a/admin/win/nsi/.directory b/admin/win/nsi/.directory
new file mode 100644
index 000000000..be8d47225
--- /dev/null
+++ b/admin/win/nsi/.directory
@@ -0,0 +1,3 @@
+[Dolphin]
+PreviewsShown=true
+Timestamp=2012,4,1,13,48,38
diff --git a/admin/win/nsi/RELEASE_NOTES.txt b/admin/win/nsi/RELEASE_NOTES.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/admin/win/nsi/RELEASE_NOTES.txt
diff --git a/admin/win/nsi/installer.ico b/admin/win/nsi/installer.ico
new file mode 100644
index 000000000..94753ac29
--- /dev/null
+++ b/admin/win/nsi/installer.ico
Binary files differ
diff --git a/admin/win/nsi/nsis_processes/bin/Processes.dll b/admin/win/nsi/nsis_processes/bin/Processes.dll
new file mode 100755
index 000000000..e532bf8bb
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/bin/Processes.dll
Binary files differ
diff --git a/admin/win/nsi/nsis_processes/license.rtf b/admin/win/nsi/nsis_processes/license.rtf
new file mode 100755
index 000000000..2ce5a58c9
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/license.rtf
@@ -0,0 +1,35 @@
+{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Verdana;}
+{\f172\froman\fcharset238\fprq2 Times New Roman CE;}{\f173\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f175\froman\fcharset161\fprq2 Times New Roman Greek;}{\f176\froman\fcharset162\fprq2 Times New Roman Tur;}
+{\f177\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f178\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f179\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f180\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
+{\f562\fswiss\fcharset238\fprq2 Verdana CE;}{\f563\fswiss\fcharset204\fprq2 Verdana Cyr;}{\f565\fswiss\fcharset161\fprq2 Verdana Greek;}{\f566\fswiss\fcharset162\fprq2 Verdana Tur;}{\f569\fswiss\fcharset186\fprq2 Verdana Baltic;}
+{\f570\fswiss\fcharset163\fprq2 Verdana (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;
+\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{
+\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\*
+\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
+\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\*\cs15 \additive \ul\cf2 \sbasedon10 \styrsid7485074 Hyperlink;}}
+{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\rsidtbl \rsid6712196\rsid7485074\rsid11352300\rsid15940516}{\*\generator Microsoft Word 11.0.5604;}{\info{\title Processes v1}{\author Hardwired}{\operator Hardwired}{\creatim\yr2004\mo12\dy12\hr23\min42}
+{\revtim\yr2004\mo12\dy12\hr23\min51}{\version2}{\edmins9}{\nofpages1}{\nofwords80}{\nofchars458}{\nofcharsws537}{\vern24689}}\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180
+\dgvspace180\dghorigin1800\dgvorigin1440\dghshow1\dgvshow1
+\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
+\asianbrkrule\rsidroot7485074\newtblstyruls\nogrowautofit \fet0\sectd \linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}
+{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}
+{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain
+\qj \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid7485074 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\f39\insrsid7485074\charrsid7485074 Processes v1.0}{\f39\insrsid7485074\charrsid7485074 .0.1
+\par }{\f39\fs20\insrsid7485074
+\par }\pard \qj \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid15940516 {\f39\fs20\insrsid15940516 This software binaries and source-code are free for any kind of use, including commercial use. }{
+\f39\fs20\insrsid7485074\charrsid7485074 There is no restriction and no guaranty for using}{\f39\fs20\insrsid7485074\charrsid7485074 t}{\f39\fs20\insrsid7485074\charrsid7485074 his software}{\f39\fs20\insrsid7485074\charrsid7485074 and/or it
+s source-code. }{\f39\fs20\insrsid15940516
+\par I}{\f39\fs20\insrsid7485074\charrsid7485074 f you use the plug}{\f39\fs20\insrsid7485074\charrsid7485074 -}{\f39\fs20\insrsid7485074\charrsid7485074 in }{\f39\fs20\insrsid7485074\charrsid7485074 and/}{\f39\fs20\insrsid7485074\charrsid7485074 or it}{
+\f39\fs20\insrsid7485074\charrsid7485074 s}{\f39\fs20\insrsid7485074\charrsid7485074 source-code, I would }{\f39\fs20\insrsid7485074\charrsid7485074 appreciate }{\f39\fs20\insrsid7485074\charrsid7485074 if my name is mentioned.}{
+\f39\fs20\insrsid7485074\charrsid7485074
+\par }\pard \qj \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid7485074 {\f39\fs20\insrsid7485074\charrsid7485074
+\par }{\b\f39\fs20\insrsid7485074\charrsid7485074 Andrei Ciubotaru [Hardwired]
+\par }{\f39\fs20\insrsid7485074\charrsid7485074 Lead Developer ICode&Ideas SRL (}{\field\flddirty{\*\fldinst {\f39\fs20\insrsid7485074\charrsid7485074 HYPERLINK "http://www.icode.ro/" }{\f39\fs20\insrsid7485074\charrsid7485074 {\*\datafield
+00d0c9ea79f9bace118c8200aa004ba90b02000000170000001500000068007400740070003a002f002f007700770077002e00690063006f00640065002e0072006f002f000000e0c9ea79f9bace118c8200aa004ba90b2a00000068007400740070003a002f002f007700770077002e00690063006f00640065002e007200
+6f002f000000}}}{\fldrslt {\cs15\f39\fs20\ul\cf2\insrsid7485074\charrsid7485074 http://www.icode.ro/}}}{\f39\fs20\insrsid7485074\charrsid7485074 )
+\par }{\field{\*\fldinst {\f39\fs20\insrsid7485074 HYPERLINK "hardwiredteks@gmail.com" }{\f39\fs20\insrsid15940516\charrsid7485074 {\*\datafield
+00d0c9ea79f9bace118c8200aa004ba90b02000000010000000303000000000000c00000000000004600001800000068617264776972656474656b7340676d61696c2e636f6d00ffffadde000000000000000000000000000000000000000000000000}}}{\fldrslt {
+\cs15\f39\fs20\ul\cf2\insrsid7485074\charrsid7485074 hardwiredteks@gmail.com}}}{\f39\fs20\insrsid7485074\charrsid7485074 , }{\field{\*\fldinst {\f39\fs20\insrsid7485074 HYPERLINK "hardwired@icode.ro" }{\f39\fs20\insrsid15940516\charrsid7485074
+{\*\datafield 00d0c9ea79f9bace118c8200aa004ba90b02000000010000000303000000000000c0000000000000460000130000006861726477697265644069636f64652e726f00ffffadde000000000000000000000000000000000000000000000000}}}{\fldrslt {
+\cs15\f39\fs20\ul\cf2\insrsid7485074\charrsid7485074 hardwired@icode.ro}}}{\f39\fs20\insrsid7485074\charrsid7485074
+\par }} \ No newline at end of file
diff --git a/admin/win/nsi/nsis_processes/readme.txt b/admin/win/nsi/nsis_processes/readme.txt
new file mode 100755
index 000000000..8529c39ad
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/readme.txt
@@ -0,0 +1,122 @@
+----------------------------------------------------------------
+----------------------------------------------------------------
+Processes (Processes.dll)
+Version: 1.0.1.0
+Release: 24.february.2005
+Description: Nullsoft Installer (NSIS) plug-in for managing?!
+ Windows processes.
+
+Copyright: © 2004-2005 Hardwired. No rights reserved.
+ There is no restriction and no guaranty for using
+ this software.
+
+Author: Andrei Ciubotaru [Hardwired]
+ Lead Developer ICode&Ideas SRL (http://www.icode.ro/)
+ hardwiredteks@gmail.com, hardwired@icode.ro
+
+----------------------------------------------------------------
+----------------------------------------------------------------
+INTRODUCTION
+
+ The Need For Plug-in - I need it for the one of my installers.
+
+ Briefly: Use it when you need to find\kill a process when
+installing\uninstalling some application. Also, use it when you
+need to test the presence of a device driver.
+
+
+SUPPORT
+
+ Supported platforms are: WinNT,Win2K,WinXP and Win2003 Server.
+
+
+DESCRIPTION
+
+ Processes::FindProcess <process_name> ;without ".exe"
+
+ Searches the currently running processes for the given
+ process name.
+
+ return: 1 - the process was found
+ 0 - the process was not found
+
+ Processes::KillProcess <process_name> ; without ".exe"
+
+ Searches the currently running processes for the given
+ process name. If the process is found then the it gets
+ killed.
+
+ return: 1 - the process was found and killed
+ 0 - the process was not found or the process
+ cannot be killed (insuficient rights)
+
+ Processes::FindDevice <device_base_name>
+
+ Searches the installed devices drivers for the given
+ device base name.
+ (important: I said BASE NAME not FILENAME)
+
+ return: 1 - the device driver was found
+ 0 - the device driver was not found
+
+
+USAGE
+
+ First of all, does not matter where you use it. Ofcourse, the
+routines must be called inside of a Section/Function scope.
+
+ Processes::FindProcess "process_name"
+ Pop $R0
+
+ StrCmp $R0 "1" make_my_day noooooo
+
+ make_my_day:
+ ...
+
+ noooooo:
+ ...
+
+
+ Processes::KillProcess "process_name"
+ Pop $R0
+
+ StrCmp $R0 "1" dead_meat why_wont_you_die
+
+ dead_meat:
+ ...
+
+ why_wont_you_die:
+ ...
+
+
+ Processes::FindDevice "device_base_name"
+ Pop $R0
+
+ StrCmp $R0 "1" blabla more_blabla
+
+ blabla:
+ ...
+
+ more_blabla:
+ ...
+
+
+THANKS
+
+ Sunil Kamath for inspiring me. I wanted to use its FindProcDLL
+but my requirements made it imposible.
+
+ Nullsoft for creating this very powerfull installer. One big,
+free and full-featured (hmmm... and guiless for the moment) mean
+install machine!:)
+
+ ME for being such a great coder...
+ ... HAHAHAHAHAHAHA!
+
+ONE MORE THING
+
+ If you use the plugin or it's source-code, I would apreciate
+if my name is mentioned.
+
+----------------------------------------------------------------
+----------------------------------------------------------------
diff --git a/admin/win/nsi/nsis_processes/src/StdAfx.cpp b/admin/win/nsi/nsis_processes/src/StdAfx.cpp
new file mode 100755
index 000000000..f38accc8a
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/StdAfx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// KillProcDLL.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/admin/win/nsi/nsis_processes/src/StdAfx.h b/admin/win/nsi/nsis_processes/src/StdAfx.h
new file mode 100755
index 000000000..dd49f99b9
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/StdAfx.h
@@ -0,0 +1,34 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__780690DC_E128_403D_BC07_780D1B2CC101__INCLUDED_)
+#define AFX_STDAFX_H__780690DC_E128_403D_BC07_780D1B2CC101__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+
+#include <windows.h>
+
+#include <string> // String management...
+
+//From exam28.cpp
+#include <tlhelp32.h>
+//#include <iostream.h>
+
+#ifdef BORLANDC
+ #include <string.h>
+ #include <ctype.h>
+#endif
+
+//To make it a NSIS Plug-In
+#include "exdll.h"
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__780690DC_E128_403D_BC07_780D1B2CC101__INCLUDED_)
diff --git a/admin/win/nsi/nsis_processes/src/exdll.c b/admin/win/nsi/nsis_processes/src/exdll.c
new file mode 100755
index 000000000..7092cb840
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/exdll.c
@@ -0,0 +1,37 @@
+#include <windows.h>
+#include "exdll.h"
+
+HINSTANCE g_hInstance;
+
+HWND g_hwndParent;
+
+void __declspec(dllexport) myFunction(HWND hwndParent, int string_size,
+ char *variables, stack_t **stacktop)
+{
+ g_hwndParent=hwndParent;
+
+ EXDLL_INIT();
+
+
+ // note if you want parameters from the stack, pop them off in order.
+ // i.e. if you are called via exdll::myFunction file.dat poop.dat
+ // calling popstring() the first time would give you file.dat,
+ // and the second time would give you poop.dat.
+ // you should empty the stack of your parameters, and ONLY your
+ // parameters.
+
+ // do your stuff here
+ {
+ char buf[1024];
+ wsprintf(buf,"$0=%s\n",getuservariable(INST_0));
+ MessageBox(g_hwndParent,buf,0,MB_OK);
+ }
+}
+
+
+
+BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
+{
+ g_hInstance=hInst;
+ return TRUE;
+}
diff --git a/admin/win/nsi/nsis_processes/src/exdll.h b/admin/win/nsi/nsis_processes/src/exdll.h
new file mode 100755
index 000000000..777d93be5
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/exdll.h
@@ -0,0 +1,136 @@
+#ifndef _EXDLL_H_
+#define _EXDLL_H_
+
+
+
+
+
+//
+// only include this file from one place in your DLL.
+// (it is all static, if you use it in two places it will fail)
+//
+#define EXDLL_INIT() { \
+ g_stringsize = string_size; \
+ g_stacktop = stacktop; \
+ g_variables = variables; }
+
+
+
+
+//
+// For page showing plug-ins
+//
+#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
+#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
+#define NOTIFY_BYE_BYE 'x'
+
+typedef struct _stack_t
+{
+ struct _stack_t *next;
+ char text[1]; // this should be the length of string_size
+} stack_t;
+
+
+static unsigned int g_stringsize;
+static stack_t **g_stacktop;
+static char *g_variables;
+
+enum
+{
+INST_0, // $0
+INST_1, // $1
+INST_2, // $2
+INST_3, // $3
+INST_4, // $4
+INST_5, // $5
+INST_6, // $6
+INST_7, // $7
+INST_8, // $8
+INST_9, // $9
+INST_R0, // $R0
+INST_R1, // $R1
+INST_R2, // $R2
+INST_R3, // $R3
+INST_R4, // $R4
+INST_R5, // $R5
+INST_R6, // $R6
+INST_R7, // $R7
+INST_R8, // $R8
+INST_R9, // $R9
+INST_CMDLINE, // $CMDLINE
+INST_INSTDIR, // $INSTDIR
+INST_OUTDIR, // $OUTDIR
+INST_EXEDIR, // $EXEDIR
+INST_LANG, // $LANGUAGE
+__INST_LAST
+};
+
+
+
+
+
+//
+// utility functions (not required but often useful)
+//
+static int popstring( char *str )
+{
+ stack_t *th;
+
+
+ if( !g_stacktop ||
+ !*g_stacktop )
+ return 1;
+
+ th = (*g_stacktop);
+ lstrcpy( str, th->text );
+ *g_stacktop = th->next;
+ GlobalFree( (HGLOBAL)th );
+
+ return 0;
+}
+
+
+
+
+static void pushstring( char *str )
+{
+ stack_t *th;
+
+
+ if( !g_stacktop )
+ return;
+
+ th = (stack_t*)GlobalAlloc( GPTR, sizeof(stack_t) + g_stringsize );
+ lstrcpyn( th->text, str, g_stringsize );
+ th->next = *g_stacktop;
+ *g_stacktop = th;
+}
+
+
+
+
+
+static char *getuservariable( int varnum )
+{
+ if( varnum < 0 ||
+ varnum >= __INST_LAST )
+ return NULL;
+
+ return (g_variables + varnum*g_stringsize);
+}
+
+
+
+
+
+static void setuservariable( int varnum, char *var )
+{
+ if( var != NULL &&
+ varnum >= 0 &&
+ varnum < __INST_LAST )
+ lstrcpy( g_variables + varnum*g_stringsize, var );
+}
+
+
+
+#endif//_EXDLL_H_ \ No newline at end of file
diff --git a/admin/win/nsi/nsis_processes/src/processes.cpp b/admin/win/nsi/nsis_processes/src/processes.cpp
new file mode 100755
index 000000000..c15f8f94a
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/processes.cpp
@@ -0,0 +1,411 @@
+#include "stdafx.h"
+#include "processes.h"
+#include "string.h"
+
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+// global variables
+lpfEnumProcesses EnumProcesses;
+lpfEnumProcessModules EnumProcessModules;
+lpfGetModuleBaseName GetModuleBaseName;
+lpfEnumDeviceDrivers EnumDeviceDrivers;
+lpfGetDeviceDriverBaseName GetDeviceDriverBaseName;
+
+HINSTANCE g_hInstance;
+HWND g_hwndParent;
+HINSTANCE g_hInstLib;
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+// main DLL entry
+BOOL WINAPI _DllMainCRTStartup( HANDLE hInst,
+ ULONG ul_reason_for_call,
+ LPVOID lpReserved )
+{
+ g_hInstance = (struct HINSTANCE__ *)hInst;
+
+ return TRUE;
+}
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+// loads the psapi routines
+bool LoadPSAPIRoutines( void )
+{
+ if( NULL == (g_hInstLib = LoadLibraryA( "PSAPI.DLL" )) )
+ return false;
+
+ EnumProcesses = (lpfEnumProcesses) GetProcAddress( g_hInstLib, "EnumProcesses" );
+ EnumProcessModules = (lpfEnumProcessModules) GetProcAddress( g_hInstLib, "EnumProcessModules" );
+ GetModuleBaseName = (lpfGetModuleBaseName) GetProcAddress( g_hInstLib, "GetModuleBaseNameA" );
+ EnumDeviceDrivers = (lpfEnumDeviceDrivers) GetProcAddress( g_hInstLib, "EnumDeviceDrivers" );
+ GetDeviceDriverBaseName = (lpfGetDeviceDriverBaseName) GetProcAddress( g_hInstLib, "GetDeviceDriverBaseNameA" );
+
+ if( ( NULL == EnumProcesses ) ||
+ ( NULL == EnumProcessModules ) ||
+ ( NULL == EnumDeviceDrivers ) ||
+ ( NULL == GetModuleBaseName ) ||
+ ( NULL == GetDeviceDriverBaseName ) )
+ {
+ FreeLibrary( g_hInstLib );
+
+ return false;
+ }
+
+ return true;
+}
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+// free the psapi routines
+bool FreePSAPIRoutines( void )
+{
+ EnumProcesses = NULL;
+ EnumProcessModules = NULL;
+ GetModuleBaseName = NULL;
+ EnumDeviceDrivers = NULL;
+
+ if( FALSE == FreeLibrary( g_hInstLib ) )
+ return false;
+
+ return true;
+}
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+// find a process by name
+// return value: true - process was found
+// false - process not found
+bool FindProc( char *szProcess )
+{
+ char szProcessName[ 1024 ];
+ char szCurrentProcessName[ 1024 ];
+ DWORD dPID[ 1024 ];
+ DWORD dPIDSize( 1024 );
+ DWORD dSize( 1024 );
+ HANDLE hProcess;
+ HMODULE phModule[ 1024 ];
+
+
+ //
+ // make the name lower case
+ //
+ memset( szProcessName, 0, 1024*sizeof(char) );
+ sprintf( szProcessName, "%s", szProcess );
+ strlwr( szProcessName );
+
+ //
+ // load PSAPI routines
+ //
+ if( false == LoadPSAPIRoutines() )
+ return false;
+
+ //
+ // enumerate processes names
+ //
+ if( FALSE == EnumProcesses( dPID, dSize, &dPIDSize ) )
+ {
+ FreePSAPIRoutines();
+
+ return false;
+ }
+
+ //
+ // walk trough and compare see if the process is running
+ //
+ for( int k( dPIDSize / sizeof( DWORD ) ); k >= 0; k-- )
+ {
+ memset( szCurrentProcessName, 0, 1024*sizeof(char) );
+
+ if( NULL != ( hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dPID[ k ] ) ) )
+ {
+ if( TRUE == EnumProcessModules( hProcess, phModule, sizeof(HMODULE)*1024, &dPIDSize ) )
+ if( GetModuleBaseName( hProcess, phModule[ 0 ], szCurrentProcessName, 1024 ) > 0 )
+ {
+ strlwr( szCurrentProcessName );
+
+ if( NULL != strstr( szCurrentProcessName, szProcessName ) )
+ {
+ FreePSAPIRoutines();
+ CloseHandle( hProcess );
+
+ return true;
+ }
+ }
+
+ CloseHandle( hProcess );
+ }
+ }
+
+ //
+ // free PSAPI routines
+ //
+ FreePSAPIRoutines();
+
+ return false;
+}
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+// kills a process by name
+// return value: true - process was found
+// false - process not found
+bool KillProc( char *szProcess )
+{
+ char szProcessName[ 1024 ];
+ char szCurrentProcessName[ 1024 ];
+ DWORD dPID[ 1024 ];
+ DWORD dPIDSize( 1024 );
+ DWORD dSize( 1024 );
+ HANDLE hProcess;
+ HMODULE phModule[ 1024 ];
+
+
+ //
+ // make the name lower case
+ //
+ memset( szProcessName, 0, 1024*sizeof(char) );
+ sprintf( szProcessName, "%s", szProcess );
+ strlwr( szProcessName );
+
+ //
+ // load PSAPI routines
+ //
+ if( false == LoadPSAPIRoutines() )
+ return false;
+
+ //
+ // enumerate processes names
+ //
+ if( FALSE == EnumProcesses( dPID, dSize, &dPIDSize ) )
+ {
+ FreePSAPIRoutines();
+
+ return false;
+ }
+
+ //
+ // walk trough and compare see if the process is running
+ //
+ for( int k( dPIDSize / sizeof( DWORD ) ); k >= 0; k-- )
+ {
+ memset( szCurrentProcessName, 0, 1024*sizeof(char) );
+
+ if( NULL != ( hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dPID[ k ] ) ) )
+ {
+ if( TRUE == EnumProcessModules( hProcess, phModule, sizeof(HMODULE)*1024, &dPIDSize ) )
+ if( GetModuleBaseName( hProcess, phModule[ 0 ], szCurrentProcessName, 1024 ) > 0 )
+ {
+ strlwr( szCurrentProcessName );
+
+ if( NULL != strstr( szCurrentProcessName, szProcessName ) )
+ {
+ FreePSAPIRoutines();
+
+ //
+ // kill process
+ //
+ if( false == TerminateProcess( hProcess, 0 ) )
+ {
+ CloseHandle( hProcess );
+
+ return true;
+ }
+
+ //
+ // refresh systray
+ //
+ UpdateWindow( FindWindow( NULL, "Shell_TrayWnd" ) );
+
+ //
+ // refresh desktop window
+ //
+ UpdateWindow( GetDesktopWindow() );
+
+ CloseHandle( hProcess );
+
+ return true;
+ }
+ }
+
+ CloseHandle( hProcess );
+ }
+ }
+
+ //
+ // free PSAPI routines
+ //
+ FreePSAPIRoutines();
+
+ return false;
+}
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+bool FindDev( char *szDriverName )
+{
+ char szDeviceName[ 1024 ];
+ char szCurrentDeviceName[ 1024 ];
+ LPVOID lpDevices[ 1024 ];
+ DWORD dDevicesSize( 1024 );
+ DWORD dSize( 1024 );
+ TCHAR tszCurrentDeviceName[ 1024 ];
+ DWORD dNameSize( 1024 );
+
+
+ //
+ // make the name lower case
+ //
+ memset( szDeviceName, 0, 1024*sizeof(char) );
+ sprintf( szDeviceName, "%s", strlwr( szDriverName ) );
+
+ //
+ // load PSAPI routines
+ //
+ if( false == LoadPSAPIRoutines() )
+ return false;
+
+ //
+ // enumerate devices
+ //
+ if( FALSE == EnumDeviceDrivers( lpDevices, dSize, &dDevicesSize ) )
+ {
+ FreePSAPIRoutines();
+
+ return false;
+ }
+
+ //
+ // walk trough and compare see if the device driver exists
+ //
+ for( int k( dDevicesSize / sizeof( LPVOID ) ); k >= 0; k-- )
+ {
+ memset( szCurrentDeviceName, 0, 1024*sizeof(char) );
+ memset( tszCurrentDeviceName, 0, 1024*sizeof(TCHAR) );
+
+ if( 0 != GetDeviceDriverBaseName( lpDevices[ k ], tszCurrentDeviceName, dNameSize ) )
+ {
+ sprintf( szCurrentDeviceName, "%S", tszCurrentDeviceName );
+
+ if( 0 == strcmp( strlwr( szCurrentDeviceName ), szDeviceName ) )
+ {
+ FreePSAPIRoutines();
+
+ return true;
+ }
+ }
+ }
+
+ //
+ // free PSAPI routines
+ //
+ FreePSAPIRoutines();
+
+ return false;
+}
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+extern "C" __declspec(dllexport) void FindProcess( HWND hwndParent,
+ int string_size,
+ char *variables,
+ stack_t **stacktop )
+{
+ char szParameter[ 1024 ];
+
+
+ g_hwndParent = hwndParent;
+
+ EXDLL_INIT();
+ {
+ popstring( szParameter );
+
+ if( true == FindProc( szParameter ) )
+ wsprintf( szParameter, "1" );
+ else
+ wsprintf( szParameter, "0" );
+
+ setuservariable( INST_R0, szParameter );
+ }
+}
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+extern "C" __declspec(dllexport) void KillProcess( HWND hwndParent,
+ int string_size,
+ char *variables,
+ stack_t **stacktop )
+{
+ char szParameter[ 1024 ];
+
+
+ g_hwndParent = hwndParent;
+
+ EXDLL_INIT();
+ {
+ popstring( szParameter );
+
+ if( true == KillProc( szParameter ) )
+ wsprintf( szParameter, "1" );
+ else
+ wsprintf( szParameter, "0" );
+
+ setuservariable( INST_R0, szParameter );
+ }
+}
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+extern "C" __declspec(dllexport) void FindDevice( HWND hwndParent,
+ int string_size,
+ char *variables,
+ stack_t **stacktop )
+{
+ char szParameter[ 1024 ];
+
+
+ g_hwndParent = hwndParent;
+
+ EXDLL_INIT();
+ {
+ popstring( szParameter );
+
+ if( true == FindDev( szParameter ) )
+ wsprintf( szParameter, "1" );
+ else
+ wsprintf( szParameter, "0" );
+
+ setuservariable( INST_R0, szParameter );
+ }
+}
diff --git a/admin/win/nsi/nsis_processes/src/processes.h b/admin/win/nsi/nsis_processes/src/processes.h
new file mode 100755
index 000000000..9bd069101
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/processes.h
@@ -0,0 +1,49 @@
+#pragma once
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+// PSAPI function pointers
+typedef BOOL (WINAPI *lpfEnumProcesses) ( DWORD *, DWORD, DWORD * );
+typedef BOOL (WINAPI *lpfEnumProcessModules) ( HANDLE, HMODULE *, DWORD, LPDWORD );
+typedef DWORD (WINAPI *lpfGetModuleBaseName) ( HANDLE, HMODULE, LPTSTR, DWORD );
+typedef BOOL (WINAPI *lpfEnumDeviceDrivers) ( LPVOID *, DWORD, LPDWORD );
+typedef BOOL (WINAPI *lpfGetDeviceDriverBaseName)( LPVOID, LPTSTR, DWORD );
+
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+// Internal use routines
+bool LoadPSAPIRoutines( void );
+bool FreePSAPIRoutines( void );
+
+bool FindProc( char *szProcess );
+bool KillProc( char *szProcess );
+
+bool FindDev( char *szDriverName );
+
+
+
+
+
+//-------------------------------------------------------------------------------------------
+// Exported routines
+extern "C" __declspec(dllexport) void FindProcess( HWND hwndParent,
+ int string_size,
+ char *variables,
+ stack_t **stacktop );
+
+extern "C" __declspec(dllexport) void KillProcess( HWND hwndParent,
+ int string_size,
+ char *variables,
+ stack_t **stacktop );
+
+extern "C" __declspec(dllexport) void FindDevice( HWND hwndParent,
+ int string_size,
+ char *variables,
+ stack_t **stacktop );
diff --git a/admin/win/nsi/nsis_processes/src/processes.ncb b/admin/win/nsi/nsis_processes/src/processes.ncb
new file mode 100755
index 000000000..c1a5f281f
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/processes.ncb
Binary files differ
diff --git a/admin/win/nsi/nsis_processes/src/processes.rc b/admin/win/nsi/nsis_processes/src/processes.rc
new file mode 100755
index 000000000..c6e62a3c8
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/processes.rc
@@ -0,0 +1,103 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "NSIS Plug-in for Windows process management. Only WinNT, Win2K, WinXP and Win2003 Server supported."
+ VALUE "CompanyName", "Andrei Ciubotaru [Hardwired]"
+ VALUE "FileDescription", "Windows Processes Management"
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "InternalName", "Processes"
+ VALUE "LegalCopyright", "Copyright (c) 2004 Hardwired. No rights reserved."
+ VALUE "OriginalFilename", "Processes.dll"
+ VALUE "ProductName", "Processes"
+ VALUE "ProductVersion", "1, 0, 0, 1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/admin/win/nsi/nsis_processes/src/processes.sln b/admin/win/nsi/nsis_processes/src/processes.sln
new file mode 100755
index 000000000..73fc989e2
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/processes.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "processes", "processes.vcproj", "{3438467F-A719-46DC-93E5-137A8B691727}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {3438467F-A719-46DC-93E5-137A8B691727}.Debug.ActiveCfg = Debug|Win32
+ {3438467F-A719-46DC-93E5-137A8B691727}.Debug.Build.0 = Debug|Win32
+ {3438467F-A719-46DC-93E5-137A8B691727}.Release.ActiveCfg = Release|Win32
+ {3438467F-A719-46DC-93E5-137A8B691727}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/admin/win/nsi/nsis_processes/src/processes.txt b/admin/win/nsi/nsis_processes/src/processes.txt
new file mode 100755
index 000000000..51d11902a
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/processes.txt
@@ -0,0 +1,122 @@
+----------------------------------------------------------------
+----------------------------------------------------------------
+Processes (Processes.dll)
+Version: 1.0.0.1
+Release: 12.december.2004
+Description:Nullsoft Installer (NSIS) plug-in for managing?!
+ Windows processes.
+
+Copyright: © 2004 Hardwired. No rights reserved.
+ There is no restriction and no guaranty for using
+ this software.
+
+Author: Andrei Ciubotaru [Hardwired]
+ Lead Developer ICode&Ideas SRL (http://www.icode.ro)
+ hardwiredteks@gmail.com, hardwired@icode.ro
+
+----------------------------------------------------------------
+----------------------------------------------------------------
+INTRODUCTION
+
+ The Need For Plug-in - I need it for the one of my installers.
+
+ Briefly: Use it when you need to find\kill a process when
+installing\uninstalling some application. Also, use it when you
+need to test the presence of a device driver.
+
+
+SUPPORT
+
+ Supported platforms are: WinNT,Win2K,WinXP and Win2003 Server.
+
+
+DESCRIPTION
+
+ Processes::FindProcess <process_name.exe>
+
+ Searches the currently running processes for the given
+ process name.
+
+ return: 1 - the process was found
+ 0 - the process was not found
+
+ Processes::KillProcess <process_name.exe>
+
+ Searches the currently running processes for the given
+ process name. If the process is found then the it gets
+ killed.
+
+ return: 1 - the process was found and killed
+ 0 - the process was not found or the process
+ cannot be killed (insuficient rights)
+
+ Processes::FindDevice <device_base_name>
+
+ Searches the installed devices drivers for the given
+ device base name.
+ (important: I said BASE NAME not FILENAME)
+
+ return: 1 - the device driver was found
+ 0 - the device driver was not found
+
+
+USAGE
+
+ First of all, does not matter where you use it. Ofcourse, the
+routines must be called inside of a Section/Function scope.
+
+ Processes::FindProcess "process_name.exe"
+ Pop $R0
+
+ StrCmp $R0 "1" make_my_day noooooo
+
+ make_my_day:
+ ...
+
+ noooooo:
+ ...
+
+
+ Processes::KillProcess "process_name.exe"
+ Pop $R0
+
+ StrCmp $R0 "1" dead_meat why_wont_you_die
+
+ dead_meat:
+ ...
+
+ why_wont_you_die:
+ ...
+
+
+ Processes::FindDevice "device_base_name"
+ Pop $R0
+
+ StrCmp $R0 "1" blabla more_blabla
+
+ blabla:
+ ...
+
+ more_blabla:
+ ...
+
+
+THANKS
+
+ Sunil Kamath for inspiring me. I wanted to use its FindProcDLL
+but my requirements made it imposible.
+
+ Nullsoft for creating this very powerfull installer. One big,
+free and full-featured (hmmm... and guiless for the moment) mean
+install machine!:)
+
+ ME for being such a great coder...
+ ... HAHAHAHAHAHAHA!
+
+ONE MORE THING
+
+ If you use the plugin or it's source-code, I would apreciate
+if my name is mentioned.
+
+----------------------------------------------------------------
+----------------------------------------------------------------
diff --git a/admin/win/nsi/nsis_processes/src/processes.vcproj b/admin/win/nsi/nsis_processes/src/processes.vcproj
new file mode 100755
index 000000000..245cbc99f
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/processes.vcproj
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="processes"
+ SccProjectName="processes"
+ SccLocalPath=".">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FINDPROCDLL_EXPORTS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile=".\Debug/processes.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile=".\Debug/processes.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile=".\Debug/processes.pdb"
+ ImportLibrary=".\Debug/processes.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/processes.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1034"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="..\bin"
+ IntermediateDirectory="..\bin\processes"
+ ConfigurationType="2"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="1"
+ FavorSizeOrSpeed="1"
+ OptimizeForWindowsApplication="TRUE"
+ PreprocessorDefinitions="NDEBUG;_WINDOWS;_USRDLL;FINDPROCDLL_EXPORTS"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ StructMemberAlignment="1"
+ EnableFunctionLevelLinking="TRUE"
+ UsePrecompiledHeader="3"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile="..\bin\processes/processes.pch"
+ AssemblerListingLocation="..\bin\processes/"
+ ObjectFile="..\bin\processes/"
+ ProgramDataBaseFileName="..\bin\processes/"
+ WarningLevel="4"
+ SuppressStartupBanner="TRUE"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="libc.lib"
+ OutputFile="..\bin/Processes.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreAllDefaultLibraries="FALSE"
+ ProgramDatabaseFile="..\bin/processes.pdb"
+ OptimizeForWindows98="1"
+ ImportLibrary="..\bin/processes.lib"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/processes.tlb"
+ HeaderFileName=""/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+ <File
+ RelativePath="processes.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;FINDPROCDLL_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ PreprocessorDefinitions="NDEBUG;_WINDOWS;_MBCS;_USRDLL;FINDPROCDLL_EXPORTS;$(NoInherit)"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\processes.rc">
+ </File>
+ <File
+ RelativePath="StdAfx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;FINDPROCDLL_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ PreprocessorDefinitions="NDEBUG;_WINDOWS;_MBCS;_USRDLL;FINDPROCDLL_EXPORTS;$(NoInherit)"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl">
+ <File
+ RelativePath="exdll.h">
+ </File>
+ <File
+ RelativePath=".\processes.h">
+ </File>
+ <File
+ RelativePath=".\resource.h">
+ </File>
+ <File
+ RelativePath="StdAfx.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ </Filter>
+ <File
+ RelativePath="processes.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/admin/win/nsi/nsis_processes/src/resource.h b/admin/win/nsi/nsis_processes/src/resource.h
new file mode 100755
index 000000000..506377e21
--- /dev/null
+++ b/admin/win/nsi/nsis_processes/src/resource.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by processes.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/admin/win/nsi/nsis_uac/History.txt b/admin/win/nsi/nsis_uac/History.txt
new file mode 100755
index 000000000..ee8af46c0
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/History.txt
@@ -0,0 +1,102 @@
+History:
+--------
+
+v0.0.11d - 20090705 (AndersK)
+ *Fixed UAC_RealWorldFullyLoadedDualModeExample.nsi so installing as admin will allow both modes
+
+v0.0.11c - 20090124 (AndersK)
+ *Checks for seclogon service on NT5 and returns ERROR_SERVICE_NOT_ACTIVE in $0 if not running
+
+v0.0.11b - 20090102 (AndersK)
+ *Fixed unicode compile bugs
+
+v0.0.11 - 20081021 (AndersK)
+ +Added UAC_GetUserShellFolderPath.nsi (Uses the new UAC::GetShellFolderPath)
+
+v0.0.10a - 20081004 (AndersK)
+ +Added SEE_MASK_NOZONECHECKS flag (experimental)
+
+v0.0.10 - 20080812 (AndersK)
+ +Added ugly hook hack to the shells run-as dialog on xp, defaults to other user
+
+v0.0.9 - 20080721 (AndersK)
+ *Fixed UAC_RealWorldFullyLoadedDualModeExample.nsi related bug (Thanks Case)
+
+v0.0.8 - 20080310 (AndersK)
+ +HTML Readme
+ +Added UAC::GetOuterHwnd (used by UAC_RealWorldFullyLoadedDualModeExample.nsi)
+ *Fixed UAC_RealWorldFullyLoadedDualModeExample.nsi
+ *Major code cleanup in UAC.cpp
+ -Removed UAC::RunElevatedAndProcessMessages (UAC::RunElevated now supports non NULL $HWNDParent)
+ -Removed several useless sample scripts
+
+v0.0.7e - 20080229 (AndersK)
+ *Added ugly hack for hackwnd to find correct title and give us a proper taskbar so the elevation dialog does not get lost (2000,XP (This also fixed Alt-Tab icon on Vista))
+ *Should compile with MSVC2005 now (Thanks Case)
+ *More unicode fixes, this time even tested with NSIS Unicode (Only RunElevated and Exec tested)
+
+v0.0.7d - 20080226 (AndersK)
+ *Fixed a couple of unicode version bugs (Unicode version still untested)
+ *Fixed weird XP string length bug (Thanks kfank)
+
+v0.0.7c - 20080218 (AndersK)
+ *Fixed SyncVars string length bug
+
+v0.0.7b - 20080205 (AndersK)
+ *Fixed DelayLoadDlls() problem on NT4
+
+v0.0.7 - 20080120 (AndersK)
+ +Added UAC::StackPush (For use with ExecCodeSegment)
+
+v0.0.6d - 20071108 (AndersK)
+ +Now syncs basic registers/variables before calling UAC::*Exec* and UAC::ExecCodeSegment (r0-r9,R0-R9,$CMDLINE,$INSTDIR,$OUTDIR,$EXEDIR,$LANGUAGE)
+ +Added UAC::RunElevatedAndProcessMessages, this can be called after .onInit (Very experimental, DO NOT USE)
+ +New include file with helper macros: UAC.nsh
+ *Replazed Clammerz hack with a better version
+
+v0.0.6c - 20071014 (AndersK)
+ +Check for and split up "domain\user" style input in RunAs.cpp for CreateProcessWithLogonW
+ *Added a ugly hack to trick messagebox'es in .OnInit to appear correctly on Vista (Thanks Clammerz)
+
+v0.0.6b - 20070523 (AndersK)
+ *Fixed showwindow flag (Thanks for the help kichik)
+
+v0.0.6 - 20070512 (AndersK)
+ +Added basic language support for MyRunAs dialog.
+
+v0.0.5e - 20070509 (AndersK)
+ *Fixed detection of UAC mode?
+ +IPC window is visible (but offscreen) during elevation to help with SetForegroundWindow/Focus problems
+
+v0.0.5d - 20070324 (AndersK)
+ *Fixed stupid IsAdmin bug
+
+v0.0.5c - 20070304 (AndersK)
+ *_IsAdmin now uses CheckTokenMembership if it exists ( MSKB:Q118626 / http://blogs.msdn.com/larryosterman/archive/2007/03/14/why-does-kb-118626-use-accesscheck-to-check-if-you-re-a-member-of-the-administrators-group.aspx )
+
+v0.0.5b - 20070301 (AndersK)
+ *Fixed ExecCodeSegment (Thread now calls CoInitialize)
+
+v0.0.5 - 20070228 (AndersK)
+ +Added ExecCodeSegment (You can now call ANY code in the context of the original user)
+
+v0.0.4b - 20070226 (AndersK)
+ *Fixed (My)RunAs font (http://blogs.msdn.com/oldnewthing/archive/2005/02/04/366987.aspx)
+
+v0.0.4 - 20070225 (AndersK)
+ +Added (My)RunAs dialog, used on Vista when running as LUA with UAC off
+ +Always uses /NCRC for elevated instance
+ *Now compiles as UNICODE (Untested, no UnicodeNSIS to test on)
+
+v0.0.3 - 20070224 (AndersK)
+ +Added Exec/ExecWait
+ +Added Verb & ShowWindow support for ShellExec[Wait]
+
+v0.0.2 - 20070219 (AndersK)
+ +Added ShellExecWait
+ *IPC srv wnd now has its own thread and msg loop
+ *Removed CRT dependency
+ *Hopefully loads on Win95 now
+
+v0.0.1 - 20070215 (AndersK)
+ *Initial release \ No newline at end of file
diff --git a/admin/win/nsi/nsis_uac/License.txt b/admin/win/nsi/nsis_uac/License.txt
new file mode 100755
index 000000000..a83294f8a
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/License.txt
@@ -0,0 +1,14 @@
+This software is provided 'as-is', without any express or implied warranty.
+
+ZLIB/LIBPNG LICENSE
+-------------------
+
+This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution. \ No newline at end of file
diff --git a/admin/win/nsi/nsis_uac/NSISUtil.h b/admin/win/nsi/nsis_uac/NSISUtil.h
new file mode 100755
index 000000000..d9920c375
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/NSISUtil.h
@@ -0,0 +1,149 @@
+/*
+Alternative to ExDll.h
+
+v0.0.1 - 20060811 (AndersK)
+*/
+
+#pragma once
+#include <TChar.h>
+
+
+typedef TCHAR NSISCH;
+#define NSISCALL __stdcall
+
+namespace NSIS {
+
+__forceinline void* NSISCALL MemAlloc(SIZE_T cb) {return GlobalAlloc(LPTR,cb);}
+__forceinline void NSISCALL MemFree(void* p) {GlobalFree(p);}
+
+enum {
+INST_0, // $0
+INST_1, // $1
+INST_2, // $2
+INST_3, // $3
+INST_4, // $4
+INST_5, // $5
+INST_6, // $6
+INST_7, // $7
+INST_8, // $8
+INST_9, // $9
+INST_R0, // $R0
+INST_R1, // $R1
+INST_R2, // $R2
+INST_R3, // $R3
+INST_R4, // $R4
+INST_R5, // $R5
+INST_R6, // $R6
+INST_R7, // $R7
+INST_R8, // $R8
+INST_R9, // $R9
+INST_CMDLINE, // $CMDLINE
+INST_INSTDIR, // $INSTDIR
+INST_OUTDIR, // $OUTDIR
+INST_EXEDIR, // $EXEDIR
+INST_LANG, // $LANGUAGE
+__INST_LAST,
+
+VIDX_TEMP=(INST_LANG+1), //#define state_temp_dir g_usrvars[25]
+VIDX_PLUGINSDIR,//# define state_plugins_dir g_usrvars[26]
+VIDX_EXEPATH,//#define state_exe_path g_usrvars[27]
+VIDX_EXEFILENAME,//#define state_exe_file g_usrvars[28]
+VIDX_STATECLICKNEXT,//#define state_click_next g_usrvars[30]
+__VIDX_UNDOCLAST
+};
+
+
+
+typedef struct _stack_t {
+ struct _stack_t *next;
+ NSISCH text[ANYSIZE_ARRAY];
+} stack_t;
+
+typedef struct {
+ int autoclose;
+ int all_user_var;
+ int exec_error;
+ int abort;
+ int exec_reboot;
+ int reboot_called;
+ int XXX_cur_insttype; // deprecated
+ int XXX_insttype_changed; // deprecated
+ int silent;
+ int instdir_error;
+ int rtl;
+ int errlvl;
+//NSIS v2.3x ?
+ int alter_reg_view;
+ int status_update;
+} exec_flags_type;
+
+typedef struct {
+ exec_flags_type *exec_flags;
+ int (NSISCALL *ExecuteCodeSegment)(int, HWND);
+ void (NSISCALL *validate_filename)(char *);
+} extra_parameters;
+
+extern UINT StrSize;
+extern stack_t **StackTop;
+extern NSISCH*Vars;
+
+inline bool NSISCALL SetErrLvl(extra_parameters*pExtraParams,int ErrLevel) {return pExtraParams? ((pExtraParams->exec_flags->errlvl=ErrLevel)||true):false;}
+inline bool NSISCALL SetErrorFlag(extra_parameters*pExtraParams) {return pExtraParams? ((pExtraParams->exec_flags->exec_error=1)||true):false;}
+inline bool NSISCALL ClearErrorFlag(extra_parameters*pExtraParams) {return pExtraParams?((pExtraParams->exec_flags->exec_error=0)||true):false;}
+
+__forceinline int NSISCALL ExecuteCodeSegment(extra_parameters*pExtraParams,int pos,HWND hwndProgress=NULL) {
+ return pExtraParams?pExtraParams->ExecuteCodeSegment(pos,hwndProgress):(/*EXEC_ERROR*/0x7FFFFFFF);
+}
+
+static NSISCH* __fastcall GetVar(const int varnum)
+{
+ //ASSERT(NSIS::Vars && NSIS::StrSize);
+ if (varnum < 0 || varnum >= __VIDX_UNDOCLAST) return NULL;
+ return NSIS::Vars+(varnum*NSIS::StrSize);
+}
+
+inline void NSISCALL SetVarUINT(const int varnum,UINT Value) {
+ wsprintf(GetVar(varnum),_T("%u"),Value);
+}
+
+static stack_t* NSISCALL StackPop() {
+ if (NSIS::StackTop && *NSIS::StackTop) {
+ stack_t*s=(*NSIS::StackTop);
+ *NSIS::StackTop=(*NSIS::StackTop)->next;
+ return s;
+ }
+ return 0;
+}
+__forceinline void NSISCALL StackFreeItem(stack_t*pStackItem) {NSIS::MemFree(pStackItem);}
+
+static DWORD NSISCALL StackPush(NSISCH*InStr,UINT StackStrSize=NSIS::StrSize) {
+ if (!NSIS::StackTop)return ERROR_INVALID_PARAMETER;
+ stack_t*sNew=(stack_t*)NSIS::MemAlloc(sizeof(stack_t)+(StackStrSize*sizeof(NSISCH)));
+ if (!sNew)return ERROR_OUTOFMEMORY;
+ lstrcpyn(sNew->text,InStr,StackStrSize);
+ sNew->next=*NSIS::StackTop;
+ *NSIS::StackTop=sNew;
+ return NO_ERROR;
+}
+
+}; /* namespace */
+
+#define NSISUTIL_INIT() namespace NSIS {static UINT StrSize;static stack_t **StackTop;static NSISCH*Vars;}//Call in only ONE source file
+#define NSISUTIL_INITEXPORT(_v,_strsize,_stackt) NSIS::Vars=_v;NSIS::StrSize=_strsize;NSIS::StackTop=_stackt
+
+//#define NSISEXPORT4(_func,_h,_strsize,_v,_stackt) extern "C" void __declspec(dllexport) __cdecl \
+// _func (HWND _h,int _strsize,NSISCH*_v,NSIS::stack_t **_stackt) { NSISUTIL_INITEXPORT(_v,_strsize,_stackt); TRACE("EXPORT::" #_func "\n");
+//#define NSISEXPORT5(_func,_h,_strsize,_v,_stackt,_eparams) extern "C" void __declspec(dllexport) __cdecl \
+// _func (HWND _h,int _strsize,NSISCH*_v,NSIS::stack_t **_stackt,NSIS::extra_parameters* _eparams) { NSISUTIL_INITEXPORT(_v,_strsize,_stackt); TRACE("EXPORT::" #_func "\n");
+//#define NSISEXPORT NSISEXPORT5
+
+#ifdef _MSC_VER
+# define EXPORTNSISFUNC extern "C" void __declspec(dllexport) __cdecl
+# else
+# error EXPORTNSISFUNC needs compiler goo, you are on your own!
+# endif
+#define NSISFUNCSTART4(_h,_strsize,_v,_stackt) {NSISUTIL_INITEXPORT(_v,_strsize,_stackt);
+#define NSISFUNCSTART5(_h,_strsize,_v,_stackt,_eparams) NSISFUNCSTART4(_h,_strsize,_v,_stackt)
+#define NSISFUNCSTART NSISFUNCSTART5
+#define NSISFUNCEND() }
+
diff --git a/admin/win/nsi/nsis_uac/Release/A/UAC.dll b/admin/win/nsi/nsis_uac/Release/A/UAC.dll
new file mode 100755
index 000000000..edf21305a
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/Release/A/UAC.dll
Binary files differ
diff --git a/admin/win/nsi/nsis_uac/Release/U/UAC.dll b/admin/win/nsi/nsis_uac/Release/U/UAC.dll
new file mode 100755
index 000000000..94dc71154
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/Release/U/UAC.dll
Binary files differ
diff --git a/admin/win/nsi/nsis_uac/RunAs.cpp b/admin/win/nsi/nsis_uac/RunAs.cpp
new file mode 100755
index 000000000..6d74b95a9
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/RunAs.cpp
@@ -0,0 +1,277 @@
+//Copyright (C) 2007 Anders Kjersem. Licensed under the zlib/libpng license, see License.txt for details.
+/*
+If UAC is disabled, the runas verb is broken (Vista RTM) so when running as LUA there is no way to elevate so
+we provide our own dialog.
+*/
+
+#include "UAC.h"
+#ifdef FEAT_CUSTOMRUNASDLG
+#include <Lmcons.h>//UNLEN && GNLEN && PWLEN
+#include <WindowsX.h>
+#include "resource.h"
+#include "NSISUtil.h"
+using namespace NSIS;
+#define ERRAPP_TRYAGAIN (0x20000000|1)
+#define MYMAX_DOMAIN (2+max(GNLEN,MAX_COMPUTERNAME_LENGTH)+1)
+
+
+static LPCTSTR g_RunAsDlgTitle=_T("Run as");
+static LPCTSTR g_RunAsHelpText=_T("You may not have the necessary permissions to use all the features of the program you are about to run. You may run this program as a different user or continue to run the program as the current user.");
+static LPCTSTR g_RunAsCurrUsrFmt=_T("&Current user (%s)");//Max 50 chars!
+static LPCTSTR g_RunAsSpecHelp=_T("Run the program as the &following user:");
+
+FORCEINLINE bool MySetDlgItemText(HWND hDlg,int id,LPCTSTR s) {return MySndDlgItemMsg(hDlg,id,WM_SETTEXT,0,(LPARAM)s)!=0;}
+
+typedef struct {
+ SHELLEXECUTEINFO*pSEI;
+ bool AsSelf;
+} RUNASDLGDATA;
+
+void MyRunAsFmtCurrUserRadio(HWND hDlg,LPCTSTR Fmt) {
+ TCHAR bufFullName[MYMAX_DOMAIN+UNLEN+1];
+ TCHAR buf[50+MYMAX_DOMAIN+UNLEN+1];
+ *bufFullName=0;
+ ULONG cch;
+ if ((!_GetUserNameEx || !_GetUserNameEx(NameSamCompatible,bufFullName,&(cch=COUNTOF(bufFullName)))) &&
+ !_GetUserName(bufFullName,&(cch=COUNTOF(bufFullName))) ) {
+ *bufFullName=0;
+ }
+ wsprintf(buf,Fmt,*bufFullName?bufFullName:_T("?"));
+ MySetDlgItemText(hDlg,IDC_RUNASCURR,buf);
+
+ // default the "User name:" to Administrator from shell32
+ if (LoadString(GetModuleHandle(_T("SHELL32.dll")),21763, bufFullName, COUNTOF(bufFullName)) > 0) {
+ MySetDlgItemText(hDlg,IDC_USERNAME,bufFullName);
+ }
+}
+
+#ifdef FEAT_CUSTOMRUNASDLG_TRANSLATE
+void MyRunAsTranslateDlgString(LPCTSTR StrID,LPTSTR Ini,HWND hDlg,INT_PTR DlgItemId,int special=0) {
+ TCHAR buf[MAX_PATH*2];
+ DWORD len=GetPrivateProfileString(_T("MyRunAsStrings"),StrID,0,buf,ARRAYSIZE(buf),Ini);
+ if (len) {
+ if (IDC_RUNASCURR==special)
+ MyRunAsFmtCurrUserRadio(hDlg,buf);
+ else
+ (DlgItemId==-1) ? SetWindowText(hDlg,buf) : MySetDlgItemText(hDlg,DlgItemId,buf);
+ }
+}
+
+void MyRunAsTranslateDlg(HWND hDlg) {
+ DWORD len;
+ TCHAR buf[MAX_PATH*2];
+ HMODULE hDll=GetWindowInstance(hDlg);ASSERT(hDll);
+ if ( (len=GetModuleFileName(hDll,buf,ARRAYSIZE(buf))) <1)return;
+ buf[len-3]=0;
+ lstrcat(buf,_T("lng"));
+ MyRunAsTranslateDlgString(_T("DlgTitle"),buf,hDlg,-1);
+ MyRunAsTranslateDlgString(_T("HelpText"),buf,hDlg,IDC_HELPTEXT);
+ MyRunAsTranslateDlgString(_T("OptCurrUser"),buf,hDlg,IDC_RUNASCURR,IDC_RUNASCURR);
+ MyRunAsTranslateDlgString(_T("OptOtherUser"),buf,hDlg,IDC_RUNASSPEC);
+ MyRunAsTranslateDlgString(_T("Username"),buf,hDlg,IDC_LBLUSER);
+ MyRunAsTranslateDlgString(_T("Pwd"),buf,hDlg,IDC_LBLPWD);
+ MyRunAsTranslateDlgString(_T("OK"),buf,hDlg,IDOK);
+ MyRunAsTranslateDlgString(_T("Cancel"),buf,hDlg,IDCANCEL);
+ HWND h=GetDlgItem(hDlg,IDC_RUNASCURR);
+ if (GetPrivateProfileInt(_T("MyRunAsCfg"),_T("DisableCurrUserOpt"),false,buf))EnableWindow(h,false);
+ if (GetPrivateProfileInt(_T("MyRunAsCfg"),_T("HideCurrUserOpt"),false,buf))ShowWindow(h,false);
+}
+#endif
+
+bool ErrorIsLogonError(DWORD err) {
+ switch (err) {
+ case ERROR_LOGON_FAILURE:
+ case ERROR_ACCOUNT_RESTRICTION:
+ case ERROR_INVALID_LOGON_HOURS:
+ case ERROR_INVALID_WORKSTATION:
+ case ERROR_PASSWORD_EXPIRED:
+ case ERROR_ACCOUNT_DISABLED:
+ case ERROR_NONE_MAPPED:
+ case ERROR_NO_SUCH_USER:
+ case ERROR_INVALID_ACCOUNT_NAME:
+ return true;
+ }
+ return false;
+}
+
+
+
+void VerifyOKBtn(HWND hDlg,RUNASDLGDATA*pRADD) {
+ const bool HasText=pRADD?(pRADD->AsSelf?true:MySndDlgItemMsg(hDlg,IDC_USERNAME,WM_GETTEXTLENGTH)>0):false;
+ EnableWindow(GetDlgItem(hDlg,IDOK),HasText);
+}
+
+void SetDlgState(HWND hDlg,bool AsSelf,RUNASDLGDATA*pRADD) {
+ if (pRADD)pRADD->AsSelf=AsSelf;
+ MySndDlgItemMsg(hDlg,IDC_RUNASCURR,BM_SETCHECK,AsSelf?BST_CHECKED:BST_UNCHECKED);
+ MySndDlgItemMsg(hDlg,IDC_RUNASSPEC,BM_SETCHECK,!AsSelf?BST_CHECKED:BST_UNCHECKED);
+ int ids[]={IDC_USERNAME,IDC_PASSWORD,IDC_LBLUSER,IDC_LBLPWD};
+ for (int i=0; i<COUNTOF(ids);++i)EnableWindow(GetDlgItem(hDlg,ids[i]),!AsSelf);
+ VerifyOKBtn(hDlg,pRADD);
+}
+
+INT_PTR CALLBACK MyRunAsDlgProc(HWND hwnd,UINT uMsg,WPARAM wp,LPARAM lp) {
+ RUNASDLGDATA*pRADD=(RUNASDLGDATA*)GetWindowLongPtr(hwnd,GWLP_USERDATA);
+ switch(uMsg) {
+ //case WM_DESTROY:
+ // break;
+ case WM_CLOSE:
+ return DestroyWindow(hwnd);
+ case WM_INITDIALOG:
+ {
+ pRADD=(RUNASDLGDATA*)lp;ASSERT(pRADD);
+ SetWindowLongPtr(hwnd,GWLP_USERDATA,lp);
+ Edit_LimitText(GetDlgItem(hwnd,IDC_USERNAME),UNLEN+1+MYMAX_DOMAIN); //room for "foo@BAR" or "BAR\foo"
+ Edit_LimitText(GetDlgItem(hwnd,IDC_PASSWORD),PWLEN);
+ const HINSTANCE hSh32=GetModuleHandle(_T("SHELL32.dll"));
+ const HICON hIco=(HICON)LoadImage(hSh32,MAKEINTRESOURCE(194),IMAGE_ICON,32,32,LR_SHARED);
+ MySndDlgItemMsg(hwnd,IDC_SHICON,STM_SETICON,(WPARAM)hIco);
+ SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)g_RunAsDlgTitle);
+ MySetDlgItemText(hwnd,IDC_HELPTEXT,g_RunAsHelpText);
+ MyRunAsFmtCurrUserRadio(hwnd,g_RunAsCurrUsrFmt);
+ MySetDlgItemText(hwnd,IDC_RUNASSPEC,g_RunAsSpecHelp);
+#ifdef FEAT_CUSTOMRUNASDLG_TRANSLATE
+ MyRunAsTranslateDlg(hwnd);
+#endif
+ SetDlgState(hwnd,false,pRADD);
+
+#if defined(BUILD_DBG) && 0 //auto login used during testing ;)
+ SetDlgItemText(hwnd,IDC_USERNAME,_T("root"));
+ SetDlgItemText(hwnd,IDC_PASSWORD,_T("???"));
+ Sleep(1);PostMessage(hwnd,WM_COMMAND,IDOK,0);
+#endif
+ }
+ return true;
+ case WM_COMMAND:
+ {
+ switch(HIWORD(wp)) {
+ case EN_CHANGE:
+ VerifyOKBtn(hwnd,pRADD);
+ break;
+ case EN_SETFOCUS:
+ case BN_CLICKED:
+ if (LOWORD(wp)<=IDCANCEL)break;
+ SetDlgState(hwnd,LOWORD(wp)==IDC_RUNASCURR,pRADD);
+ return FALSE;
+ }
+ INT_PTR exitcode=!pRADD?-1:IDCANCEL;
+ switch(LOWORD(wp)) {
+ case IDOK:
+ if (pRADD) {
+ SHELLEXECUTEINFO&sei=*pRADD->pSEI;
+ PROCESS_INFORMATION pi={0};
+ DWORD ec=NO_ERROR;
+ WCHAR*wszExec;//Also used as TCHAR buffer in AsSelf mode
+ bool PerformTCharFmt=pRADD->AsSelf;
+ //const DWORD CommonStartupInfoFlags=STARTF_FORCEONFEEDBACK;
+#ifdef UNICODE
+ PerformTCharFmt=true;
+#endif
+ wszExec=(WCHAR*)NSIS::MemAlloc( (pRADD->AsSelf?sizeof(TCHAR):sizeof(WCHAR)) *(lstrlen(sei.lpFile)+1+lstrlen(sei.lpParameters)+1));
+ if (!wszExec)ec=ERROR_OUTOFMEMORY;
+ if (PerformTCharFmt)wsprintf((TCHAR*)wszExec,_T("%s%s%s"),sei.lpFile,((sei.lpParameters&&*sei.lpParameters)?_T(" "):_T("")),sei.lpParameters);
+ if (!ec) {
+ if (pRADD->AsSelf) {
+ STARTUPINFO si={sizeof(si)};
+ TRACEF("MyRunAs:CreateProcess:%s|\n",wszExec);
+ ec=(CreateProcess(0,(TCHAR*)wszExec,0,0,false,0,0,0,&si,&pi)?NO_ERROR:GetLastError());
+ }
+ else {
+ //All Wide strings!
+ WCHAR wszPwd[PWLEN+1];
+ WCHAR wszUName[UNLEN+1+MYMAX_DOMAIN+1];
+ STARTUPINFOW siw={sizeof(siw)};
+ WCHAR*p;
+#ifndef UNICODE
+ //Build unicode string, we already know the buffer is big enough so no error handling
+ p=wszExec;
+ MultiByteToWideChar(CP_THREAD_ACP,0,sei.lpFile,-1,p,0xFFFFFF);
+ if (sei.lpParameters && *sei.lpParameters) {
+ p+=lstrlen(sei.lpFile);*p++=L' ';*p=0;
+ MultiByteToWideChar(CP_THREAD_ACP,0,sei.lpParameters,-1,p,0xFFFFFF);
+ }
+#endif
+ SendMessageW(GetDlgItem(hwnd,IDC_USERNAME),WM_GETTEXT,COUNTOF(wszUName),(LPARAM)wszUName);
+ SendMessageW(GetDlgItem(hwnd,IDC_PASSWORD),WM_GETTEXT,COUNTOF(wszPwd),(LPARAM)wszPwd);
+
+ //Try to find [\\]domain\user and split into username and domain strings
+ WCHAR*pUName=wszUName,*pDomain=0;
+ p=wszUName;
+ //if (*p==p[1]=='\\')pUName=(p+=2);else \ //Should we still split things up if the string starts with \\ ? Is it possible to use \\machine\user at all?
+ ++p;//Don't parse "\something", require at least one char before backslash "?[*\]something"
+ while(*p && *p!='\\')++p;
+ if (*p=='\\') {
+ pDomain=pUName;
+ pUName=p+1;*p=0;
+ }
+
+ TRACEF("MyRunAs:CreateProcessWithLogonW:%ws|%ws|%ws|%ws|\n",pUName,pDomain?pDomain:L"NO?DOMAIN",wszPwd,wszExec);
+ ec=(_CreateProcessWithLogonW(pUName,pDomain?pDomain:0,wszPwd,LOGON_WITH_PROFILE,0,wszExec,0,0,0,&siw,&pi)?NO_ERROR:GetLastError());
+ TRACEF("MyRunAs:CreateProcessWithLogonW: ret=%u\n",ec);
+ SecureZeroMemory(wszPwd,sizeof(wszPwd));//if (wszPwd) {volatile WCHAR*_p=wszPwd;for(;_p&&*_p;++_p)*_p=1;if (_p)*wszPwd=0;}//Burn password (And attempt to prevent compiler from removing it)
+ if (ec && ErrorIsLogonError(ec)) {
+ LPTSTR szMsg;
+ DWORD ret=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,0,ec,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR)&szMsg,0,0);
+ if (ret) {
+ ec=ERRAPP_TRYAGAIN;
+ MessageBox(hwnd,szMsg,0,MB_ICONWARNING);
+ LocalFree(szMsg);
+ }
+ else ec=GetLastError();
+ }
+ }
+ }
+ NSIS::MemFree(wszExec);
+ if (pi.hThread)CloseHandle(pi.hThread);
+ if (ERRAPP_TRYAGAIN==ec)break;
+ if (ec) {
+ SetLastError(ec);
+ exitcode=-1;
+ }
+ else {
+ pRADD->pSEI->hProcess=pi.hProcess;
+ exitcode=IDOK;
+ }
+ }
+ case IDCANCEL:
+ EndDialog(hwnd,exitcode);
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+DWORD MyRunAs(HINSTANCE hInstDll,SHELLEXECUTEINFO&sei) {
+ INT_PTR ec;
+ ASSERT(sei.cbSize>=sizeof(SHELLEXECUTEINFO) && hInstDll);
+ if (ec=DelayLoadDlls())return ec;
+ ASSERT(_CreateProcessWithLogonW && _GetUserName);
+ RUNASDLGDATA radd={0};
+ radd.pSEI=&sei;
+ ec=DialogBoxParam(hInstDll,MAKEINTRESOURCE(IDD_MYRUNAS),sei.hwnd,MyRunAsDlgProc,(LPARAM)&radd);
+ TRACEF("MyRunAs returned %d (%s|%s)\n",ec,sei.lpFile,sei.lpParameters);
+ switch(ec) {
+ case 0:
+ return ERROR_INVALID_HANDLE;//DialogBoxParam returns 0 on bad hwnd
+ case IDOK:
+ return NO_ERROR;
+ case IDCANCEL:
+ return ERROR_CANCELLED;
+ }
+ //TODO:BUGBUG: on vista, the last error seems to get lost, should probably put it in RUNASDLGDATA and always return IDOK
+ return GetLastError();
+}
+
+
+#ifdef BUILD_DBG
+// RunDll exports are __stdcall, we dont care about that for this debug export, rundll32.exe is able to handle this mistake
+extern "C" void __declspec(dllexport) __cdecl DBGRDMyRunAs(HWND hwnd,HINSTANCE hinst,LPTSTR lpCmdLine,int nCmdShow) {
+ SHELLEXECUTEINFO sei={sizeof(sei)};
+ sei.lpFile=_T("Notepad.exe");//sei.lpParameters=_T("param1");
+ TRACEF("ec=%d\n",MyRunAs(GetModuleHandle(_T("UAC.dll")),sei));
+}
+#endif
+
+#endif /* FEAT_CUSTOMRUNASDLG */
+
diff --git a/admin/win/nsi/nsis_uac/UAC Readme.html b/admin/win/nsi/nsis_uac/UAC Readme.html
new file mode 100755
index 000000000..1c8d9ed26
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/UAC Readme.html
@@ -0,0 +1,222 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html><head>
+<title>UAC plug-in readme</title>
+<script type="text/javascript">
+function NavGL(q){window.open("http://www.google.com/search?hl=en&btnI=I&num=2&q="+escape(q));return 0;}
+</script>
+<style type="text/css">
+html,body {background-color:#FFF; color:#000;}
+a:link, a:visited, a:active {color:#00F;}
+h2 {border-bottom:0.1em solid #000;}
+#docHdrHdln{text-align:center;}
+.importanttxt {color:#e00;}
+.code {font-family:monospace;}
+.nsisvar {color:#C00;}
+.str {color:#390}
+.inifile {background-color:#EEE;border:1px solid #000;padding:0.2em;}
+.inicomment {background-color:#f5f5c5;color:#555;}
+table.piexport {text-align:left;margin-bottom:1em;}
+table.piexport td {vertical-align:top;}
+table.piexport table.ret {padding:0;margin:0;border:0;}
+</style>
+</head><body>
+<h1 id="docHdrHdln">UAC plug-in</h1>
+
+
+<code><pre>
+Interactive User (MediumIL) Admin user(HighIL)
++++[Setup.exe]++++++++++++++ +++[Setup.exe]++++++++++++++
++ + + +
++ ***[.OnInit]************ + + ***[.OnInit]************ +
++ * UAC::RunElevated >---+-+------>+ * * +
++ * NSIS.Quit() * + + * * +
++ ************************ + + ***********||*********** +
++ + + || +
++ + + \/ +
++ ***[Sections]*********** + + ***[Sections]*********** +
++ * * + /--+-+-< UAC::Exec * +
++ ************************ + | + ************************ +
++ + | + +
++ Win32.CreateProcess() <-+----/ + +
++ + + +
+++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++
+</pre></code>
+
+
+<h2>Contents</h2>
+<ul>
+<li><a href="#exports">Plugin Functions</a>
+<li><a href="#lang">Language support</a>
+<li><a href="#knownissues">Known Issues</a>
+<li><a href="#glossary">Glossary</a>
+</ul>
+
+
+
+
+
+
+<a name="exports"><h2>Plugin Functions</h2></a><div class="CntSec"><p>
+Every function will try to emulate the basic NSIS instruction (of similar name) when UAC::RunElevated has not "succeeded" or running on a system that does not support elevation (Win9x/NT4)</p>
+
+<table class="piexport"><tr><th colspan=2>UAC::RunElevated</th></tr>
+<tr><td>Parameters:</td><td></td></tr>
+<tr><td>Returns:</td><td>
+ <table class="ret">
+ <tr><td><span class="nsisvar">$0</span></td><td>Win32 error code (0 on success, 1223 if user aborted elevation dialog, anything else should be treated as a fatal error)</td></tr>
+ <tr><td><span class="nsisvar">$1</span></td><td><span class="code">If <span class="nsisvar">$0</span>==0</span>:
+ <table class="ret">
+ <tr><td>0</td><td>UAC is not supported by the OS</td></tr>
+ <tr><td>1</td><td>Started a elevated child process, the current process should act like a wrapper (Call Quit without any further processing)</td></tr>
+ <tr><td>2</td><td>The process is already running @ HighIL (Member of admin group)</td></tr>
+ <tr><td>3</td><td>You should call RunElevated again (This can happen if a user without admin priv. is used in the runas dialog)</td></tr>
+ </table>
+ </td></tr>
+ <tr><td><span class="nsisvar">$2</span></td><td><span class="code">If <span class="nsisvar">$0</span>==0 && <span class="nsisvar">$1</span>==1</span>: ExitCode of the elevated fork process (The NSIS errlvl is also set)</td></tr>
+ <tr><td><span class="nsisvar">$3</span></td><td><span class="code">If <span class="nsisvar">$0</span>==0</span>: 1 if the user is a member of the admin group or 0 otherwise</td></tr>
+ </table></td></tr>
+<tr><td>Description:</td><td>Allows non-admin/UAC.LUA users to re-spawn the installer as another user and UAC.Admin users to elevate.</td></tr>
+</table>
+<!--table class="piexport"><tr><th colspan=2>UAC::RunElevatedAndProcessMessages <i style="font-size:smaller;">(Experimental)</i></th></tr>
+<tr><td>Parameters:</td><td></td></tr>
+<tr><td>Returns:</td><td><i>See UAC::RunElevated</i></td></tr>
+<tr><td>Description:</td><td>Version of UAC::RunElevated that can be called from a page</td></tr>
+</table-->
+
+<table class="piexport"><tr><th colspan=2>UAC::Unload</th></tr>
+<tr><td>Parameters:</td><td></td></tr>
+<tr><td>Returns:</td><td></td></tr>
+<tr><td>Description:</td><td>Cleanup, you must call this function in .OnInstFailed, .onUserAbort and .OnInstSuccess</td></tr>
+</table>
+
+<table class="piexport"><tr>
+<th colspan=2>UAC::Exec</th></tr>
+<tr><td>Parameters:</td><td>&lt;INT:ShowWindow&gt; &lt;STR:App&gt; &lt;STR:Parameters&gt; &lt;STR:WorkingDir&gt;</td></tr>
+<tr><td>Returns:</td><td>
+ <table class="ret">
+ <tr><td><span class="nsisvar">$0</span></td><td>Win32 error code, 0 on success (ErrorFlag is also set on error)</td></tr>
+ </table></td></tr>
+</table>
+<table class="piexport"><tr>
+<th colspan=2>UAC::ExecWait</th></tr>
+<tr><td>Parameters:</td><td>&lt;INT:ShowWindow&gt; &lt;STR:App&gt; &lt;STR:Parameters&gt; &lt;STR:WorkingDir&gt;</td></tr>
+<tr><td>Returns:</td><td>
+ <table class="ret">
+ <tr><td><span class="nsisvar">$0</span></td><td>Win32 error code, 0 on success (ErrorFlag is also set on error)</td></tr>
+ <tr><td><span class="nsisvar">$1</span></td><td>Exitcode of new process</td></tr>
+ </table></td></tr>
+</table>
+<table class="piexport"><tr>
+<th colspan=2>UAC::ShellExec</th></tr>
+<tr><td>Parameters:</td><td>&lt;STR:Verb&gt; &lt;INT:ShowWindow&gt; &lt;STR:App&gt; &lt;STR:Parameters&gt; &lt;STR:WorkingDir&gt;</td></tr>
+<tr><td>Returns:</td><td>
+ <table class="ret">
+ <tr><td><span class="nsisvar">$0</span></td><td>Win32 error code, 0 on success (ErrorFlag is also set on error)</td></tr>
+ </table></td></tr>
+</table>
+<table class="piexport"><tr>
+<th colspan=2>UAC::ShellExecWait</th></tr>
+<tr><td>Parameters:</td><td>&lt;STR:Verb&gt; &lt;INT:ShowWindow&gt; &lt;STR:App&gt; &lt;STR:Parameters&gt; &lt;STR:WorkingDir&gt;</td></tr>
+<tr><td>Returns:</td><td>
+ <table class="ret">
+ <tr><td><span class="nsisvar">$0</span></td><td>Win32 error code, 0 on success (ErrorFlag is also set on error)</td></tr>
+ <tr><td><span class="nsisvar">$1</span></td><td>Exitcode of new process</td></tr>
+ </table></td></tr>
+</table>
+
+<table class="piexport"><tr><th colspan=2>UAC::IsAdmin</th></tr>
+<tr><td>Parameters:</td><td></td></tr>
+<tr><td>Returns:</td><td><span class="nsisvar">$0</span> (BOOL) result</td></tr>
+<tr><td>Description:</td><td>Check current thread/process token for a non-deny admin group SID entry</td></tr>
+</table>
+
+<table class="piexport"><tr><th colspan=2>UAC::ExecCodeSegment</th></tr>
+<tr><td>Parameters:</td><td>&lt;INT:NSISFunctionAddress&gt;</td></tr>
+<tr><td>Returns:</td><td>[None] (ErrorFlag is set on error)</td></tr>
+<tr><td>Description:</td><td>Calls NSIS function in LUA/outer instance (If you use instructions that alter the UI or the stack/variables in the code segment (StrCpy,Push/Pop/Exch,DetailPrint etc.) they will affect the hidden wrapper installer and not "your" installer instance)</td></tr>
+</table>
+
+<table class="piexport"><tr><th colspan=2>UAC::StackPush</th></tr>
+<tr><td>Parameters:</td><td>&lt;STR:String&gt;</td></tr>
+<tr><td>Returns:</td><td>[None] (ErrorFlag is set on error)</td></tr>
+<tr><td>Description:</td><td>Push to outer instance stack (For use with UAC::ExecCodeSegment)</td></tr>
+</table>
+
+<table class="piexport"><tr><th colspan=2>UAC::GetOuterHwnd</th></tr>
+<tr><td>Parameters:</td><td></td></tr>
+<tr><td>Returns:</td><td><span class="nsisvar">$0</span> HWNDPARENT of outer instance</td></tr>
+<tr><td>Description:</td><td>For use with ${UAC.RunElevatedAndProcessMessages}</td></tr>
+</table>
+
+<table class="piexport"><tr><th colspan=2>UAC::SupportsUAC</th></tr>
+<tr><td>Parameters:</td><td></td></tr>
+<tr><td>Returns:</td><td><span class="nsisvar">$0</span> !=0 if supported</td></tr>
+<tr><td>Description:</td><td>Check if the OS supports UAC (And the user has UAC turned on) <span class="importanttxt">This function only tests if UAC is active, will return 0 on NT5 even though runas is implemented on those platforms, will also return 0 on NT6+ if UAC is off. You should only call this function during testing, NOT to determine if you can call UAC::RunElevated</span></td></tr>
+</table>
+
+<table class="piexport"><tr><th colspan=2>UAC::GetElevationType</th></tr>
+<tr><td>Parameters:</td><td></td></tr>
+<tr><td>Returns:</td><td>
+ <table class="ret">
+ <tr><td><span class="nsisvar">$0</span></td><td><a href="#" OnClick="return NavGL('TOKEN_ELEVATION_TYPE Enumeration')">TOKEN_ELEVATION_TYPE</a>:
+ <table class="ret">
+ <tr><td>0</td><td>Unsupported/Failed (ErrorFlag is also set)</td></tr>
+ <tr><td>1</td><td>TokenElevationTypeDefault: User is not using a split token (UAC disabled)</td></tr>
+ <tr><td>2</td><td>TokenElevationTypeFull: UAC enabled, the (current) process is elevated</td></tr>
+ <tr><td>3</td><td>TokenElevationTypeLimited: UAC enabled, the process is not elevated</td></tr>
+ </table>
+ </td></tr>
+ </table></td></tr>
+</table>
+
+</div>
+
+
+
+
+
+<a name="lang"><h2>Language support</h2></a><div class="CntSec">
+<p>If the plugin is built with FEAT_CUSTOMRUNASDLG_TRANSLATE (Enabled by default),
+you can extract a file named <span class="str">UAC.LNG</span> to <span class="nsisvar">$pluginsdir</span>.
+It is a ini file with the following sections:
+</p><pre class="inifile">
+[MyRunAsCfg]
+<span class="inicomment">;Set to 1 to disable the radio button</span>
+DisableCurrUserOpt=
+<span class="inicomment">;Set to 1 to hide the radio button</span>
+HideCurrUserOpt=
+
+[MyRunAsStrings]
+DlgTitle=Hello There!
+HelpText=Just do your thing!
+<span class="inicomment">;Label for current user radio button, %s is replaced with result of GetUserNameEx(NameSamCompatible,...)</span>
+OptCurrUser=Self service (%s)
+OptOtherUser=Run as someone:
+UserName=Who:
+Pwd=PIN:
+OK=Okey!
+Cancel=No Way</pre>
+</div>
+
+<a name="knownissues"><h2>Known Issues</h2></a><div class="CntSec">
+<ul>
+<li>UACPI.KI#1: DetailPrint in outer process is ignored
+<li>UACPI.KI#2: Elevation can fail if the installer is located on a remote share that requires authentication
+</ul>
+</div>
+
+
+<a name="glossary"><h2>Glossary</h2></a><div class="CntSec">
+<ul>
+<li>AAM: Admin Approval Mode
+<li>IL: Integrity level (Part of the new MIC/WIC security levels added to NT6)
+<li>LUA: Limited/Least-privilege User Account
+<li>MIC: <a href="http://en.wikipedia.org/wiki/Mandatory_Integrity_Control">Mandatory Integrity Controls</a> (Now known as WIC)
+<li>UAC: User Account Control (Part of the UAP umbrella)
+<li>UAP: User Account Protection
+<li>WIC: <a href="http://www.securityfocus.com/infocus/1887">Windows Integrity Controls</a>
+<li>Win32 error code: Standard windows error codes, ERROR_???
+</ul>
+</div>
+
+</body></html>
diff --git a/admin/win/nsi/nsis_uac/UAC.nsh b/admin/win/nsi/nsis_uac/UAC.nsh
new file mode 100755
index 000000000..b21e72ff4
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/UAC.nsh
@@ -0,0 +1,191 @@
+/*
+=======================
+UAC helper include file
+.......................
+
+Macros starting with UAC.I should only be called from the installer and vice versa for UAC.U macros.
+
+*/
+!ifndef UAC_HDR__INC
+!define UAC_HDR__INC
+!include LogicLib.nsh
+
+!define UAC.RunElevatedAndProcessMessages 'UAC::RunElevated '
+!define UAC.Unload 'UAC::Unload '
+!define UAC.StackPush 'UAC::StackPush '
+
+/*!macro _UAC.BuildOnInitElevationFunc _funcprefix
+Function ${_funcprefix}onInit
+!ifmacrodef
+FunctionEnd
+!macroend*/
+
+!macro _UAC.GenerateSimpleFunction _funcprefix _funcName _funcCode
+Function ${_funcprefix}${_funcName}
+${_funcCode}
+#messagebox mb_ok "${_funcprefix}${_funcName}"
+FunctionEnd
+!macroend
+
+!macro _UAC.TryDef _d _v
+!ifndef ${_d}
+!define ${_d} "${_v}"
+!endif
+!macroend
+
+!macro _UAC.InitStrings _modeprefix
+!insertmacro _UAC.TryDef UACSTR.UnDataFile "UAC.dat"
+!insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvWinErr "Unable to elevate , error $0"
+!ifNdef __UNINSTALL__
+ !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvAbortReqAdmin "This installer requires admin access, aborting!"
+ !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvMustTryAgain "This installer requires admin access, try again"
+ !else
+ !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvAbortReqAdmin "This uninstaller requires admin access, aborting!"
+ !insertmacro _UAC.TryDef UACSTR.${_modeprefix}ElvMustTryAgain "This uninstaller requires admin access, try again"
+ !endif
+!macroend
+
+!ifmacroNdef _UAC.GenerateUninstallerTango
+!macro _UAC.GenerateUninstallerTango UninstallerFileName
+!ifdef __GLOBAL__
+ !error "UAC: Needs to be called inside a function"
+ !endif
+!ifNdef __UNINSTALL__
+ !error "UAC: _UAC.GenerateUninstallerTango should only be called by uninstaller, see http://forums.winamp.com/showthread.php?threadid=280330"
+ !endif
+!ifNdef UAC_UNINSTALLERTANGOFORALLPLATFORMS
+ !include WinVer.nsh
+ !endif
+!insertmacro _UAC.InitStrings 'U.'
+ReadIniStr $0 "$ExeDir\${UACSTR.UnDataFile}" UAC "Un.Ready"
+${IF} $0 != 1
+!ifNdef UAC_UNINSTALLERTANGOFORALLPLATFORMS
+${AndIf} ${AtLeastWinVista}
+!endif
+ InitPluginsDir
+ WriteIniStr "$PluginsDir\${UACSTR.UnDataFile}" UAC "Un.Ready" 1
+ CopyFiles /SILENT "$EXEPATH" "$PluginsDir\${UninstallerFileName}"
+ StrCpy $0 ""
+ ${IfThen} ${Silent} ${|} StrCpy $0 "/S " ${|}
+ ExecWait '"$PluginsDir\${UninstallerFileName}" $0/NCRC _?=$INSTDIR' $0
+ SetErrorLevel $0
+ Quit
+ ${EndIf}
+!macroend
+!endif
+
+!ifmacroNdef _UAC.GenerateOnInitElevationCode
+!macro _UAC.GenerateOnInitElevationCode _modeprefix
+!ifndef __FUNCTION__
+ !error "UAC: Needs to be called inside a function"
+ !endif
+!insertmacro _UAC.InitStrings ${_modeprefix}
+!define _UAC.GOIECUniq L${__LINE__}
+UAC_Elevate_${_UAC.GOIECUniq}:
+UAC::RunElevated
+StrCmp 1223 $0 UAC_ElevationAborted_${_UAC.GOIECUniq} ; UAC dialog aborted by user?
+StrCmp 0 $0 0 UAC_Err_${_UAC.GOIECUniq} ; Error?
+StrCmp 1 $1 0 UAC_Success_${_UAC.GOIECUniq} ;Are we the real deal or just the wrapper?
+Quit
+UAC_Err_${_UAC.GOIECUniq}:
+MessageBox mb_iconstop "${UACSTR.${_modeprefix}ElvWinErr}"
+Abort
+UAC_ElevationAborted_${_UAC.GOIECUniq}:
+MessageBox mb_iconstop "${UACSTR.${_modeprefix}ElvAbortReqAdmin}"
+Abort
+UAC_Success_${_UAC.GOIECUniq}:
+# if $0==0 && $3==1, we are a member of the admin group (Any OS)
+# if $0==0 && $1==0, UAC not supported (Probably <NT6), run as normal?
+# if $0==0 && $1==3, we can try to elevate again
+StrCmp 1 $3 /*+4*/ UAC_Done_${_UAC.GOIECUniq} ;Admin?
+StrCmp 3 $1 0 UAC_ElevationAborted_${_UAC.GOIECUniq} ;Try again or abort?
+MessageBox mb_iconexclamation "${UACSTR.${_modeprefix}ElvMustTryAgain}" ;Inform user...
+goto UAC_Elevate_${_UAC.GOIECUniq} ;...lets try again
+UAC_Done_${_UAC.GOIECUniq}:
+!undef _UAC.GOIECUniq
+!macroend
+!endif
+
+!define UAC.I.Elevate.AdminOnly '!insertmacro UAC.I.Elevate.AdminOnly '
+!macro UAC.I.Elevate.AdminOnly
+!insertmacro _UAC.GenerateOnInitElevationCode 'I.'
+!macroend
+
+!define UAC.U.Elevate.AdminOnly '!insertmacro UAC.U.Elevate.AdminOnly '
+!macro UAC.U.Elevate.AdminOnly _UninstallerName
+!ifNdef UAC_DISABLEUNINSTALLERTANGO
+ !insertmacro _UAC.GenerateUninstallerTango "${_UninstallerName}"
+ !endif
+!insertmacro _UAC.GenerateOnInitElevationCode 'U.'
+!macroend
+
+!define UAC.AutoCodeUnload '!insertmacro UAC.AutoCodeUnload '
+!macro UAC.AutoCodeUnload _HasUninstaller
+!insertmacro _UAC.GenerateSimpleFunction "" .OnInstFailed '${UAC.Unload}'
+!insertmacro _UAC.GenerateSimpleFunction "" .OnInstSuccess '${UAC.Unload}'
+!ifNdef MUI_INCLUDED
+ !insertmacro _UAC.GenerateSimpleFunction "" .onUserAbort '${UAC.Unload}'
+ !else
+ !ifNdef MUI_CUSTOMFUNCTION_ABORT
+ !error "UAC: must call $$ {UAC.Unload} in MUI_CUSTOMFUNCTION_ABORT!"
+ !endif
+ !endif
+!if "${_HasUninstaller}" != ""
+ !insertmacro _UAC.GenerateSimpleFunction "un" .onUninstFailed '${UAC.Unload}'
+ !insertmacro _UAC.GenerateSimpleFunction "un" .onUninstSuccess '${UAC.Unload}'
+ !ifNdef MUI_INCLUDED
+ !insertmacro _UAC.GenerateSimpleFunction "un" .onUserAbort '${UAC.Unload}'
+ !else
+ !ifNdef MUI_CUSTOMFUNCTION_ABORT
+ !error "UAC: must call $$ {UAC.Unload} in MUI_CUSTOMFUNCTION_(UN)ABORT!"
+ !endif
+ !endif
+ !endif
+!macroend
+
+!define UAC.FastCallFunctionAsUser '!insertmacro UAC.FastCallFunctionAsUser '
+!macro UAC.FastCallFunctionAsUser _func _var
+GetFunctionAddress ${_var} ${_func}
+UAC::ExecCodeSegment ${_var}
+!macroend
+!define UAC.CallFunctionAsUser '!insertmacro UAC.CallFunctionAsUser '
+!macro UAC.CallFunctionAsUser _func
+push $R9
+!insertmacro UAC.FastCallFunctionAsUser ${_func} $R9
+pop $R9
+!macroend
+
+!define UAC.FastCallGetOuterInstanceHwndParent UAC::GetOuterHwnd
+!define UAC.GetOuterInstanceHwndParent '!insertmacro UAC.GetOuterInstanceHwndParent '
+!macro UAC.GetOuterInstanceHwndParent _var
+push $0
+${UAC.FastCallGetOuterInstanceHwndParent}
+Exch $0
+Pop ${_var}
+!macroend
+
+
+
+!macro _UAC.DumpEx _disp _f _fp _v
+${_f} ${_fp}
+DetailPrint "${_disp}=${_v}"
+!macroend
+!macro _UAC.Dump _f _fp _v
+!insertmacro _UAC.DumpEx `${_f}` `${_f}` `${_fp}` `${_v}`
+!macroend
+!macro _UAC.DbgDetailPrint
+push $0
+push $1
+System::Call /NoUnload "advapi32::GetUserName(t.r0,*i${NSIS_MAX_STRLEN})"
+System::Call "Kernel32::GetComputerName(t.r1,*i${NSIS_MAX_STRLEN})"
+DetailPrint "$1\$0"
+;!insertmacro _UAC.DumpEx "User" System::Call "advapi32::GetUserName(t.r0,*i${NSIS_MAX_STRLEN})" $0
+!insertmacro _UAC.DumpEx "CmdLine" "" "" "$CmdLine"
+!insertmacro _UAC.Dump UAC::IsAdmin "" $0
+!insertmacro _UAC.Dump UAC::SupportsUAC "" $0
+!insertmacro _UAC.Dump UAC::GetElevationType "" $0
+pop $1
+pop $0
+!macroend
+
+!endif /* ifndef UAC_HDR__INC */ \ No newline at end of file
diff --git a/admin/win/nsi/nsis_uac/UAC_AdminOnly.nsi b/admin/win/nsi/nsis_uac/UAC_AdminOnly.nsi
new file mode 100755
index 000000000..8668b9e95
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/UAC_AdminOnly.nsi
@@ -0,0 +1,62 @@
+RequestExecutionLevel user /* RequestExecutionLevel REQUIRED! */
+!define APPNAME "UAC_AdminOnly"
+Name "${APPNAME}"
+OutFile "${APPNAME}.exe"
+ShowInstDetails show
+
+!include UAC.nsh ;<<< New headerfile that does everything for you ;)
+!include LogicLib.nsh
+
+!define UACSTR.I.ElvAbortReqAdmin "This fancy app requires admin rights fool" ;custom error string, see _UAC.InitStrings macro in uac.nsh for more
+
+Function .OnInit
+${UAC.I.Elevate.AdminOnly}
+FunctionEnd
+
+Function .OnInstFailed
+${UAC.Unload}
+FunctionEnd
+Function .OnInstSuccess
+${UAC.Unload}
+FunctionEnd
+
+Function ExecCodeSegmentTest
+${If} "$1" != "666, the # of the beast"
+ MessageBox mb_ok "uh oh"
+ ${EndIf}
+FunctionEnd
+
+Section "Info"
+!insertmacro _UAC.DbgDetailPrint
+
+StrCpy $1 "666, the # of the beast"
+!insertmacro UAC.CallFunctionAsUser ExecCodeSegmentTest
+SectionEnd
+
+page InstFiles
+
+/* LEGACY CODE: (now uses magic code from UAC.nsh)
+Function .OnInit
+UAC_Elevate:
+UAC::RunElevated
+StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user?
+StrCmp 0 $0 0 UAC_Err ; Error?
+StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper?
+Quit
+UAC_Err:
+MessageBox mb_iconstop "Unable to elevate , error $0"
+Abort
+UAC_ElevationAborted:
+/*System::Call "user32::CreateWindowEx(i ${WS_EX_TRANSPARENT}|${WS_EX_LAYERED}, t 'Button', t 'blah', i 0, i 10, i 10, i 10, i 10, i 0, i 0, i 0) i .r0"
+ShowWindow $0 ${SW_SHOW}
+System::Call "user32::SetForegroundWindow(i r0) i."
+System::Call "user32::DestroyWindow(i r0) i."
+* /
+MessageBox mb_iconstop "This installer requires admin access, aborting!"
+Abort
+UAC_Success:
+StrCmp 1 $3 +4 ;Admin?
+StrCmp 3 $1 0 UAC_ElevationAborted ;Try again or abort?
+MessageBox mb_iconstop "This installer requires admin access, try again" ;Inform user...
+goto UAC_Elevate ;... and try again
+FunctionEnd*/ \ No newline at end of file
diff --git a/admin/win/nsi/nsis_uac/UAC_AllowLUA.nsi b/admin/win/nsi/nsis_uac/UAC_AllowLUA.nsi
new file mode 100755
index 000000000..e7b04824a
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/UAC_AllowLUA.nsi
@@ -0,0 +1,45 @@
+/*
+This sample will try to elevate, but it will also allow non admin users to continue if they click cancel in the elevation dialog
+*/
+
+RequestExecutionLevel user /* RequestExecutionLevel REQUIRED! */
+!define APPNAME "UAC_AllowLUA"
+Name "${APPNAME}"
+OutFile "${APPNAME}.exe"
+ShowInstDetails show
+!include UAC.nsh
+
+
+Function .OnInstFailed
+UAC::Unload ;Must call unload!
+FunctionEnd
+Function .OnInstSuccess
+UAC::Unload ;Must call unload!
+FunctionEnd
+
+Function .OnInit
+UAC::RunElevated
+;MessageBox mb_iconinformation "Debug: UAC::RunElevated: $\n0(Error)=$0 $\n1(UACMode)=$1 $\n2=$2 $\nadmin=$3$\n$\n$CmdLine"
+StrCmp 1223 $0 UAC_ElevationAborted ; UAC dialog aborted by user?
+StrCmp 0 $0 0 UAC_Err ; Error?
+StrCmp 1 $1 0 UAC_Success ;Are we the real deal or just the wrapper?
+Quit
+UAC_Err:
+MessageBox mb_iconstop "Unable to elevate , error $0"
+Abort
+UAC_ElevationAborted:
+# elevation was aborted, we still run as normal
+UAC_Success:
+FunctionEnd
+
+
+
+Section "Info"
+!insertmacro _UAC.DbgDetailPrint
+SectionEnd
+
+
+
+
+
+Page InstFiles
diff --git a/admin/win/nsi/nsis_uac/UAC_GetUserShellFolderPath.nsi b/admin/win/nsi/nsis_uac/UAC_GetUserShellFolderPath.nsi
new file mode 100755
index 000000000..2822efb9e
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/UAC_GetUserShellFolderPath.nsi
@@ -0,0 +1,30 @@
+RequestExecutionLevel user /* RequestExecutionLevel REQUIRED! */
+!define APPNAME "UAC_GetUserShellFolderPath"
+Name "${APPNAME}"
+OutFile "${APPNAME}.exe"
+ShowInstDetails show
+
+!include UAC.nsh
+!include LogicLib.nsh
+
+page instfiles
+
+Function .onInit
+${UAC.I.Elevate.AdminOnly}
+FunctionEnd
+
+!ifndef CSIDL_PERSONAL
+ !define CSIDL_PERSONAL 0x0005 ;My Documents
+!endif
+Section
+
+/*
+You can specify a fallback value in the 2nd parameter, it is used if the installer is not elevated
+or running on NT4/Win9x or on errors.
+If you just want to check for success, use "" as the 2nd parameter and compare $0 with ""
+*/
+UAC::GetShellFolderPath ${CSIDL_PERSONAL} $Documents
+DetailPrint MyDocs=$0
+
+
+SectionEnd
diff --git a/admin/win/nsi/nsis_uac/UAC_RealWorldFullyLoadedDualModeExample.nsi b/admin/win/nsi/nsis_uac/UAC_RealWorldFullyLoadedDualModeExample.nsi
new file mode 100755
index 000000000..6126edca7
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/UAC_RealWorldFullyLoadedDualModeExample.nsi
@@ -0,0 +1,242 @@
+/*
+This sample supports two modes, installing as a normal user (single user install) AND as admin (all users install)
+This sample uses the registry plugin, so you need to download that if you don't already have it
+*/
+
+!define APPNAME "UAC_RealWorldFullyLoadedDualMode"
+!define ELEVATIONTITLE "${APPNAME}: Elevate" ;displayed during elevation on our custom page
+!define SMSUBDIR $StartMenuFolder ;"${APPNAME}"
+!define UNINSTALLER_NAME "Uninstall ${APPNAME}.exe"
+!define UNINSTALLER_REGSECTION "${APPNAME}"
+!define RegPath.MSUninstall "Software\Microsoft\Windows\CurrentVersion\Uninstall"
+Name "${APPNAME}"
+OutFile "${APPNAME}.exe"
+ShowInstDetails show
+SetCompressor LZMA
+RequestExecutionLevel user /* RequestExecutionLevel REQUIRED! */
+!include MUI.nsh
+!include UAC.nsh
+!include LogicLib.nsh
+!include Registry.nsh
+!include nsDialogs.nsh ;for our custom page
+!include FileFunc.nsh ;we need to parse the command line
+
+!insertmacro GetParameters
+!insertmacro GetOptions
+
+!define MUI_CUSTOMFUNCTION_ABORT onAbort
+!define MUI_CUSTOMFUNCTION_GUIINIT onGuiInit
+!define MUI_COMPONENTSPAGE_NODESC
+!define MUI_FINISHPAGE_NOAUTOCLOSE
+!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\llama-blue.ico"
+!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\llama-blue.ico"
+!define MUI_WELCOMEPAGE_TITLE_3LINES
+
+var InstMode # 0: Single user, 1:All users, >1:elevated instance, perform page jump
+var hKey # Reg hive
+var hSelModeAdminRadio
+var StartMenuFolder
+
+!macro SetMode IsAdmin
+!if "${IsAdmin}" > 0
+ SetShellVarContext all
+ StrCpy $InstMode 1
+ StrCpy $hKey HKLM
+ !else
+ SetShellVarContext current
+ StrCpy $InstMode 0
+ StrCpy $hKey HKCU
+ !endif
+!macroend
+
+Function .OnInit
+!insertmacro SetMode 0
+${GetParameters} $R9
+${GetOptions} "$R9" UAC $0 ;look for special /UAC:???? parameter (sort of undocumented)
+${Unless} ${Errors}
+ UAC::IsAdmin
+ ${If} $0 < 1
+ SetErrorLevel 666 ;special return value for outer instance so it knows we did not have admin rights
+ Quit
+ ${EndIf}
+ !insertmacro SetMode 1
+ StrCpy $InstMode 2
+ ${EndIf}
+FunctionEnd
+
+Function onGuiInit
+${If} $InstMode >= 2
+ ${UAC.GetOuterInstanceHwndParent} $0
+ ${If} $0 <> 0
+ System::Call /NOUNLOAD "*(i,i,i,i)i.r1"
+ System::Call /NOUNLOAD 'user32::GetWindowRect(i $0,i r1)i.r2'
+ ${If} $2 <> 0
+ System::Call /NOUNLOAD "*$1(i.r2,i.r3)"
+ System::Call /NOUNLOAD 'user32::SetWindowPos(i $hwndParent,i0,ir2,ir3,i0,i0,i 4|1)'
+ ${EndIf}
+ ShowWindow $hwndParent ${SW_SHOW}
+ ShowWindow $0 ${SW_HIDE} ;hide outer instance installer window
+ System::Free $1
+ ${EndIf}
+ ${EndIf}
+FunctionEnd
+
+Function Un.OnInit
+!insertmacro SetMode 0
+ReadRegDWORD $0 HKLM "${RegPath.MSUninstall}\${UNINSTALLER_REGSECTION}" InstMode ;We saved the "mode" in the installer
+${If} $0 U> 0
+ ; If it was installed for all users, we have to be admin to uninstall it
+ ${UAC.U.Elevate.AdminOnly} "${UNINSTALLER_NAME}"
+ !insertmacro SetMode 1
+ ${EndIf}
+FunctionEnd
+
+Function onAbort
+${UAC.Unload}
+FunctionEnd
+
+${UAC.AutoCodeUnload} 1 ;Auto-generate .OnInstFailed and .OnInstSuccess functions
+
+!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipPageInElvModePreCB
+!insertmacro MUI_PAGE_WELCOME
+Page Custom ModeSelectionPageCreate ModeSelectionPageLeave
+!define MUI_PAGE_CUSTOMFUNCTION_PRE CmpntsPreCB
+!insertmacro MUI_PAGE_COMPONENTS
+!define MUI_PAGE_CUSTOMFUNCTION_PRE DirPreCB
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_STARTMENU 1 $StartMenuFolder
+!insertmacro MUI_PAGE_INSTFILES
+!define MUI_FINISHPAGE_TITLE_3LINES
+!define MUI_FINISHPAGE_RUN
+!define MUI_FINISHPAGE_RUN_FUNCTION FinishRunCB
+!insertmacro MUI_PAGE_FINISH
+!define MUI_WELCOMEPAGE_TITLE_3LINES
+!insertmacro MUI_UNPAGE_WELCOME
+!insertmacro MUI_UNPAGE_INSTFILES
+!insertmacro MUI_LANGUAGE "English"
+
+Function CmpntsPreCB
+GetDlgItem $0 $hwndparent 3
+${IfThen} $InstMode >= 1 ${|} EnableWindow $0 0 ${|} ;prevent user from going back and selecting single user so noobs don't end up installing as the wrong user
+FunctionEnd
+
+Function SkipPageInElvModePreCB
+${IfThen} $InstMode > 1 ${|} Abort ${|} ;skip this page so we get to the mode selection page
+FunctionEnd
+
+Function ModeSelectionPageCreate
+${If} $InstMode > 1
+ StrCpy $InstMode 1
+ Abort ;skip this page and contine where the "parent" would have gone
+ ${EndIf}
+!insertmacro MUI_HEADER_TEXT_PAGE "Select install type" "Blah blah blah blah"
+nsDialogs::Create /NOUNLOAD 1018
+Pop $0
+${NSD_CreateLabel} 0 20u 75% 20u "Blah blah blah blah select install type..."
+Pop $0
+System::Call "advapi32::GetUserName(t.r0, *i ${NSIS_MAX_STRLEN}r1) i.r2"
+${NSD_CreateRadioButton} 0 40u 75% 15u "Single User ($0)"
+Pop $0
+${IfThen} $InstMode U< 1 ${|} SendMessage $0 ${BM_SETCHECK} 1 0 ${|}
+${NSD_CreateRadioButton} 0 60u 75% 15u "All users"
+Pop $hSelModeAdminRadio
+${IfThen} $InstMode U> 0 ${|} SendMessage $hSelModeAdminRadio ${BM_SETCHECK} 1 0 ${|}
+nsDialogs::Show
+FunctionEnd
+
+!macro EnableCtrl dlg id state
+push $language
+GetDlgItem $language ${dlg} ${id}
+EnableWindow $language ${state}
+pop $language
+!macroend
+
+Function ModeSelectionPageLeave
+SendMessage $hSelModeAdminRadio ${BM_GETCHECK} 0 0 $9
+UAC::IsAdmin
+${If} $9 U> 0
+ ${If} $0 <> 0
+ !insertmacro SetMode 1
+ ${Else}
+ System::Call /NoUnload 'user32::GetWindowText(i $HwndParent,t.R1,i ${NSIS_MAX_STRLEN})' ;get original window title
+ System::Call /NoUnload 'user32::SetWindowText(i $HwndParent,t "${ELEVATIONTITLE}")' ;set out special title
+ StrCpy $2 "" ;reset special return, only gets set when sub process is executed, not when user cancels
+ !insertmacro EnableCtrl $HWNDParent 1 0 ;Disable next button, just because it looks good ;)
+ ${UAC.RunElevatedAndProcessMessages}
+ !insertmacro EnableCtrl $HWNDParent 1 1
+ System::Call 'user32::SetWindowText(i $HwndParent,t "$R1")' ;restore title
+ ${If} $2 = 666 ;our special return, the new process was not admin after all
+ MessageBox mb_iconExclamation "You need to login with an account that is a member of the admin group to continue..."
+ Abort
+ ${ElseIf} $0 = 1223 ;cancel
+ Abort
+ ${Else}
+ ${If} $0 <> 0
+ ${If} $0 = 1062
+ MessageBox mb_iconstop "Unable to elevate, Secondary Logon service not running!"
+ ${Else}
+ MessageBox mb_iconstop "Unable to elevate, error $0 ($1,$2,$3)"
+ ${EndIf}
+ Abort
+ ${EndIf}
+ ${EndIf}
+ Quit ;We now have a new process, the install will continue there, we have nothing left to do here
+ ${EndIf}
+${EndIf}
+FunctionEnd
+
+Function DirPreCB
+${If} $InstDir == ""
+ ${If} $InstMode U> 0
+ StrCpy $InstDir "$ProgramFiles\${APPNAME}"
+ ${Else}
+ StrCpy $InstDir "$APPDATA\${APPNAME}"
+ ${EndIf}
+ ${EndIf}
+FunctionEnd
+
+Function FinishRunCB
+UAC::Exec "" "Notepad.exe" "$Windir\Win.INI" "$InstDir"
+FunctionEnd
+
+Function CreateSMShortcuts
+StrCpy ${SMSUBDIR} $9 ;stupid sync
+CreateDirectory "$SMPrograms\${SMSUBDIR}"
+CreateShortcut "$SMPrograms\${SMSUBDIR}\${APPNAME}.lnk" "$Windir\Notepad.exe"
+CreateShortcut "$SMPrograms\${SMSUBDIR}\Uninstall ${APPNAME}.lnk" "$InstDir\${UNINSTALLER_NAME}"
+FunctionEnd
+Function CreateDeskShortcuts
+CreateShortcut "$Desktop\${APPNAME}.lnk" "$Windir\Notepad.exe"
+FunctionEnd
+
+Section "!Required files"
+SectionIn RO
+SetOutPath -
+!insertmacro _UAC.DbgDetailPrint ;some debug info, useful during testing
+;Install files here...
+WriteUninstaller "$InstDir\${UNINSTALLER_NAME}"
+${registry::Write} "$hKey\${RegPath.MSUninstall}\${UNINSTALLER_REGSECTION}" DisplayName "${APPNAME}" REG_SZ $0
+${registry::Write} "$hKey\${RegPath.MSUninstall}\${UNINSTALLER_REGSECTION}" UninstallString "$InstDir\${UNINSTALLER_NAME}" REG_SZ $0
+${registry::Write} "$hKey\${RegPath.MSUninstall}\${UNINSTALLER_REGSECTION}" InstMode $InstMode REG_DWORD $0
+${registry::Unload}
+SectionEnd
+
+Section "Startmenu Shortcuts"
+StrCpy $9 ${SMSUBDIR} ;this is stupid as hell, we need correct ${SMSUBDIR} in the outer process, this is the only way (plugins cannot enum "custom" var's AFAIK)
+${UAC.CallFunctionAsUser} CreateSMShortcuts
+SectionEnd
+Section "Desktop Shortcut"
+${UAC.CallFunctionAsUser} CreateDeskShortcuts
+SectionEnd
+
+Section Uninstall
+Delete "$InstDir\${UNINSTALLER_NAME}"
+Delete "$SMPrograms\${SMSUBDIR}\${APPNAME}.lnk"
+Delete "$SMPrograms\${SMSUBDIR}\Uninstall ${APPNAME}.lnk"
+RMDir "$SMPrograms\${SMSUBDIR}"
+Delete "$Desktop\${APPNAME}.lnk"
+
+RMDir "$InstDir"
+${registry::DeleteKey} "$hKey\${RegPath.MSUninstall}\${UNINSTALLER_REGSECTION}" $0
+${registry::Unload}
+SectionEnd \ No newline at end of file
diff --git a/admin/win/nsi/nsis_uac/UAC_Uninstaller.nsi b/admin/win/nsi/nsis_uac/UAC_Uninstaller.nsi
new file mode 100755
index 000000000..3cef1814c
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/UAC_Uninstaller.nsi
@@ -0,0 +1,49 @@
+/*
+This script was made in response to http://forums.winamp.com/showthread.php?threadid=280330
+It is a ugly hack and is mostly here just to have a solution right now.
+Hopefully, NSIS will add support for changing the RequestExecutionLevel of the uninstaller
+This code inspired the _UAC.GenerateUninstallerTango macro (called by ${UAC.U.Elevate.AdminOnly} unless you define UAC_DISABLEUNINSTALLERTANGO)
+*/
+
+RequestExecutionLevel user /* RequestExecutionLevel REQUIRED! */
+!define APPNAME "UAC_Uninstaller"
+Name "${APPNAME}"
+OutFile "${APPNAME}.exe"
+ShowInstDetails show
+!include LogicLib.nsh
+
+!define UNINSTALLER_UACDATA "uac.ini"
+!define UNINSTALLER_NAME "Uninstall FooBarBaz"
+
+Function un.onInit
+ReadIniStr $0 "$ExeDir\${UNINSTALLER_UACDATA}" UAC "Un.First"
+${IF} $0 != 1
+ ;SetSilent silent
+ InitPluginsDir
+ WriteIniStr "$PluginsDir\${UNINSTALLER_UACDATA}" UAC "Un.First" 1
+ CopyFiles /SILENT "$EXEPATH" "$PluginsDir\${UNINSTALLER_NAME}.exe"
+ StrCpy $0 ""
+ ${IfThen} ${Silent} ${|} StrCpy $0 "/S " ${|}
+ ExecWait '"$PluginsDir\${UNINSTALLER_NAME}.exe" $0/NCRC _?=$INSTDIR' $0
+ SetErrorLevel $0
+ Quit
+ ${EndIf}
+
+# UAC code goes here ...
+FunctionEnd
+
+Section
+WriteUninstaller "$exedir\${UNINSTALLER_NAME}.exe"
+SetAutoClose true
+DetailPrint "Uninstalling..."
+Sleep 1111
+Exec '"$exedir\${UNINSTALLER_NAME}.exe"'
+SectionEnd
+
+Section uninstall
+MessageBox mb_ok "My filename is: $EXEFILE"
+Delete "$instdir\${UNINSTALLER_NAME}.exe"
+Delete "$instdir\${APPNAME}.exe" ;delete generated installer aswell, this is just a sample script
+SectionEnd
+
+page InstFiles \ No newline at end of file
diff --git a/admin/win/nsi/nsis_uac/resource.h b/admin/win/nsi/nsis_uac/resource.h
new file mode 100755
index 000000000..933adac5b
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/resource.h
@@ -0,0 +1,24 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_MYRUNAS 101
+#define IDC_RUNASCURR 1000
+#define IDC_RUNASSPEC 1001
+#define IDC_SHICON 1002
+#define IDC_HELPTEXT 1003
+#define IDC_USERNAME 1004
+#define IDC_PASSWORD 1005
+#define IDC_LBLUSER 1007
+#define IDC_LBLPWD 1008
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1009
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/admin/win/nsi/nsis_uac/resource.rc b/admin/win/nsi/nsis_uac/resource.rc
new file mode 100755
index 000000000..3c90e6bea
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/resource.rc
@@ -0,0 +1,109 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include "uac.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_MYRUNAS DIALOG DISCARDABLE 0, 0, 250, 145
+STYLE DS_MODALFRAME | DS_NOIDLEMSG | DS_SETFOREGROUND | DS_FIXEDSYS |
+ DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "&OK",IDOK,132,122,50,14
+ PUSHBUTTON "Ca&ncel",IDCANCEL,188,122,50,14
+ ICON "",IDC_SHICON,7,7,20,20
+ LTEXT "",IDC_HELPTEXT,34,7,204,35
+ CONTROL "",IDC_RUNASCURR,"Button",BS_AUTORADIOBUTTON,20,49,218,
+ 10
+ CONTROL "",IDC_RUNASSPEC,"Button",BS_AUTORADIOBUTTON,20,65,218,
+ 10
+ LTEXT "&User name:",IDC_LBLUSER,20,84,42,16
+ EDITTEXT IDC_USERNAME,63,83,175,14,ES_AUTOHSCROLL
+ LTEXT "&Password:",IDC_LBLPWD,20,102,42,20
+ EDITTEXT IDC_PASSWORD,63,100,175,14,ES_PASSWORD | ES_AUTOHSCROLL
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_MYRUNAS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 238
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 136
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "#include ""uac.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/admin/win/nsi/nsis_uac/uac.cpp b/admin/win/nsi/nsis_uac/uac.cpp
new file mode 100755
index 000000000..6ccbc0424
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/uac.cpp
@@ -0,0 +1,1518 @@
+//Copyright (C) 2007 Anders Kjersem. Licensed under the zlib/libpng license, see License.txt for details.
+/*
+UAC plugin for NSIS
+===================
+Compiled with VC6+PlatformSDK (StdCall & MinimizeSize)
+
+
+Todo:
+-----
+¤GetCurrentDir in elevated parent and pass along to outer process for Exec* (or somekind of ipc to request it if workingdir param is empty)
+X¤Check if secondary logon service is running in SysElevationPresent() on NT5
+¤Use IsUserAnAdmin? MAKEINTRESOURCE(680) export on 2k (it even exists on NT4?) //http://forums.winamp.com/showthread.php?s=&threadid=195020
+¤AllowSetForegroundWindow
+¤Use RPC instead of WM_COPYDATA for IPC
+¤Autodetect "best" default admin user in MyRunAs
+¤Use ChangeWindowMessageFilter so we can get >WM_USER msg success feedback and possibly fill the log with detailprints
+¤Hide IPC window inside inner instance window? (Could this add unload problems?)
+¤CREATE_PRESERVE_CODE_AUTHZ_LEVEL? http://msdn2.microsoft.com/en-us/library/ms684863.aspx
+¤UpdateProcThreadAttribute?
+¤Consent UI on XP ?
+¤All langs in single file; [MyRunAsStrings]>LangSections != 0 then load strings from [langid] sections
+¤BroadcastSystemMessage to help with SetForeground
+¤UAC::StackPop
+
+
+Notes:
+------
+Primary integrity levels:
+Name SID RID
+Low Mandatory Level S-1-16-4096 0x1000
+Medium Mandatory Level S-1-16-8192 0x2000
+High Mandatory Level S-1-16-12288 0x3000
+System Mandatory Level S-1-16-16384 0x4000
+
+*/
+
+#define UAC_HACK_Clammerz //ugly messagebox focus hack for .onInit
+#define UAC_HACK_FGWND1 //super ugly fullscreen invisible window for focus tricks
+
+#define UAC_INITIMPORTS
+#include "UAC.h"
+#include <objbase.h>//CoInitialize
+#include "NSISUtil.h"
+using namespace NSIS;
+NSISUTIL_INIT();
+
+
+#define ERRAPP_BADIPCSRV (0x20000000|1)
+#define SW_INVALID ((WORD)-1)
+#define IPCTOUT_DEF (1000*3) //default timeout for IPC messages
+#define IPCTOUT_SHORT 1500
+#define IPCTOUT_LONG (IPCTOUT_DEF*2)
+
+enum _IPCSRVWNDMSG
+{
+ IPC_GETEXITCODE=WM_USER, //Get exit-code of the process spawned by the last call to ExecWait/ShellExecWait
+ IPC_ELEVATEAGAIN,
+ IPC_GETSRVPID, //Get PID of outer process
+ IPC_GETSRVHWND, //Get $HWNDParent of outer process
+ IPC_EXECCODESEGMENT, //wp:pos | lp:hwnd | returns ErrorCode+1
+ IPC_GETOUTERPROCESSTOKEN,
+#ifdef UAC_HACK_FGWND1
+ IPC_HACKFINDRUNAS,
+#endif
+};
+
+enum _COPYDATAID
+{
+ CDI_SHEXEC=666, //returns WindowsErrorCode+1
+ CDI_SYNCVAR,
+ CDI_STACKPUSH,
+};
+
+typedef struct
+{
+ UINT VarId;
+ NSISCH buf[ANYSIZE_ARRAY];
+} IPC_SYNCVAR;
+
+typedef struct
+{
+ HWND hwnd;
+ bool Wait;
+ bool UseCreateProcess;
+ WORD ShowMode;
+ NSISCH*strExec;
+ NSISCH*strParams;
+ NSISCH*strWorkDir;
+ NSISCH*strVerb;
+ NSISCH buf[ANYSIZE_ARRAY];
+} IPC_SHEXEC;
+
+
+typedef struct
+{
+ HINSTANCE hInstance;
+ HWND hSrvIPC;
+ BYTE DllRef;
+ bool UseIPC;
+ bool CheckedIPCParam;
+ UINT NSISStrLen;
+ //IPC Server stuff:
+ HANDLE hElevatedProcess;
+ HANDLE threadIPC;
+ DWORD LastWaitExitCode;//Exit code of process started from last call to ExecWait/ShellExecWait
+ NSIS::extra_parameters*pXParams;
+ bool ElevateAgain;
+ //DelayLoadedModules:
+ HMODULE hModAdvAPI;
+} GLOBALS;
+
+
+GLOBALS g = {0};
+
+
+void StopIPCSrv();
+DWORD _GetElevationType(TOKEN_ELEVATION_TYPE* pTokenElevType);
+bool GetIPCSrvWndFromParams(HWND&hwndOut);
+
+
+
+#if _MSC_VER >= 1400 //MSVC 2005 wants to pull in the CRT, let's try to help it out
+void* __cdecl memset(void*mem,int c,size_t len)
+{
+ char *p=(char*)mem;
+ while (len-- > 0){*p++=c;}
+ return mem;
+}
+#endif
+
+
+
+FORCEINLINE NSISCH* GetIPCWndClass() { return _T("NSISUACIPC"); }
+FORCEINLINE bool StrCmpI(LPCTSTR s1,LPCTSTR s2) {return 0==lstrcmpi(s1,s2);}
+LPTSTR StrNextChar(LPCTSTR Str) { return CharNext(Str); }
+bool StrContainsWhiteSpace(LPCTSTR s) { if (s) {while(*s && *s>_T(' '))s=StrNextChar(s);if (*s)return true;}return false; }
+
+DWORD GetSysVer(bool Major=true)
+{
+ OSVERSIONINFO ovi = { sizeof(ovi) };
+ if ( !GetVersionEx(&ovi) ) return 0;
+ return Major ? ovi.dwMajorVersion : ovi.dwMinorVersion;
+}
+#define GetOSVerMaj() (GetSysVer(true))
+#define GetOSVerMin() (GetSysVer(false))
+
+UINT_PTR StrToUInt(LPTSTR s,bool ForceHEX=false,BOOL*pFoundBadChar=0)
+{
+ UINT_PTR v=0;
+ BYTE base=ForceHEX?16:10;
+ if (pFoundBadChar)*pFoundBadChar=false;
+ if ( !ForceHEX && *s=='0' && ((*(s=StrNextChar(s)))&~0x20)=='X' && (s=StrNextChar(s)) )base=16;
+ for (TCHAR c=*s; c; c=*(s=StrNextChar(s)) )
+ {
+ if (c >= _T('0') && c <= _T('9')) c-='0';
+ else if (base==16 && (c & ~0x20) >= 'A' && (c & ~0x20) <= 'F') c=(c & 7) +9;
+ else
+ {
+ if (pFoundBadChar /*&& c!=' '*/)*pFoundBadChar=true;
+ break;
+ }
+ v*=base;v+=c;
+ }
+ return v;
+}
+
+LPTSTR FindExePathEnd(LPTSTR p)
+{
+ if ( *p=='"' && *(++p) )
+ {
+ while( *p && *p!='"' )p=StrNextChar(p);
+ if (*p)
+ p=StrNextChar(p);
+ else
+ return 0;
+ }
+ else
+ if ( *p!='/' )while( *p && *p!=' ' )p=StrNextChar(p);
+ return p;
+}
+
+
+#ifdef FEAT_MSRUNASDLGMODHACK
+HHOOK g_MSRunAsHook;
+void MSRunAsDlgMod_Unload(void*hook)
+{
+ if (hook)
+ {
+ //ASSERT(g_MSRunAsHook==hook);
+ UnhookWindowsHookEx((HHOOK)hook);
+ //g_MSRunAsHook=0;
+ }
+}
+LRESULT CALLBACK MSRunAsDlgMod_ShellProc(int nCode,WPARAM wp,LPARAM lp)
+{
+ CWPRETSTRUCT*pCWPS;
+ if (nCode >= 0 && (pCWPS=(CWPRETSTRUCT*)lp) && WM_INITDIALOG==pCWPS->message)
+ {
+ TCHAR buf[30];
+ GetClassName(pCWPS->hwnd,buf,COUNTOF(buf));
+ if (!lstrcmpi(buf,_T("#32770")))
+ {
+ const UINT IDC_USRSAFER=0x106,IDC_OTHERUSER=0x104,IDC_SYSCRED=0x105;
+ GetClassName(GetDlgItem(pCWPS->hwnd,IDC_SYSCRED),buf,COUNTOF(buf));
+ if (!lstrcmpi(buf,_T("SysCredential"))) //make sure this is the run as dialog
+ {
+ MySndDlgItemMsg(pCWPS->hwnd,IDC_USRSAFER,BM_SETCHECK,BST_UNCHECKED);
+ MySndDlgItemMsg(pCWPS->hwnd,IDC_OTHERUSER,BM_CLICK);
+ }
+ }
+ }
+ return CallNextHookEx(g_MSRunAsHook,nCode,wp,lp);
+}
+void* MSRunAsDlgMod_Init()
+{
+ if(GetOSVerMaj()!=5 || GetOSVerMin()<1)return NULL;//only XP/2003
+ return g_MSRunAsHook=SetWindowsHookEx(WH_CALLWNDPROCRET,MSRunAsDlgMod_ShellProc,0,GetCurrentThreadId());
+}
+#endif
+
+DWORD DllSelfAddRef()
+{
+ NSISCH buf[MAX_PATH*5];//Lets hope $pluginsdir is shorter than this, only special builds could break this
+ DWORD len=GetModuleFileName(g.hInstance,buf,MAX_PATH*5);
+ if ( len && len<MAX_PATH*5 && LoadLibrary(buf) )
+ {
+ if (!g.DllRef)g.DllRef++;
+ return NO_ERROR;
+ }
+ ASSERT(!"DllSelfAddRef failed!");
+ return ERROR_BUFFER_OVERFLOW;
+}
+
+FORCEINLINE DWORD MaintainDllSelfRef() //Call this from every exported function to prevent NSIS from unloading our plugin
+{
+ if(!g.CheckedIPCParam && !g.DllRef)
+ {
+ HWND hSrv;
+ g.CheckedIPCParam=true;
+ g.UseIPC=GetIPCSrvWndFromParams(hSrv);
+ if(g.UseIPC)
+ {
+ g.DllRef++;
+ g.hSrvIPC=hSrv;
+ }
+ }
+ return (g.DllRef)?DllSelfAddRef():NO_ERROR;
+}
+
+
+DWORD SendIPCMsg(UINT Msg,WPARAM wp,LPARAM lp,DWORD_PTR&MsgRet,DWORD tout=IPCTOUT_DEF,const HWND hIPCSrv=g.hSrvIPC)
+{
+ if (tout==INFINITE) //BUGFIX: SendMessageTimeout(...,INFINITE,...) seems to be broken, SendMessageTimeout(...,SMTO_NORMAL,0,..) seems to work but why take the chance
+ {
+ MsgRet=SendMessage(hIPCSrv,Msg,wp,lp);
+ return NO_ERROR;
+ }
+ if ( SendMessageTimeout(hIPCSrv,Msg,wp,lp,SMTO_NORMAL,tout,&MsgRet) )return NO_ERROR;
+ return (tout=GetLastError()) ? tout : ERROR_TIMEOUT;
+}
+
+void _Unload()
+{
+ StopIPCSrv();
+ if (g.DllRef)
+ {
+ g.DllRef=0;
+ FreeLibrary(g.hInstance);
+ //Why bother?> FreeLibrary(g.hModAdvAPI);
+ }
+}
+
+DWORD DelayLoadGetProcAddr(void**ppProc,HMODULE hLib,LPCSTR Export)
+{
+ ASSERT(ppProc && hLib && Export);
+ if (!*ppProc)
+ {
+ *ppProc=GetProcAddress(hLib,Export);
+ if (!*ppProc)return GetLastError();
+ }
+ return NO_ERROR;
+}
+
+DWORD DelayLoadDlls()
+{
+
+#ifdef UNICODE
+# define __DLD_FUNCSUFFIX "W"
+# else
+# define __DLD_FUNCSUFFIX "A"
+# endif
+
+ if (!g.hModAdvAPI) //using g.hModAdvAPI to test if this is the first time we have been called
+ {
+ struct
+ {
+ HMODULE*pMod;
+ LPCSTR DllName;//NOTE: Always using ANSI strings to save a couple of bytes
+ }
+ dld[]=
+ {
+ {&g.hModAdvAPI,"AdvAPI32"},
+ {0}
+ };
+ DWORD ec;
+ UINT o;
+
+ for (o=0; dld[o].pMod; ++o)
+ if ( !(*dld[o].pMod=LoadLibraryA(dld[o].DllName)) )
+ return GetLastError();
+
+ struct
+ {
+ HMODULE hMod;
+ void**ppProc;
+ LPCSTR Export;
+ bool Optional;
+ }
+ dldprocs[]=
+ {
+ {GetModuleHandle(_T("USER32")),(void**)&_AllowSetForegroundWindow,"AllowSetForegroundWindow",true},
+ {g.hModAdvAPI,(void**)&_OpenProcessToken, "OpenProcessToken"},
+ {g.hModAdvAPI,(void**)&_OpenThreadToken, "OpenThreadToken"},
+ {g.hModAdvAPI,(void**)&_GetTokenInformation, "GetTokenInformation"},
+ {g.hModAdvAPI,(void**)&_AllocateAndInitializeSid, "AllocateAndInitializeSid"},
+ {g.hModAdvAPI,(void**)&_FreeSid, "FreeSid"},
+ {g.hModAdvAPI,(void**)&_EqualSid, "EqualSid"},
+ {g.hModAdvAPI,(void**)&_CheckTokenMembership, "CheckTokenMembership",true},
+ #ifdef FEAT_CUSTOMRUNASDLG
+ {g.hModAdvAPI,(void**)&_GetUserName, "GetUserName" __DLD_FUNCSUFFIX},
+ {g.hModAdvAPI,(void**)&_CreateProcessWithLogonW,"CreateProcessWithLogonW",true},
+ {LoadLibraryA("SECUR32"),(void**)&_GetUserNameEx,"GetUserNameEx" __DLD_FUNCSUFFIX,true},//We never free this library
+ #endif
+ {0}
+ };
+//#undef __DLD_FUNCSUFFIX
+ for (o=0; dldprocs[o].hMod; ++o)
+ if (ec=DelayLoadGetProcAddr(dldprocs[o].ppProc,dldprocs[o].hMod,dldprocs[o].Export) && !dldprocs[o].Optional)
+ {
+ TRACEF("DelayLoadDlls failed to find %s in %X\n",dldprocs[o].Export,dldprocs[o].hMod);
+ return ec;
+ }
+ }
+ return NO_ERROR;
+}
+
+void AllowOuterInstanceWindowFocus()
+{
+ if (g.UseIPC)
+ {
+ DWORD_PTR MsgRet;
+ if (!SendIPCMsg(IPC_GETSRVPID,0,0,MsgRet,IPCTOUT_SHORT) && MsgRet && _AllowSetForegroundWindow)_AllowSetForegroundWindow(MsgRet);
+ }
+}
+
+DWORD SyncVars(HWND hwndNSIS)
+{
+ DWORD i,ec=NO_ERROR;
+ IPC_SYNCVAR*pSV=0;
+ if (!g.UseIPC)return NO_ERROR;
+ g.NSISStrLen=NSIS::StrSize;
+ TRACEF("SyncVars: g.NSISStrLen=%d\n",g.NSISStrLen);ASSERT(g.NSISStrLen>10);
+ DWORD cbStruct=FIELD_OFFSET(IPC_SYNCVAR,buf[g.NSISStrLen+1]);
+ pSV=(IPC_SYNCVAR*)MemAlloc(cbStruct);
+ if (!pSV)
+ goto die_GLE;
+ else
+ {
+ COPYDATASTRUCT cds={CDI_SYNCVAR,cbStruct,pSV};
+ for (i=0;i<__INST_LAST && !ec;++i)
+ {
+ pSV->VarId=i;
+ lstrcpyn(pSV->buf,GetVar(i),g.NSISStrLen);
+ DWORD MsgRet;//TRACEF("SyncVars: (%d)%s|\n",i,pSV->buf);
+ if (!(ec=SendIPCMsg(WM_COPYDATA,(WPARAM)hwndNSIS,(LPARAM)&cds,MsgRet,3000 )))ec=MsgRet-1;
+ }
+ }
+ return ec;
+die_GLE:
+ return GetLastError();
+}
+
+DWORD _Exec(HWND hwnd,NSISCH*Verb,NSISCH*Exec,NSISCH*Params,NSISCH*WorkDir,WORD ShowWnd,bool Wait,bool UseCreateProcess)
+{
+ DWORD ec;
+ NSISCH*buf=0;
+ SHELLEXECUTEINFO sei={sizeof(SHELLEXECUTEINFO)};
+ sei.hwnd =hwnd;
+ sei.nShow =(ShowWnd!=SW_INVALID)?ShowWnd:SW_NORMAL;
+ sei.fMask =SEE_MASK_FLAG_DDEWAIT;
+ sei.lpFile =(Exec&&*Exec) ?Exec:0;
+ sei.lpParameters=(Params&&*Params) ?Params:0;
+ sei.lpDirectory =(WorkDir&&*WorkDir) ?WorkDir:0;
+ sei.lpVerb =(Verb&&*Verb) ?Verb:0;
+ TRACEF("_Exec:%X|%s|%s|%s|wait=%d useCreateProc=%d ShowWnd=%d useShowWnd=%d\n",hwnd,Exec,Params,WorkDir,Wait,UseCreateProcess,ShowWnd,ShowWnd!=SW_INVALID);
+ if (UseCreateProcess)
+ {
+ STARTUPINFO si={sizeof(STARTUPINFO)};
+ if (ShowWnd != SW_INVALID)
+ {
+ si.dwFlags|=STARTF_USESHOWWINDOW;
+ si.wShowWindow=sei.nShow;
+ }
+ PROCESS_INFORMATION pi;
+ const NSISCH*Q=( (*Exec!='"') && (*Params) && StrContainsWhiteSpace(Exec)) ? _T("\"") : _T("");//Add extra quotes to program part of command-line?
+ const DWORD len= ((*Q)?2:0) + lstrlen(Exec) + 1 + lstrlen(Params) + 1;
+ buf=(NSISCH*)NSIS::MemAlloc(len*sizeof(NSISCH));
+ if (!buf)return ERROR_OUTOFMEMORY;
+ //Build string for CreateProcess, "[Q]<Exec>[Q][Space]<Params>"
+ wsprintf(buf,_T("%s%s%s%s%s"),Q,Exec,Q,((*Params)?_T(" "):_T("")),Params);
+ TRACEF("_Exec: calling CreateProcess>%s< in >%s< addedQ=%d show=%u\n",buf,sei.lpDirectory,*Q,sei.nShow);
+ if ( !CreateProcess(0,buf,0,0,false,0,0,sei.lpDirectory,&si,&pi) ) goto die_GLE;
+ CloseHandle(pi.hThread);
+ sei.hProcess=pi.hProcess;
+ }
+ else
+ {
+ sei.fMask|=SEE_MASK_NOCLOSEPROCESS;
+ TRACEF("_Exec: calling ShellExecuteEx...\n");
+ if ( !ShellExecuteEx(&sei) )goto die_GLE;
+ }
+ if (Wait)
+ {
+ WaitForSingleObject(sei.hProcess,INFINITE);
+ GetExitCodeProcess(sei.hProcess,&g.LastWaitExitCode);
+ }
+ else WaitForInputIdle(sei.hProcess,1500);//wait a little bit so the finish page window does not go away too fast and cause focus problems
+
+ CloseHandle(sei.hProcess);
+ ec=NO_ERROR;
+ret:
+ if (buf)NSIS::MemFree(buf);
+ return ec;
+die_GLE:
+ ec=GetLastError();
+ TRACEF("_Exec>%s failed with error %u (%s)\n",UseCreateProcess?"CreateProcess":"ShExec",ec,buf);
+ goto ret;
+}
+
+WORD GetShowWndCmdFromStr(NSISCH*s)
+{
+ //NOTE: Little used modes are still supported, just not with strings, you must use the actual number or ${SW_xx} defines from WinMessages.h
+ struct {NSISCH*id;WORD cmd;} swcm[] = {
+ {_T("SW_HIDE"), SW_HIDE},
+ {_T("SW_SHOW"), SW_SHOW},
+ {_T("SW_RESTORE"), SW_RESTORE},
+ {_T("SW_MAXIMIZE"), SW_MAXIMIZE},
+ {_T("SW_MINIMIZE"), SW_MINIMIZE},
+ // {_T("SW_MAX"), SW_MAXIMIZE},
+ // {_T("SW_MIN"), SW_MINIMIZE},
+ {_T("SW_SHOWNORMAL"), SW_SHOWNORMAL},
+ //{_T("SW_NORMAL"), SW_NORMAL},
+ //{_T("SW_SHOWMINIMIZED"), SW_SHOWMINIMIZED},
+ //{_T("SW_SHOWMAXIMIZED"), SW_SHOWMAXIMIZED},
+ //{_T("SW_SHOWNOACTIVATE"), SW_SHOWNOACTIVATE},
+ //{_T("SW_SHOWNA"), SW_SHOWNA},
+ //{_T("SW_SHOWMINNOACTIVE"), SW_SHOWMINNOACTIVE},
+ //{_T("SW_SHOWDEFAULT"), SW_SHOWDEFAULT},
+ //{_T("SW_FORCEMINIMIZE"), SW_FORCEMINIMIZE},
+ {0}
+ };
+ for (int i=0; swcm[i].id; ++i) if (StrCmpI(s,swcm[i].id)) return swcm[i].cmd;
+ return SW_INVALID;
+}
+
+#define HasIPCServer() (g.UseIPC!=NULL)
+
+void HandleExecExport(bool CreateProc,bool Wait,HWND&hwndNSIS,int&StrSize,NSISCH*&Vars,stack_t**&StackTop,NSIS::extra_parameters*pXParams)
+{
+ DWORD ec=NO_ERROR,ForkExitCode=ERROR_INVALID_FUNCTION;
+ UINT cch=0,cbStruct;
+ WORD ShowWnd;
+ IPC_SHEXEC*pISE=0;
+ stack_t* const pSIVerb=CreateProc?0:StackPop();//Only ShellExec supports verb's
+ stack_t* const pSIShowWnd =StackPop();
+ stack_t* const pSIExec =StackPop();
+ stack_t* const pSIParams =StackPop();
+ stack_t* const pSIWorkDir =StackPop();
+
+ if (ec=MaintainDllSelfRef())goto ret;
+ if (!pSIExec || !pSIParams || !pSIWorkDir || !pSIShowWnd || (!pSIVerb && !CreateProc))
+ {
+ TRACE("If you see this you probably forgot that all parameters are required!\n");
+ ec=ERROR_INVALID_PARAMETER;
+ goto ret;
+ }
+ ShowWnd=GetShowWndCmdFromStr(pSIShowWnd->text);
+ if (ShowWnd==SW_INVALID && *pSIShowWnd->text)
+ {
+ BOOL BadCh;
+ ShowWnd=StrToUInt(pSIShowWnd->text,false,&BadCh);
+ if (BadCh)ShowWnd=SW_INVALID;
+ }
+ TRACEF("HandleExecExport: ipc=%X (%X)\n",g.UseIPC,g.hSrvIPC);
+ SyncVars(hwndNSIS);
+ if (!g.UseIPC) //No IPC Server, we are not elevated with UAC
+ {
+ ec=_Exec(hwndNSIS,pSIVerb?pSIVerb->text:0,pSIExec->text,pSIParams->text,pSIWorkDir->text,ShowWnd,Wait,CreateProc);
+ if (Wait)ForkExitCode=g.LastWaitExitCode;
+ goto ret;
+ }
+ cch+=lstrlen(pSIExec->text)+1;
+ cch+=lstrlen(pSIParams->text)+1;
+ cch+=lstrlen(pSIWorkDir->text)+1;
+ if (pSIVerb)cch+=lstrlen(pSIVerb->text)+1;
+ cbStruct=FIELD_OFFSET( IPC_SHEXEC, buf[cch*sizeof(TCHAR)] );
+ pISE=(IPC_SHEXEC*)NSIS::MemAlloc(cbStruct);
+ if (!pISE)ec=GetLastError();
+ if (!ec)
+ {
+ DWORD_PTR MsgRet;
+ pISE->hwnd =hwndNSIS;
+ pISE->Wait =Wait;
+ pISE->ShowMode =ShowWnd;
+ pISE->UseCreateProcess=CreateProc;
+ //Just offsets at this point
+ pISE->strExec =(NSISCH*)0;
+ pISE->strParams =(NSISCH*)(lstrlen(pSIExec->text) +pISE->strExec+1);
+ pISE->strWorkDir=(NSISCH*)(lstrlen(pSIParams->text) +pISE->strParams+1);
+ pISE->strVerb= (NSISCH*)(lstrlen(pSIWorkDir->text)+pISE->strWorkDir+1);
+ lstrcpy(pISE->buf,pSIExec->text);
+ lstrcpy(&pISE->buf[(DWORD_PTR)pISE->strParams], pSIParams->text);
+ lstrcpy(&pISE->buf[(DWORD_PTR)pISE->strWorkDir],pSIWorkDir->text);
+ if (pSIVerb)lstrcpy(&pISE->buf[(DWORD_PTR)pISE->strVerb], pSIVerb->text);
+ COPYDATASTRUCT cds;
+ cds.dwData=CDI_SHEXEC;
+ cds.cbData=cbStruct;
+ cds.lpData=pISE;
+ AllowOuterInstanceWindowFocus();
+ if (!(ec=SendIPCMsg(WM_COPYDATA,(WPARAM)hwndNSIS,(LPARAM)&cds,MsgRet,Wait?(INFINITE):(IPCTOUT_LONG) )))ec=MsgRet-1;
+ TRACEF("HandleExecExport: IPC returned %X, ec=%d\n",MsgRet,ec);
+ if (Wait && NO_ERROR==ec)
+ {
+ ec=SendIPCMsg(IPC_GETEXITCODE,0,0,ForkExitCode);
+ TRACEF("HandleExecExport(Wait): Spawned process exit code=%d",ForkExitCode);
+ }
+ }
+ret:
+ NSIS::MemFree(pISE);
+ StackFreeItem(pSIShowWnd);
+ StackFreeItem(pSIExec);
+ StackFreeItem(pSIParams);
+ StackFreeItem(pSIWorkDir);
+ StackFreeItem(pSIVerb);
+ SetVarUINT(INST_0,ec);
+ if (ec)SetErrorFlag(pXParams);
+ if (Wait)SetVarUINT(INST_1,ForkExitCode);
+}
+
+
+bool _SupportsUAC(bool VersionTestOnly=false)
+{
+ TOKEN_ELEVATION_TYPE tet;
+ OSVERSIONINFO ovi={sizeof(ovi)};
+ if (!GetVersionEx(&ovi))
+ {
+ ASSERT(!"_SupportsUAC>GetVersionEx");
+ return false;
+ }
+ if (VersionTestOnly)return ovi.dwMajorVersion>=6;
+ if (ovi.dwMajorVersion>=6 && _GetElevationType(&tet)==NO_ERROR)
+ {
+ const bool ret=tet!=TokenElevationTypeDefault && tet!=NULL;
+ TRACEF("_SupportsUAC tet=%d, returning %d\n",tet,ret);
+ return ret;
+ }
+ DBGONLY(TRACEF("_SupportsUAC returning false! ver=%d _GetElevationType.ret=%u\n",ovi.dwMajorVersion,_GetElevationType(&tet)));
+ return false;
+}
+
+DWORD _GetElevationType(TOKEN_ELEVATION_TYPE*pTokenElevType)
+{
+ DWORD ec=ERROR_ACCESS_DENIED;
+ HANDLE hToken=0;
+ DWORD RetLen;
+ if (!pTokenElevType)return ERROR_INVALID_PARAMETER;
+ if (ec=DelayLoadDlls())return ec;
+ *pTokenElevType=(TOKEN_ELEVATION_TYPE)NULL;
+ if (!_SupportsUAC(true))return NO_ERROR;
+ if (!_OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hToken))goto dieLastErr;
+ if (!_GetTokenInformation(hToken,(_TOKEN_INFORMATION_CLASS)TokenElevationType,pTokenElevType,sizeof(TOKEN_ELEVATION_TYPE),&RetLen))goto dieLastErr;
+ SetLastError(NO_ERROR);
+dieLastErr:
+ ec=GetLastError();
+ CloseHandle(hToken);
+ TRACEF("_GetElevationType ec=%u type=%d\n",ec,*pTokenElevType);
+ return ec;
+}
+
+
+bool _IsUACEnabled()
+{
+ HKEY hKey;
+ bool ret=false;
+ if (GetSysVer()>=6 && NO_ERROR==RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"),0,KEY_READ,&hKey))
+ {
+ //Check must be !=0, see http://codereview.chromium.org/3110 & http://src.chromium.org/viewvc/chrome?view=rev&revision=2330
+ //Apparently, Vista treats !=0 as UAC on, and some machines have EnableLUA=2 !!
+ DWORD val,type,size=sizeof(DWORD);
+ if (NO_ERROR==RegQueryValueEx(hKey,_T("EnableLUA"),0,&type,(LPBYTE)&val,&size) && type==REG_DWORD && val!=0) ret=true;
+ RegCloseKey(hKey);
+ }
+ return ret;
+}
+
+bool SysQuery_IsServiceRunning(LPCTSTR servicename)
+{
+ bool retval=false;
+ SC_HANDLE scdbh=NULL,hsvc;
+ scdbh=OpenSCManager(NULL,NULL,GENERIC_READ);
+ if (scdbh)
+ {
+ if (hsvc=OpenService(scdbh,servicename,SERVICE_QUERY_STATUS))
+ {
+ SERVICE_STATUS ss;
+ if (QueryServiceStatus(hsvc,&ss))retval=(ss.dwCurrentState==SERVICE_RUNNING);
+ CloseServiceHandle(hsvc);
+ }
+ }
+ CloseServiceHandle(scdbh);
+ return retval;
+}
+
+inline bool SysNT5IsSecondaryLogonSvcRunning()
+{
+ return SysQuery_IsServiceRunning(_T("seclogon"));
+}
+
+bool SysElevationPresent() //Will return false on Vista if UAC is off
+{
+ const DWORD vmaj=GetSysVer();
+ ASSERT(vmaj<=6 && vmaj>=4);
+ if (vmaj==5) return true; //TODO:Check if secondary logon service is running?
+ if (vmaj>=6) return _IsUACEnabled();
+ return false;
+}
+
+FORCEINLINE bool SysSupportsRunAs()
+{
+ return GetSysVer()>=5;
+}
+
+
+
+
+
+bool _IsAdmin()
+{
+
+#ifdef BUILD_XPTEST
+ static int _dbgOld=-1;
+ unsigned _dbg=(unsigned)FindExePathEnd(GetCommandLine());
+ if (_dbgOld==-1){_dbg=(_dbg && *((TCHAR*)_dbg))?MessageBoxA(0,"Debug: Pretend to be admin?",GetCommandLine(),MB_YESNOCANCEL):IDCANCEL;} else _dbg=_dbgOld;_dbgOld=_dbg;TRACEF("_IsAdmin=%d|%d\n",_dbg,_dbg==IDYES);
+ if (_dbg!=IDCANCEL){SetLastError(0);return _dbg==IDYES;}
+#endif
+
+ BOOL isAdmin=false;
+ DWORD ec;
+ OSVERSIONINFO ovi={sizeof(ovi)};
+ if (!GetVersionEx(&ovi))return false;
+ if (VER_PLATFORM_WIN32_NT != ovi.dwPlatformId) //Not NT
+ {
+ SetLastError(NO_ERROR);
+ return true;
+ }
+ if (ec=DelayLoadDlls())
+ {
+ TRACEF("DelayLoadDlls failed in _IsAdmin() with err x%X\n",ec);
+ SetLastError(ec);
+ return false;
+ }
+
+ ASSERT(_OpenThreadToken && _OpenProcessToken && _AllocateAndInitializeSid && _EqualSid && _FreeSid);
+ HANDLE hToken;
+ if (_OpenThreadToken(GetCurrentThread(),TOKEN_QUERY,FALSE,&hToken) || _OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hToken))
+ {
+ SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
+ PSID psid=0;
+ if (_AllocateAndInitializeSid(&SystemSidAuthority,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,0,&psid))
+ {
+ if (_CheckTokenMembership)
+ {
+ if (!_CheckTokenMembership(0,psid,&isAdmin))isAdmin=false;
+ }
+ else
+ {
+ DWORD cbTokenGrps;
+ if (!_GetTokenInformation(hToken,TokenGroups,0,0,&cbTokenGrps)&&GetLastError()==ERROR_INSUFFICIENT_BUFFER)
+ {
+ TOKEN_GROUPS*ptg=0;
+ if (ptg=(TOKEN_GROUPS*)NSIS::MemAlloc(cbTokenGrps))
+ {
+ if (_GetTokenInformation(hToken,TokenGroups,ptg,cbTokenGrps,&cbTokenGrps))
+ {
+ for (UINT i=0; i<ptg->GroupCount;i++)
+ {
+ if (_EqualSid(ptg->Groups[i].Sid,psid))isAdmin=true;
+ }
+ }
+ NSIS::MemFree(ptg);
+ }
+ }
+ }
+ _FreeSid(psid);
+ }
+ CloseHandle(hToken);
+ }
+ if (isAdmin) //UAC Admin with split token check
+ {
+ if (_SupportsUAC())
+ {
+ TOKEN_ELEVATION_TYPE tet;
+ if (_GetElevationType(&tet) || tet==TokenElevationTypeLimited)isAdmin=false;
+ }
+ else SetLastError(NO_ERROR);
+ }
+ return FALSE != isAdmin;
+}
+
+
+LRESULT CALLBACK IPCSrvWndProc(HWND hwnd,UINT uMsg,WPARAM wp,LPARAM lp)
+{
+ switch(uMsg)
+ {
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+ case WM_CLOSE:
+ return DestroyWindow(hwnd);
+ case WM_COPYDATA:
+ if (lp)
+ {
+ const COPYDATASTRUCT*pCDS=(COPYDATASTRUCT*)lp;
+ if (pCDS->dwData==CDI_SHEXEC && pCDS->lpData)
+ {
+ if ( pCDS->cbData < sizeof(IPC_SHEXEC) )break;
+ g.LastWaitExitCode=ERROR_INVALID_FUNCTION;
+ IPC_SHEXEC& ise=*((IPC_SHEXEC*)pCDS->lpData);
+ SetForegroundWindow(ise.hwnd);
+ DWORD ec=_Exec(
+ ise.hwnd,
+ &ise.buf[(DWORD_PTR)ise.strVerb],
+ &ise.buf[(DWORD_PTR)ise.strExec],
+ &ise.buf[(DWORD_PTR)ise.strParams],
+ &ise.buf[(DWORD_PTR)ise.strWorkDir],
+ ise.ShowMode,ise.Wait,ise.UseCreateProcess
+ );
+ TRACEF("IPCSrvWndProc>IPC_SHEXEC>_ShExec=%d\n",ec);
+ return ec+1;
+ }
+ else if (pCDS->dwData==CDI_SYNCVAR && pCDS->lpData && pCDS->cbData>1)
+ {
+ IPC_SYNCVAR*pSV=(IPC_SYNCVAR*)pCDS->lpData;
+ if (pSV->VarId>=__INST_LAST)return 1+ERROR_INVALID_PARAMETER;
+ TRACEF("WM_COPYDATA: CDI_SYNCVAR:%d=%s|\n",pSV->VarId,&pSV->buf[0]);
+ lstrcpy(GetVar(pSV->VarId),&pSV->buf[0]);
+ return NO_ERROR+1;
+ }
+ else if (pCDS->dwData==CDI_STACKPUSH && pCDS->lpData && pCDS->cbData>=1)
+ {
+ TRACEF("WM_COPYDATA: CDI_STACKPUSH:%s|\n",pCDS->lpData);
+ return StackPush((NSISCH*)pCDS->lpData)+1;
+ }
+ }
+ break;
+ case IPC_GETEXITCODE:
+ return g.LastWaitExitCode;
+ case IPC_ELEVATEAGAIN:
+ TRACE("IPCSrvWndProc>IPC_ELEVATEAGAIN\n");
+ return (g.ElevateAgain=true);
+ case IPC_GETSRVPID:
+ return GetCurrentProcessId();
+ case IPC_GETSRVHWND:
+ return GetWindowLongPtr(hwnd,GWLP_USERDATA);
+ case IPC_EXECCODESEGMENT:
+ return 1+(g.pXParams ? ExecuteCodeSegment(g.pXParams,wp,(HWND)lp) : ERROR_INVALID_FUNCTION);
+ case IPC_GETOUTERPROCESSTOKEN:
+ if (_OpenProcessToken)
+ {
+ HANDLE hToken,hOutToken;
+ if (_OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken))
+ {
+ TRACEF("IPC_GETOUTERPROCESSTOKEN: hToken=%X targetProcess=%X\n",hToken,g.hElevatedProcess);
+ if (DuplicateHandle(GetCurrentProcess(),hToken,g.hElevatedProcess,&hOutToken,lp,false,DUPLICATE_CLOSE_SOURCE))
+ {
+ TRACEF("IPC_GETOUTERPROCESSTOKEN: %X(%X) > %X(%X)\n",hToken,-1,hOutToken,g.hElevatedProcess);
+ return (LRESULT)hOutToken;
+ }
+ }
+ }
+ return NULL;
+
+#ifdef UAC_HACK_FGWND1
+ case IPC_HACKFINDRUNAS: //super ugly hack to get title of run as dialog
+ if (wp<200)
+ {
+ HWND hRA=GetLastActivePopup((HWND)lp);
+ TRACEF("IPC_HACKFINDRUNAS:%d %X %X\n",wp,lp,hRA);
+ if (hRA && hRA !=(HWND)lp ) return PostMessage((HWND)lp,WM_APP,0,(LONG_PTR)hRA);
+ Sleep(10);PostMessage(hwnd,uMsg,wp+1,lp);
+ }
+ break;
+#endif
+ }
+ return DefWindowProc(hwnd,uMsg,wp,lp);
+}
+
+
+DWORD WINAPI IPCSrvThread(LPVOID lpParameter)
+{
+ CoInitialize(0);
+ const DWORD WStyle=WS_VISIBLE DBGONLY(|(WS_CAPTION));
+ const int PosOffset=32700;
+ MSG msg;
+ WNDCLASS wc={0};
+ wc.lpszClassName=GetIPCWndClass();
+ wc.lpfnWndProc=IPCSrvWndProc;
+ wc.hInstance=g.hInstance;
+ if (!RegisterClass(&wc))goto dieLastErr;
+ if (!(g.hSrvIPC=CreateWindowEx(WS_EX_TOOLWINDOW DBGONLY(&~WS_EX_TOOLWINDOW),
+ GetIPCWndClass(),
+ DBGONLY(_T("Debug: NSIS.UAC")+)0,
+ WStyle,
+ -PosOffset DBGONLY(+PosOffset),-PosOffset DBGONLY(+PosOffset),DBGONLY(150+)1,DBGONLY(10+)1,
+ 0,0,wc.hInstance,0
+ )))goto dieLastErr;
+ SetWindowLongPtr(g.hSrvIPC,GWLP_USERDATA,(LONG_PTR)lpParameter);
+ TRACEF("IPCSrv=%X server created...\n",g.hSrvIPC);
+ while (GetMessage(&msg,0,0,0)>0)DispatchMessage(&msg);
+ SetLastError(NO_ERROR);
+dieLastErr:
+ CoUninitialize();
+ return g.LastWaitExitCode=GetLastError();
+}
+
+DWORD InitIPC(HWND hwndNSIS,NSIS::extra_parameters*pXParams,UINT NSISStrLen)
+{
+ if (g.threadIPC)return NO_ERROR;
+ TRACEF("InitIPC StrSize=%u vs %u\n",NSIS::StrSize,NSISStrLen);
+ DWORD tid;
+ ASSERT(!g.pXParams && pXParams);
+ ASSERT(NSISStrLen>0 && NSISStrLen==NSIS::StrSize);
+ g.NSISStrLen=NSISStrLen;
+ g.pXParams=pXParams;
+ g.threadIPC=CreateThread(0,0,IPCSrvThread,hwndNSIS,0,&tid);
+ if (g.threadIPC)
+ {
+ while(!g.hSrvIPC && !g.LastWaitExitCode)Sleep(20);
+ return g.hSrvIPC ? NO_ERROR : g.LastWaitExitCode;
+ }
+ return GetLastError();
+}
+
+void StopIPCSrv()
+{
+ if (g.threadIPC)
+ {
+ TRACEF("StopIPCSrv h=%X \n",g.hSrvIPC);
+#ifdef UAC_HACK_Clammerz
+ if ( GetSysVer()>=5 )
+ {
+ //WINBUGFIX: This ugly thing supposedly solves the problem of messagebox'es in .OnInit appearing behind other windows in Vista
+ HWND hack=CreateWindowEx(WS_EX_TRANSPARENT|WS_EX_LAYERED,_T("Button"),NULL,NULL,0,0,0,0,NULL,NULL,NULL,0);
+ ShowWindow(hack,SW_SHOW);
+ SetForegroundWindow(hack);
+ DestroyWindow(hack);
+ }
+#endif
+ PostMessage(g.hSrvIPC,WM_CLOSE,0,0);
+ WaitForSingleObject(g.threadIPC,INFINITE);
+ CloseHandle(g.threadIPC);
+ UnregisterClass(GetIPCWndClass(),g.hInstance);//DLL can be loaded more than once, so make sure RegisterClass doesn't fail
+ g.hSrvIPC=0;
+ g.threadIPC=0;
+ }
+}
+
+#ifdef UAC_HACK_FGWND1
+LRESULT CALLBACK HackWndSubProc(HWND hwnd,UINT Msg,WPARAM wp,LPARAM lp)
+{
+ switch(Msg)
+ {
+ case WM_APP:
+ GetWindowText((HWND)lp,GetVar(0),NSIS::StrSize);
+ if (*GetVar(0))SendMessage(hwnd,WM_SETTEXT,0,(LONG_PTR)GetVar(0));
+ break;
+ }
+ return DefWindowProc(hwnd,Msg,wp,lp);
+}
+#endif
+
+inline bool MustUseInternalRunAs()
+{
+#ifdef BUILD_DBGSELECTELVMODE
+ TCHAR dbgb[MAX_PATH*4];wsprintf(dbgb,_T("%s.ini"),GetVar(VIDX_EXEPATH));
+ static int dbg_answer=GetPrivateProfileInt(_T("UACDBG"),_T("MustUseInternalRunAs"),2,dbgb);
+ if (dbg_answer<2)return !!dbg_answer;WritePrivateProfileString(_T("UACDBG"),_T("MustUseInternalRunAs"),"",dbgb);
+ if (MessageBox(GetActiveWindow(),"MustUseInternalRunAs?",dbgb,MB_YESNO)==IDYES)return true;
+#endif
+ return GetSysVer()>=6 && !SysElevationPresent();
+}
+
+DWORD ForkSelf(HWND hParent,DWORD&ForkExitCode,NSIS::extra_parameters*pXParams,UINT NSISStrLen)
+{
+ DWORD ec=ERROR_ACCESS_DENIED;
+ SHELLEXECUTEINFO sei={sizeof(sei)};
+ //STARTUPINFO startInfo={sizeof(STARTUPINFO)};
+ LPTSTR pszExePathBuf=0;
+ LPTSTR pszParamBuf=0;
+ LPTSTR p,pCL=GetCommandLine();
+ UINT len;
+ const OSVerMaj=GetOSVerMaj();
+#ifdef UAC_HACK_FGWND1
+ HWND hHack=0;
+#endif
+ ASSERT(pXParams);
+
+ //GetStartupInfo(&startInfo);
+ if (ec=InitIPC(hParent,pXParams,NSISStrLen))goto ret;
+ ASSERT(IsWindow(g.hSrvIPC));
+ sei.hwnd=hParent;
+ sei.nShow=/*(startInfo.dwFlags&STARTF_USESHOWWINDOW) ? startInfo.wShowWindow :*/ SW_SHOWNORMAL;
+ sei.fMask=SEE_MASK_NOCLOSEPROCESS|SEE_MASK_NOZONECHECKS;
+ sei.lpVerb=_T("runas");
+ p=FindExePathEnd(pCL);
+ len=p-pCL;
+ if (!p || !len)
+ {
+ ec=ERROR_FILE_NOT_FOUND;
+ goto ret;
+ }
+ for (;;)
+ {
+ NSIS::MemFree(pszExePathBuf);
+ if (!(pszExePathBuf=(LPTSTR)NSIS::MemAlloc((++len)*sizeof(TCHAR))))goto dieOOM;
+ if ( GetModuleFileName(0,pszExePathBuf,len) < len )break; //FUCKO: what if GetModuleFileName returns 0?
+ len+=MAX_PATH;
+ }
+ sei.lpFile=pszExePathBuf;
+ len=lstrlen(p);
+ len+=20;//space for "/UAC:xxxxxx /NCRC\0"
+ if (!(pszParamBuf=(LPTSTR)NSIS::MemAlloc(len*sizeof(TCHAR))))goto dieOOM;
+ wsprintf(pszParamBuf,_T("/UAC:%X /NCRC%s"),g.hSrvIPC,p);//NOTE: The argument parser depends on our special flag appearing first
+ sei.lpParameters=pszParamBuf;
+
+
+ if (OSVerMaj==5)
+ {
+ bool hasseclogon=SysNT5IsSecondaryLogonSvcRunning();
+ TRACEF("SysNT5IsSecondaryLogonSvcRunning=%d\n",hasseclogon);
+ if (!hasseclogon)
+ {
+ ec=ERROR_SERVICE_NOT_ACTIVE;
+ goto ret;
+ }
+ }
+
+
+
+
+#ifdef UAC_HACK_FGWND1
+ if ( OSVerMaj>=5 && !sei.hwnd )
+ {
+ //sei.nShow=SW_SHOW;//forced, do we HAVE to do this?
+ hHack=CreateWindowEx(WS_EX_TRANSPARENT|WS_EX_LAYERED|WS_EX_TOOLWINDOW|WS_EX_APPWINDOW,_T("Button"),GetVar(VIDX_EXEFILENAME),0|WS_MAXIMIZE,0,0,0,0,NULL,NULL,NULL,0);
+
+ SetWindowLongPtr(hHack,GWLP_WNDPROC,(LONG_PTR)HackWndSubProc);
+ if (GetSysVer()<6 || MustUseInternalRunAs())
+ PostMessage(g.hSrvIPC,IPC_HACKFINDRUNAS,0,(LONG_PTR)hHack);
+ else
+ SetWindowLongPtr(hHack,GWL_EXSTYLE,GetWindowLongPtr(hHack,GWL_EXSTYLE)&~WS_EX_APPWINDOW);//kill taskbar btn on vista
+ HICON hIcon=(HICON)LoadImage(GetModuleHandle(0),MAKEINTRESOURCE(103),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED);
+ SendMessage(hHack,WM_SETICON,ICON_BIG,(LONG_PTR)hIcon);
+ ShowWindow(hHack,SW_SHOW);
+ SetForegroundWindow(hHack);
+ sei.hwnd=hHack;
+ }
+#endif
+
+ if (hParent)SetForegroundWindow(hParent);//try to force taskbar button active (for RunElevatedAndProcessMessages, really important on Vista)
+
+#ifdef FEAT_CUSTOMRUNASDLG
+ if (MustUseInternalRunAs())
+ {
+ ec=MyRunAs(g.hInstance,sei);
+ }
+ else
+#endif
+ {
+ if (GetSysVer()>=6)
+ {
+ ////////sei.nShow=SW_SHOW;
+ //if ( _SupportsUAC() )sei.hwnd=0; //Vista does not like it when we provide a HWND
+ //if (_AllowSetForegroundWindow) _AllowSetForegroundWindow(ASFW_ANY);//TODO: is GrantClientWindowInput() enough?
+ }
+#ifdef FEAT_MSRUNASDLGMODHACK
+ void* hook=MSRunAsDlgMod_Init();
+#endif
+ TRACEF("ForkSelf:calling ShExec:app=%s|params=%s|vrb=%s|hwnd=%X\n",sei.lpFile,sei.lpParameters,sei.lpVerb,sei.hwnd);
+ ec=(ShellExecuteEx(&sei)?NO_ERROR:GetLastError());
+ TRACEF("ForkSelf: ShExec->Runas returned %d hInstApp=%d\n",ec,sei.hInstApp);
+#ifdef FEAT_MSRUNASDLGMODHACK
+ MSRunAsDlgMod_Unload(hook);
+#endif
+ }
+#ifdef UAC_HACK_FGWND1
+ DestroyWindow(hHack);
+#endif
+ if (ec)goto ret;
+ TRACEF("ForkSelf: waiting for process %X (%s|%s|%s)sei.hwnd=%X\n",(sei.hProcess),sei.lpFile,sei.lpParameters,sei.lpVerb,sei.hwnd);
+ ASSERT(sei.hProcess);
+ ASSERT(NO_ERROR==ec);
+ ShowWindow(g.hSrvIPC,SW_HIDE);
+
+ g.hElevatedProcess=sei.hProcess;
+
+ if (!IsWindow(sei.hwnd))
+ {
+ DWORD w=WaitForSingleObject(sei.hProcess,INFINITE);
+ if (w==WAIT_OBJECT_0)
+ VERIFY(GetExitCodeProcess(sei.hProcess,&ForkExitCode));
+ else
+ {
+ ec=GetLastError();
+ TRACEF("ForkSelf:WaitForSingleObject failed ec=%d w=%d\n",ec,w);ASSERT(!"ForkSelf:WaitForSingleObject");
+ }
+ }
+ else
+ {
+ bool abortWait=false;
+ const DWORD waitCount=1;
+ const HANDLE handles[waitCount]={sei.hProcess};
+ do
+ {
+ DWORD w=MsgWaitForMultipleObjects(waitCount,handles,false,INFINITE,QS_ALLEVENTS|QS_ALLINPUT);
+ switch(w)
+ {
+ case WAIT_OBJECT_0:
+ VERIFY(GetExitCodeProcess(sei.hProcess,&ForkExitCode));
+ abortWait=true;
+ break;
+ case WAIT_OBJECT_0+waitCount:
+ {
+ const HWND hwnd=sei.hwnd;
+ MSG msg;
+ while( !ec && PeekMessage(&msg,hwnd,0,0,PM_REMOVE) )
+ {
+ if (msg.message==WM_QUIT)
+ {
+ ASSERT(0);
+ ec=ERROR_CANCELLED;
+ break;
+ }
+ if (!IsDialogMessage(hwnd,&msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ }
+ break;
+ default:
+ abortWait=true;
+ ec=GetLastError();
+ TRACEF("ForkSelf:MsgWaitForMultipleObjects failed, ec=%u w=%u\n",ec,w);
+ }
+ } while( NO_ERROR==ec && !abortWait );
+ }
+
+ TRACEF("ForkSelf: wait complete, ec=%d forkexitcode=%u\n",ec,ForkExitCode);
+ goto ret;
+dieOOM:
+ ec=ERROR_OUTOFMEMORY;
+ret:
+ StopIPCSrv();
+ CloseHandle(sei.hProcess);
+ NSIS::MemFree(pszExePathBuf);
+ NSIS::MemFree(pszParamBuf);
+ return ec;
+}
+
+bool GetIPCSrvWndFromParams(HWND&hwndOut)
+{
+ LPTSTR p=FindExePathEnd(GetCommandLine());
+ while(p && *p==' ')p=CharNext(p);TRACEF("GetIPCSrvWndFromParams:%s|\n",p);
+ if (p && *p++=='/'&&*p++=='U'&&*p++=='A'&&*p++=='C'&&*p++==':')
+ {
+ hwndOut=(HWND)StrToUInt(p,true);
+ return !!IsWindow(hwndOut);
+ }
+ return false;
+}
+
+
+/*** RunElevated
+Return: r0: Windows error code (0 on success, 1223 if user aborted elevation dialog, anything else should be treated as a fatal error)
+ r1: If r0==0, r1 is:
+ 0 if UAC is not supported by the OS,
+ 1 if UAC was used to elevate and the current process should act like a wrapper (Call Quit in .OnInit without any further processing),
+ 2 if the process is (already?) running @ HighIL (Member of admin group on other systems),
+ 3 if you should call RunElevated again (This can happen if a user without admin priv. is used in the runas dialog),
+ r2: If r0==0 && r1==1: r2 is the ExitCode of the elevated fork process (The NSIS errlvl is also set to the ExitCode)
+ r3: If r0==0: r3 is 1 if the user is a member of the admin group or 0 otherwise
+*/
+EXPORTNSISFUNC RunElevated(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+
+ BYTE UACMode=0;
+ bool UserIsAdmin=false;
+ DWORD ec=ERROR_ACCESS_DENIED,ForkExitCode;
+ TOKEN_ELEVATION_TYPE tet;
+
+ UserIsAdmin=_IsAdmin();
+ TRACEF("RunElevated:Init: IsAdmin=%d\n",UserIsAdmin);
+#ifdef BUILD_XPTEST
+ if (!UserIsAdmin)goto DbgXPAsUAC;//Skip UAC detection for special debug builds and force a call to runas on <NT6 systems
+#endif
+ if (!_SupportsUAC() && !SysSupportsRunAs())goto noUAC;
+ if ((ec=DelayLoadDlls()))goto ret;
+
+ if (GetIPCSrvWndFromParams(g.hSrvIPC))
+ {
+ if (ec=DllSelfAddRef())goto ret;
+ if (!IsWindow(g.hSrvIPC))ec=ERRAPP_BADIPCSRV;
+ UACMode=2;
+ g.UseIPC=true;
+ if (!UserIsAdmin) //Elevation used, but we are not Admin, let the wrapper know so it can try again...
+ {
+ UACMode=0xFF;//Special invalid mode
+ DWORD_PTR MsgRet;
+ if (SendIPCMsg(IPC_ELEVATEAGAIN,0,0,MsgRet) || !MsgRet)ec=ERRAPP_BADIPCSRV;//if we could not notify the need for re-elevation, the IPCSrv must be bad
+ }
+ goto ret;
+ }
+
+ if ( (ec=DllSelfAddRef()) || (ec=_GetElevationType(&tet)) )goto ret;
+ if ( tet==TokenElevationTypeFull || UserIsAdmin )
+ {
+ UserIsAdmin=true;
+ UACMode=2;
+ goto ret;
+ }
+
+ DBGONLY(DBG_RESETDBGVIEW());
+
+#ifdef BUILD_XPTEST
+DbgXPAsUAC:VERIFY(!DllSelfAddRef());
+#endif
+ //OS supports UAC and we need to elevate...
+ ASSERT(!UserIsAdmin);
+ UACMode=1;
+
+ ec=ForkSelf(hwndNSIS,ForkExitCode,XParams,StrSize);
+ if (!ec && !g.ElevateAgain)
+ {
+ SetVarUINT(INST_2,ForkExitCode);
+ SetErrLvl(XParams,ForkExitCode);
+ }
+ goto ret;
+noUAC:
+ ec=NO_ERROR;ASSERT(UACMode==0);
+ret:
+ if (ec==ERROR_CANCELLED)
+ {
+ if (UACMode!=1)ec=ERROR_INVALID_FUNCTION;
+ if (UACMode<2)g.UseIPC=false;
+ }
+ if (UACMode==0xFF && !ec) //We called IPC_ELEVATEAGAIN, so we need to quit so the wrapper gains control
+ {
+ ASSERT(g.UseIPC);
+ UACMode=1;//We pretend to be the wrapper so Quit gets called in .OnInit
+ SetErrLvl(XParams,0);
+ _Unload();
+ }
+ if (g.ElevateAgain)
+ {
+ ASSERT(!g.UseIPC);
+ UACMode=3;//Fork called IPC_ELEVATEAGAIN, we need to change our UACMode so the wrapper(our instance) can try to elevate again if it wants to
+ }
+ if (!g.UseIPC)
+ _Unload();//The wrapper can call quit in .OnInit without calling UAC::Unload, so we do it here
+
+ SetVarUINT(INST_0,ec);
+ SetVarUINT(INST_1,UACMode);
+ SetVarUINT(INST_3,UserIsAdmin);
+ TRACEF("RunElevated returning ec=%X UACMode=%d g.UseIPC=%d g.ElevateAgain=%d IsAdmin=%d\n",ec,UACMode,g.UseIPC,g.ElevateAgain,UserIsAdmin);
+
+ NSISFUNCEND();
+}
+
+
+
+/*** Exec
+Notes:
+ ¤ ErrorFlag is also set on error
+STACK: <ShowWindow> <File> <Parameters> <WorkingDir>
+Return: windows error code in r0, 0 on success
+*/
+EXPORTNSISFUNC Exec(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+ HandleExecExport(true,false,hwndNSIS,StrSize,Vars,StackTop,XParams);
+ NSISFUNCEND();
+}
+
+/*** ExecWait
+Notes:
+ ¤ ErrorFlag is also set on error
+STACK: <ShowWindow> <File> <Parameters> <WorkingDir>
+Return:
+ r0: windows error code, 0 on success
+ r1: exitcode of new process
+*/
+EXPORTNSISFUNC ExecWait(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+ HandleExecExport(true,true,hwndNSIS,StrSize,Vars,StackTop,XParams);
+ NSISFUNCEND();
+}
+
+/*** ShellExec
+Notes:
+ ¤ ErrorFlag is also set on error
+STACK: <Verb> <ShowWindow> <File> <Parameters> <WorkingDir>
+Return: windows error code in r0, 0 on success
+*/
+EXPORTNSISFUNC ShellExec(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+ HandleExecExport(false,false,hwndNSIS,StrSize,Vars,StackTop,XParams);
+ NSISFUNCEND();
+}
+
+/*** ShellExecWait
+Notes:
+ ¤ ErrorFlag is also set on error
+STACK: <Verb> <ShowWindow> <File> <Parameters> <WorkingDir>
+Return:
+ r0: windows error code, 0 on success
+ r1: exitcode of new process
+*/
+EXPORTNSISFUNC ShellExecWait(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+ HandleExecExport(false,true,hwndNSIS,StrSize,Vars,StackTop,XParams);
+ NSISFUNCEND();
+}
+
+
+/*** GetElevationType
+Notes:
+ TokenElevationTypeDefault=1 :User is not using a split token (UAC disabled)
+ TokenElevationTypeFull=2 :UAC enabled, the process is elevated
+ TokenElevationTypeLimited=3 :UAC enabled, the process is not elevated
+Return: r0: (TOKEN_ELEVATION_TYPE)TokenType, The error flag is set if the function fails and r0==0
+*/
+EXPORTNSISFUNC GetElevationType(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+ TOKEN_ELEVATION_TYPE tet=(TOKEN_ELEVATION_TYPE)NULL; //Default to invalid value
+ if (MaintainDllSelfRef() || /*!_SupportsUAC() ||*/ _GetElevationType(&tet)) SetErrorFlag(XParams);
+ SetVarUINT(INST_0,tet);
+ NSISFUNCEND();
+}
+
+
+
+/*** SupportsUAC
+Notes: Check if the OS supports UAC (And the user has UAC turned on)
+Return: r0: (BOOL)Result
+*/
+EXPORTNSISFUNC SupportsUAC(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+ BOOL present=false;
+ MaintainDllSelfRef();
+ if (_SupportsUAC())present=true;
+ SetVarUINT(INST_0,present);
+ NSISFUNCEND();
+}
+
+
+/*** IsAdmin
+Return: r0: (BOOL)Result
+*/
+EXPORTNSISFUNC IsAdmin(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+ bool Admin=false;
+ DWORD ec;
+ if ( !(ec=MaintainDllSelfRef()) )
+ {
+ Admin=_IsAdmin();
+ if ( ec=GetLastError() )
+ {
+ TRACEF("IsAdmin failed with %d\n",ec);
+ SetErrorFlag(XParams);
+ Admin=false;
+ }
+ }
+ SetVarUINT(INST_0,Admin);
+ NSISFUNCEND();
+}
+
+
+
+/*** ExecCodeSegment
+Notes: Sets error flag on error
+ There is currently no way to transfer state to/from the executed code segment!
+ If you use instructions that alter the UI or the stack/variables in the code segment (StrCpy,Push/Pop/Exch,DetailPrint,HideWindow etc.) they will affect the hidden wrapper installer and not "your" installer instance!
+*/
+EXPORTNSISFUNC ExecCodeSegment(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+
+ DWORD ec;
+ if (!(ec=DllSelfAddRef())) //force AddRef since our plugin could be called inside the executed code segment!
+ {
+ ec=ERROR_INVALID_PARAMETER;
+ stack_t* pSI=StackPop();
+ if (pSI)
+ {
+ BOOL badCh;
+ UINT pos=StrToUInt(pSI->text,false,&badCh);
+ TRACEF("ExecCodeSegment %d (%s) badinput=%d\n",pos-1,pSI->text,badCh);
+ if (!badCh && pos--)
+ {
+ if (!g.UseIPC)
+ ec=NSIS::ExecuteCodeSegment(XParams,pos);
+ else
+ {
+ SyncVars(hwndNSIS);
+ DWORD_PTR MsgRet;
+ AllowOuterInstanceWindowFocus();
+ if (!(ec=SendIPCMsg(IPC_EXECCODESEGMENT,pos,0,MsgRet,INFINITE)))ec=MsgRet-1;
+ }
+ }
+ StackFreeItem(pSI);
+ }
+ }
+ if (ec)SetErrorFlag(XParams);
+
+ NSISFUNCEND();
+}
+
+
+
+/*** StackPush */
+EXPORTNSISFUNC StackPush(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+
+ DWORD ec;
+ if (!(ec=DllSelfAddRef()) && g.UseIPC)
+ {
+ stack_t* pSI=StackPop();
+ ec=ERROR_INVALID_PARAMETER;
+ if (pSI)
+ {
+ DWORD_PTR MsgRet;
+ COPYDATASTRUCT cds={CDI_STACKPUSH,(lstrlen(pSI->text)+1)*sizeof(NSISCH),pSI->text};
+ if (!(ec=SendIPCMsg(WM_COPYDATA,(WPARAM)hwndNSIS,(LPARAM)&cds,MsgRet,5000 )))ec=MsgRet-1;
+ StackFreeItem(pSI);
+ }
+ }
+ if (ec)SetErrorFlag(XParams);
+
+ NSISFUNCEND();
+}
+
+
+
+/*** GetOuterHwnd */
+EXPORTNSISFUNC GetOuterHwnd(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+ MaintainDllSelfRef();
+ DWORD_PTR MsgRet;HWND hSrvIPC;
+ if (!GetIPCSrvWndFromParams(hSrvIPC)||!IsWindow(hSrvIPC)||SendIPCMsg(IPC_GETSRVHWND,0,0,MsgRet,IPCTOUT_DEF,hSrvIPC))MsgRet=0;
+ SetVarUINT(INST_0,MsgRet);
+ NSISFUNCEND();
+}
+
+
+DWORD SetPrivilege(LPCSTR PrivName,bool Enable)
+{
+ DWORD r=NO_ERROR;
+ HANDLE hToken=NULL;
+ TOKEN_PRIVILEGES TokenPrivs;
+ if (!LookupPrivilegeValueA(NULL,PrivName,&TokenPrivs.Privileges[0].Luid))goto dieGLE;
+ if (!_OpenProcessToken(GetCurrentProcess (),TOKEN_ADJUST_PRIVILEGES,&hToken))goto dieGLE;
+ TokenPrivs.Privileges[0].Attributes = Enable ? SE_PRIVILEGE_ENABLED : 0 ;
+ TokenPrivs.PrivilegeCount=1;
+ if (AdjustTokenPrivileges(hToken,FALSE,&TokenPrivs,0,NULL,NULL))goto ret;
+dieGLE:
+ r=GetLastError();
+ret:
+ CloseHandle(hToken);
+ return r;
+}
+
+
+#include <shlobj.h>
+/*** GetShellFolderPath */
+EXPORTNSISFUNC GetShellFolderPath(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ /*
+ WINBUG:
+ For some reason, even with debug priv. enabled, a call to OpenProcessToken(TOKEN_READ|TOKEN_IMPERSONATE)
+ will fail, even if we have a PROCESS_ALL_ACCESS handle on XP when running as a member of the Power Users Group.
+ So we have to ask the outer process to give us the handle.
+ */
+
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+ MaintainDllSelfRef();
+
+ const unsigned TokenAccessRights=TOKEN_READ|TOKEN_IMPERSONATE;
+ unsigned clsidFolder;
+ HWND hSrvIPC;
+ HANDLE hToken=NULL,hOuterProcess=NULL;
+ DWORD SrvPID;
+ HRESULT hr;
+ FARPROC pfnSHGetFolderPath;
+ LPTSTR buf=GetVar(INST_0);
+ stack_t*pssCLSID=StackPop();
+ stack_t*pssFallback=NULL;
+ BOOL ConvBadCh;
+ if (!pssCLSID || !(pssFallback=StackPop())) goto fail;
+ clsidFolder=StrToUInt(pssCLSID->text,false,&ConvBadCh);
+ if (ConvBadCh)goto fail;
+ TRACEF("GetShellFolderPath HasIPCServer=%X param=%s>%X fallback=%s|\n",HasIPCServer(),pssCLSID->text,clsidFolder,pssFallback->text);
+
+ pfnSHGetFolderPath=GetProcAddress(GetModuleHandle(_T("SHELL32")),"SHGetFolderPath"__DLD_FUNCSUFFIX);
+ if (!pfnSHGetFolderPath)goto fail;
+
+ if (GetIPCSrvWndFromParams(hSrvIPC) && 0 != GetWindowThreadProcessId(hSrvIPC,&SrvPID))
+ {
+ hOuterProcess=OpenProcess(PROCESS_QUERY_INFORMATION,false,SrvPID);
+ if (hOuterProcess)
+ {
+ BOOL bOk=OpenProcessToken(hOuterProcess,TokenAccessRights,&hToken);
+ CloseHandle(hOuterProcess);
+ if (bOk)goto gotToken;
+
+ }
+/* SetPrivilege(SE_DEBUG_NAME,true);
+ hOuterProcess=OpenProcess(PROCESS_DUP_HANDLE,false,SrvPID);
+ SetPrivilege(SE_DEBUG_NAME,false);
+ if (!hOuterProcess)goto fail;
+ TRACEF("hOuterProcess=%X\n",hOuterProcess);
+*/ SendIPCMsg(IPC_GETOUTERPROCESSTOKEN,0,TokenAccessRights,(DWORD_PTR&)hToken,IPCTOUT_DEF,hSrvIPC);
+ TRACEF("IPC_GETOUTERPROCESSTOKEN=%X\n",hToken);//*/
+ }
+gotToken:
+ if (HasIPCServer() && !hToken)goto fail;
+
+ hr=((HRESULT(WINAPI*)(HWND,int,HANDLE,DWORD,LPTSTR))pfnSHGetFolderPath)(hwndNSIS,clsidFolder,hToken,SHGFP_TYPE_CURRENT,buf);
+ TRACEF("SHGetFolderPath hr=%X with token=%X, clsidFolder=%X|%s\n",hr,hToken,clsidFolder,buf);
+ if (FAILED(hr)) goto fail; else goto ret;
+fail:
+ TRACEF("GetShellFolderPath GLE=%X\n",GetLastError());
+ lstrcpy(buf,pssFallback->text);
+ TRACEF("%s|%s\n",buf,pssFallback->text);
+ret:
+// CloseHandle(hOuterProcess);
+ CloseHandle(hToken);
+ StackFreeItem(pssFallback);
+ StackFreeItem(pssCLSID);
+ NSISFUNCEND();
+}
+
+
+
+/*** GetOuterPID * /
+EXPORTNSISFUNC GetOuterPID(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop,NSIS::extra_parameters* XParams)
+{
+ NSISFUNCSTART(hwndNSIS,StrSize,Vars,StackTop,XParams);
+ MaintainDllSelfRef();
+ DWORD_PTR Ret=0;
+ HWND hSrvIPC;
+ if (GetIPCSrvWndFromParams(hSrvIPC))
+ if (0==GetWindowThreadProcessId(hSrvIPC,&Ret))Ret=0;
+ SetVarUINT(INST_0,Ret);
+ NSISFUNCEND();
+}//*/
+
+
+
+/*** Unload
+Notes: Call in .OnInstFailed AND .OnInstSuccess !
+*/
+EXPORTNSISFUNC Unload(HWND hwndNSIS,int StrSize,NSISCH*Vars,NSIS::stack_t **StackTop)
+{
+ NSISFUNCSTART4(hwndNSIS,StrSize,Vars,StackTop);
+ if (!MaintainDllSelfRef())_Unload(); else ASSERT(!"MaintainDllSelfRef failed in Unload!");
+ NSISFUNCEND();
+}
+
+
+
+#ifdef _DEBUG
+BOOL WINAPI DllMain(HINSTANCE hInst,DWORD Event,LPVOID lpReserved)
+#else
+extern "C" BOOL WINAPI _DllMainCRTStartup(HINSTANCE hInst,ULONG Event,LPVOID lpReserved)
+#endif
+{
+ if (Event==DLL_PROCESS_ATTACH)
+ {
+ TRACEF("************************************ DllMain %u\n",GetCurrentProcessId());
+ ASSERT(!_OpenProcessToken && !_EqualSid);
+ g.hInstance=hInst;
+ }
+// DBGONLY( if (Event==DLL_PROCESS_DETACH){ASSERT(g.DllRef==0);}TRACE("DLL_PROCESS_DETACH\n"); );//Make sure we unloaded so we don't lock $pluginsdir
+ return TRUE;
+}
+
+
diff --git a/admin/win/nsi/nsis_uac/uac.h b/admin/win/nsi/nsis_uac/uac.h
new file mode 100755
index 000000000..8e6e396e3
--- /dev/null
+++ b/admin/win/nsi/nsis_uac/uac.h
@@ -0,0 +1,169 @@
+//Copyright (C) 2007 Anders Kjersem. Licensed under the zlib/libpng license, see License.txt for details.
+#pragma once
+/** /#define BUILD_DBGRELEASE // Include simple debug output in release version */
+/** /#define BUILD_DBGSELECTELVMODE //Test MyRunAs*/
+
+/** /#define UNICODE // Unicode build */
+/**/#define FEAT_CUSTOMRUNASDLG // Include custom runas dialog */
+/**/#define FEAT_CUSTOMRUNASDLG_TRANSLATE //*/
+/**/#define FEAT_MSRUNASDLGMODHACK // Default to other user radio button */
+
+
+#if !defined(APSTUDIO_INVOKED) && !defined(RC_INVOKED)
+
+#if (defined(_MSC_VER) && !defined(_DEBUG))
+ #pragma comment(linker,"/opt:nowin98")
+ #pragma comment(linker,"/ignore:4078")
+ #pragma comment(linker,"/merge:.rdata=.text")
+
+ //#pragma intrinsic(memset) //http://www.codeguru.com/forum/showthread.php?t=371491&page=2&pp=15 | http://www.ddj.com/windows/184416623
+#endif
+
+#if defined(UNICODE) && !defined(_UNICODE)
+#define _UNICODE
+#endif
+#ifdef _UNICODE
+#define TFUNCSUFFIX W
+#else
+#define TFUNCSUFFIX A
+#endif
+#define _PCJOIN(a,b) a##b
+#define PCJOIN(a,b) _PCJOIN(a,b)
+
+
+#define _WIN32_WINNT 0x0501
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <ShellAPI.h>
+#include <TChar.h>
+#include "NSISUtil.h"
+
+#ifndef SEE_MASK_NOZONECHECKS
+#define SEE_MASK_NOZONECHECKS 0x00800000
+#endif
+
+#define COUNTOF(___c) ( sizeof(___c)/sizeof(___c[0]) )
+#ifndef ARRAYSIZE
+#define ARRAYSIZE COUNTOF
+#endif
+#define FORCEINLINE __forceinline
+
+#if _MSC_VER >= 1400
+extern void* __cdecl memset(void*mem,int c,size_t len);
+#endif
+
+FORCEINLINE LRESULT MySndDlgItemMsg(HWND hDlg,int id,UINT Msg,WPARAM wp=0,LPARAM lp=0) {return SendMessage(GetDlgItem(hDlg,id),Msg,wp,lp);}
+#ifndef UAC_NOCUSTOMIMPLEMENTATIONS
+FORCEINLINE HANDLE WINAPI GetCurrentProcess(){return ((HANDLE)(-1));}
+FORCEINLINE HANDLE WINAPI GetCurrentThread(){return ((HANDLE)(-2));}
+
+#define MyTStrLen lstrlen
+
+#undef lstrcpy
+#define lstrcpy MyTStrCpy
+FORCEINLINE LPTSTR MyTStrCpy(LPTSTR s1,LPCTSTR s2) {return PCJOIN(lstr,PCJOIN(cpyn,TFUNCSUFFIX))(s1,s2,0x7FFFFFFF);}
+
+#undef lstrcat
+#define lstrcat MyTStrCat
+LPTSTR MyTStrCat(LPTSTR s1,LPCTSTR s2)
+#ifdef UAC_INITIMPORTS
+{return s1?MyTStrCpy(&s1[MyTStrLen(s1)],s2):NULL;}
+#else
+;
+#endif //UAC_INITIMPORTS
+
+#endif //UAC_NOCUSTOMIMPLEMENTATIONS
+
+
+//DelayLoaded functions:
+typedef BOOL (WINAPI*ALLOWSETFOREGROUNDWINDOW)(DWORD dwProcessId);
+typedef BOOL (WINAPI*OPENPROCESSTOKEN)(HANDLE ProcessHandle,DWORD DesiredAccess,PHANDLE TokenHandle);
+typedef BOOL (WINAPI*OPENTHREADTOKEN)(HANDLE ThreadHandle,DWORD DesiredAccess,BOOL OpenAsSelf,PHANDLE TokenHandle);
+typedef BOOL (WINAPI*GETTOKENINFORMATION)(HANDLE hToken,TOKEN_INFORMATION_CLASS TokInfoClass,LPVOID TokInfo,DWORD TokInfoLenh,PDWORD RetLen);
+typedef BOOL (WINAPI*ALLOCATEANDINITIALIZESID)(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,BYTE nSubAuthorityCount,DWORD sa0,DWORD sa1,DWORD sa2,DWORD sa3,DWORD sa4,DWORD sa5,DWORD sa6,DWORD sa7,PSID*pSid);
+typedef PVOID (WINAPI*FREESID)(PSID pSid);
+typedef BOOL (WINAPI*EQUALSID)(PSID pSid1,PSID pSid2);
+typedef BOOL (WINAPI*CHECKTOKENMEMBERSHIP)(HANDLE TokenHandle,PSID SidToCheck,PBOOL IsMember);
+#ifdef FEAT_CUSTOMRUNASDLG
+typedef BOOL (WINAPI*GETUSERNAME)(LPTSTR lpBuffer,LPDWORD nSize);
+typedef BOOL (WINAPI*CREATEPROCESSWITHLOGONW)(LPCWSTR lpUsername,LPCWSTR lpDomain,LPCWSTR lpPassword,DWORD dwLogonFlags,LPCWSTR lpApplicationName,LPWSTR lpCommandLine,DWORD dwCreationFlags,LPVOID pEnv,LPCWSTR WorkDir,LPSTARTUPINFOW pSI,LPPROCESS_INFORMATION pPI);
+#define SECURITY_WIN32
+#include <Security.h>//NameSamCompatible
+typedef BOOLEAN (WINAPI*GETUSERNAMEEX)(EXTENDED_NAME_FORMAT NameFormat,LPTSTR lpNameBuffer,PULONG nSize);
+#endif
+#ifdef UAC_INITIMPORTS
+ALLOWSETFOREGROUNDWINDOW _AllowSetForegroundWindow=0;
+OPENPROCESSTOKEN _OpenProcessToken=0;
+OPENTHREADTOKEN _OpenThreadToken=0;
+GETTOKENINFORMATION _GetTokenInformation=0;
+ALLOCATEANDINITIALIZESID _AllocateAndInitializeSid=0;
+FREESID _FreeSid=0;
+EQUALSID _EqualSid=0;
+CHECKTOKENMEMBERSHIP _CheckTokenMembership=0;
+#ifdef FEAT_CUSTOMRUNASDLG
+GETUSERNAME _GetUserName=0;
+GETUSERNAMEEX _GetUserNameEx=0;
+CREATEPROCESSWITHLOGONW _CreateProcessWithLogonW=0;
+#endif
+#else
+#ifdef FEAT_CUSTOMRUNASDLG
+extern GETUSERNAME _GetUserName;
+extern GETUSERNAMEEX _GetUserNameEx;
+extern CREATEPROCESSWITHLOGONW _CreateProcessWithLogonW;
+#endif
+#endif /* UAC_INITIMPORTS */
+
+
+extern DWORD DelayLoadDlls();
+#ifdef FEAT_CUSTOMRUNASDLG
+extern DWORD MyRunAs(HINSTANCE hInstDll,SHELLEXECUTEINFO&sei);
+#endif
+
+#if !defined(NTDDI_VISTA) || defined(BUILD_OLDSDK)
+//#if !defined(NTDDI_VERSION) || (NTDDI_VERSION < 0x06000000) || !defined(NTDDI_VISTA)
+//#if !defined(TOKEN_ELEVATION_TYPE) || defined(BUILD_OLDSDK)
+enum TOKEN_ELEVATION_TYPE {
+ TokenElevationTypeDefault = 1,
+ TokenElevationTypeFull,
+ TokenElevationTypeLimited
+};
+enum _TOKEN_INFORMATION_CLASS___VISTA {
+ TokenElevationType = (TokenOrigin+1),
+ TokenLinkedToken,
+ TokenElevation,
+ TokenHasRestrictions,
+ TokenAccessInformation,
+ TokenVirtualizationAllowed,
+ TokenVirtualizationEnabled,
+ TokenIntegrityLevel,
+ TokenUIAccess,
+ TokenMandatoryPolicy,
+ TokenLogonSid,
+};
+#endif
+
+
+#if defined(_DEBUG) || defined(BUILD_DBGRELEASE)
+//Simple debug helpers:
+#define BUILD_DBG
+/** /#define BUILD_XPTEST //Pretend UAC exists and "elevate" with NT runas */
+#define DBG_RESETDBGVIEW() do{HWND hDbgView=FindWindowA("dbgviewClass",0);PostMessage(hDbgView,WM_COMMAND,40020,0);if(0)SetForegroundWindow(hDbgView);}while(0)
+#define _pp_MakeStr_(x) #x
+#define pp_MakeStr(x) _pp_MakeStr_(x)
+#define TRACE OutputDebugStringA
+#define DBGONLY(_x) _x
+#ifndef ASSERT
+#define ASSERT(_x) do{if(!(_x)){MessageBoxA(GetActiveWindow(),#_x##"\n\n"##__FILE__##":"## pp_MakeStr(__LINE__),"SimpleAssert",0);/*TRACE(#_x##"\n"##__FILE__##":" pp_MakeStr(__LINE__)"\n");*/}}while(0)
+#endif
+#define VERIFY(_x) ASSERT(_x)
+static void TRACEF(const char*fmt,...) {va_list a;va_start(a,fmt);static TCHAR b[1024*4];if (sizeof(TCHAR)!=sizeof(char)){static TCHAR fmtBuf[COUNTOF(b)];VERIFY(wsprintf(fmtBuf,_T("%hs"),fmt)<COUNTOF(fmtBuf));fmt=(LPCSTR)fmtBuf;}wvsprintf(b,(TCHAR*)fmt,a);OutputDebugString(b);}
+#else
+#define TRACE /*(void)0*/
+#define DBGONLY(_x)
+#define ASSERT(_x)
+#define VERIFY(_x) ((void)(_x))
+#define TRACEF TRACE
+#endif /* DEBUG */
+
+#endif /* APSTUDIO_INVOKED */
+
diff --git a/admin/win/nsi/page_header_oc.bmp b/admin/win/nsi/page_header_oc.bmp
new file mode 100644
index 000000000..7a7c0733d
--- /dev/null
+++ b/admin/win/nsi/page_header_oc.bmp
Binary files differ
diff --git a/admin/win/nsi/page_header_oc.xcf b/admin/win/nsi/page_header_oc.xcf
new file mode 100644
index 000000000..0c61bb8be
--- /dev/null
+++ b/admin/win/nsi/page_header_oc.xcf
Binary files differ
diff --git a/admin/win/nsi/tomahawk.ini b/admin/win/nsi/tomahawk.ini
new file mode 100644
index 000000000..be3933a95
--- /dev/null
+++ b/admin/win/nsi/tomahawk.ini
@@ -0,0 +1,21 @@
+[Settings]
+NumFields=3
+[Field 1]
+Type=Label
+Left=0
+Right=-1
+Top=0
+Bottom=24
+[Field 2]
+Type=RadioButton
+Left=30
+Right=-1
+Top=50
+Bottom=58
+State=1
+[Field 3]
+Type=RadioButton
+Left=30
+Right=-1
+Top=70
+Bottom=78 \ No newline at end of file
diff --git a/admin/win/nsi/welcome_oc.bmp b/admin/win/nsi/welcome_oc.bmp
new file mode 100644
index 000000000..470b5b595
--- /dev/null
+++ b/admin/win/nsi/welcome_oc.bmp
Binary files differ