mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-09-01 01:51:58 +02:00
Move installer related stuff into admin/win/nsi.
This commit is contained in:
102
admin/win/nsi/nsis_uac/History.txt
Executable file
102
admin/win/nsi/nsis_uac/History.txt
Executable file
@@ -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
|
14
admin/win/nsi/nsis_uac/License.txt
Executable file
14
admin/win/nsi/nsis_uac/License.txt
Executable file
@@ -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.
|
149
admin/win/nsi/nsis_uac/NSISUtil.h
Executable file
149
admin/win/nsi/nsis_uac/NSISUtil.h
Executable file
@@ -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() }
|
||||
|
BIN
admin/win/nsi/nsis_uac/Release/A/UAC.dll
Executable file
BIN
admin/win/nsi/nsis_uac/Release/A/UAC.dll
Executable file
Binary file not shown.
BIN
admin/win/nsi/nsis_uac/Release/U/UAC.dll
Executable file
BIN
admin/win/nsi/nsis_uac/Release/U/UAC.dll
Executable file
Binary file not shown.
277
admin/win/nsi/nsis_uac/RunAs.cpp
Executable file
277
admin/win/nsi/nsis_uac/RunAs.cpp
Executable file
@@ -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 */
|
||||
|
222
admin/win/nsi/nsis_uac/UAC Readme.html
Executable file
222
admin/win/nsi/nsis_uac/UAC Readme.html
Executable file
@@ -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><INT:ShowWindow> <STR:App> <STR:Parameters> <STR:WorkingDir></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><INT:ShowWindow> <STR:App> <STR:Parameters> <STR:WorkingDir></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><STR:Verb> <INT:ShowWindow> <STR:App> <STR:Parameters> <STR:WorkingDir></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><STR:Verb> <INT:ShowWindow> <STR:App> <STR:Parameters> <STR:WorkingDir></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><INT:NSISFunctionAddress></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><STR:String></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>
|
191
admin/win/nsi/nsis_uac/UAC.nsh
Executable file
191
admin/win/nsi/nsis_uac/UAC.nsh
Executable file
@@ -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 */
|
62
admin/win/nsi/nsis_uac/UAC_AdminOnly.nsi
Executable file
62
admin/win/nsi/nsis_uac/UAC_AdminOnly.nsi
Executable file
@@ -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*/
|
45
admin/win/nsi/nsis_uac/UAC_AllowLUA.nsi
Executable file
45
admin/win/nsi/nsis_uac/UAC_AllowLUA.nsi
Executable file
@@ -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
|
30
admin/win/nsi/nsis_uac/UAC_GetUserShellFolderPath.nsi
Executable file
30
admin/win/nsi/nsis_uac/UAC_GetUserShellFolderPath.nsi
Executable file
@@ -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
|
242
admin/win/nsi/nsis_uac/UAC_RealWorldFullyLoadedDualModeExample.nsi
Executable file
242
admin/win/nsi/nsis_uac/UAC_RealWorldFullyLoadedDualModeExample.nsi
Executable file
@@ -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
|
49
admin/win/nsi/nsis_uac/UAC_Uninstaller.nsi
Executable file
49
admin/win/nsi/nsis_uac/UAC_Uninstaller.nsi
Executable file
@@ -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
|
24
admin/win/nsi/nsis_uac/resource.h
Executable file
24
admin/win/nsi/nsis_uac/resource.h
Executable file
@@ -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
|
109
admin/win/nsi/nsis_uac/resource.rc
Executable file
109
admin/win/nsi/nsis_uac/resource.rc
Executable file
@@ -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
|
||||
|
1518
admin/win/nsi/nsis_uac/uac.cpp
Executable file
1518
admin/win/nsi/nsis_uac/uac.cpp
Executable file
File diff suppressed because it is too large
Load Diff
169
admin/win/nsi/nsis_uac/uac.h
Executable file
169
admin/win/nsi/nsis_uac/uac.h
Executable file
@@ -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 */
|
||||
|
Reference in New Issue
Block a user