chore: initial commit (extracted from Launchers monorepo)
Plugin: nsShellExecAsUser v1.0.0 Architectures: x86-ansi, x86-unicode, amd64-unicode License: zlib
This commit is contained in:
@@ -0,0 +1,272 @@
|
||||
// ShellExecAsUser.cpp : Defines the entry point for the DLL application.
|
||||
//
|
||||
#include <windows.h>
|
||||
#include <shlDisp.h>
|
||||
#include <atlbase.h>
|
||||
#include <Exdisp.h>
|
||||
#include <shobjidl.h>
|
||||
#include <shlguid.h>
|
||||
//#include <process.h>
|
||||
#include "pluginapi.h" // nsis plugin
|
||||
#include <shellApi.h>
|
||||
//#pragma comment(linker,"/merge:.rdata=.text")
|
||||
|
||||
//VistaTools
|
||||
#define NO_DLL_IMPORTS 1
|
||||
#define DONTWANT_RunNonElevated 1
|
||||
#define IMPLEMENT_VISTA_TOOLS
|
||||
#include "VistaTools.cxx"
|
||||
//////////////////////////////////////
|
||||
|
||||
//missing in old sdk, had to replace shlwapi.lib as well
|
||||
//LWSTDAPI IUnknown_QueryService(__in IUnknown* punk, __in REFGUID guidService, __in REFIID riid, __deref_out void ** ppvOut);
|
||||
|
||||
|
||||
HINSTANCE g_hInstance;
|
||||
HWND g_hwndParent;
|
||||
HWND g_hwnd;
|
||||
HANDLE g_hThread;
|
||||
|
||||
typedef struct _ExecShellParams {
|
||||
TCHAR action[50];
|
||||
TCHAR command[_MAX_PATH];
|
||||
TCHAR params[1024];
|
||||
TCHAR directory[_MAX_PATH];
|
||||
int iShow;
|
||||
} ExecShellParams;
|
||||
|
||||
UINT_PTR NSISPluginCallback(enum NSPIM Event)
|
||||
{
|
||||
switch(Event)
|
||||
{
|
||||
case NSPIM_UNLOAD:
|
||||
if (g_hThread) {
|
||||
//OutputDebugString("ExecShellAsUser: NSPIM_UNLOAD wait...");
|
||||
::PostMessage(g_hwnd, WM_USER+11, 0, 0);
|
||||
::WaitForSingleObject(g_hThread, INFINITE);
|
||||
::CloseHandle(g_hThread);
|
||||
//OutputDebugString("ExecShellAsUser: NSPIM_UNLOAD");
|
||||
}
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//http://brandonlive.com/2008/04/27/getting-the-shell-to-run-an-application-for-you-part-2-how/
|
||||
static CComQIPtr<IShellDispatch2> retrieveDesktop()
|
||||
{
|
||||
CComPtr<IShellWindows> psw;
|
||||
HRESULT hr = psw.CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
HWND hwnd;
|
||||
CComPtr<IDispatch> pdisp;
|
||||
VARIANT vEmpty;
|
||||
vEmpty.vt = VT_EMPTY;
|
||||
if (S_OK == (hr = psw->FindWindowSW(&vEmpty, &vEmpty, 0x8/*SWC_DESKTOP*/, (long*)&hwnd, SWFO_NEEDDISPATCH, &pdisp)))
|
||||
{
|
||||
CComPtr<IShellBrowser> psb;
|
||||
|
||||
hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, __uuidof(IShellBrowser), (void**) &psb); //IID_PPV_ARGS(&psb)
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
CComPtr<IShellView> psv;
|
||||
hr = psb->QueryActiveShellView(&psv);
|
||||
|
||||
CComPtr<IDispatch> pdispBackground;
|
||||
HRESULT hr = psv->GetItemObject(SVGIO_BACKGROUND, __uuidof(IDispatch), (void**) &pdispBackground);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (CComQIPtr<IShellFolderViewDual> psfvd = pdispBackground)
|
||||
{
|
||||
CComPtr<IDispatch> pdisp;
|
||||
hr = psfvd->get_Application(&pdisp);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
return CComQIPtr<IShellDispatch2>(pdisp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TCHAR buf[100];
|
||||
wsprintf(buf, _T("ShellExecAsUser: FindWindowSW failed: %x"), hr);
|
||||
OutputDebugString(buf);
|
||||
}
|
||||
}
|
||||
return CComQIPtr<IShellDispatch2>();
|
||||
}
|
||||
|
||||
static int getShowMode(const TCHAR* s)
|
||||
{
|
||||
if (s[0] == 0) return SW_SHOWNORMAL;
|
||||
const TCHAR* strModes[] = { _T("SW_SHOWDEFAULT"), _T("SW_SHOWNORMAL"), _T("SW_SHOWMAXIMIZED"), _T("SW_SHOWMINIMIZED"), _T("SW_HIDE") };
|
||||
int modes[] = { SW_SHOWDEFAULT, SW_SHOWNORMAL, SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED, SW_HIDE };
|
||||
for (int i=0; i<sizeof(strModes)/sizeof(TCHAR*); ++i) {
|
||||
if (lstrcmp(s, strModes[i]) == 0)
|
||||
return modes[i];
|
||||
}
|
||||
return SW_SHOWNORMAL;
|
||||
}
|
||||
|
||||
static bool runCommand(IShellDispatch2* psd, ExecShellParams* params)
|
||||
{
|
||||
if (!psd) return false;
|
||||
CComBSTR command(params->command);
|
||||
CComVariant vAction, vParams, vDir;
|
||||
if (params->action[0] != 0) vAction = params->action;
|
||||
if (params->params[0] != 0) vParams = params->params;
|
||||
if (params->directory[0] != 0) vDir = params->directory;
|
||||
CComVariant vShow;
|
||||
if (params->iShow != -1) vShow = params->iShow;
|
||||
//#pragma push_macro("ShellExecute")
|
||||
//#undef ShellExecute
|
||||
HRESULT hr = psd->ShellExecute(command, vParams, vDir, vAction, vShow);
|
||||
//#pragma pop_macro("ShellExecute")
|
||||
return hr == S_OK;
|
||||
}
|
||||
|
||||
static LRESULT WndProc(HWND hWnd, UINT uMsg,WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
void* param = ((LPCREATESTRUCT)lParam)->lpCreateParams;
|
||||
::SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)param);
|
||||
break;
|
||||
}
|
||||
case WM_USER+10:
|
||||
{
|
||||
ExecShellParams* p = (ExecShellParams*)lParam;
|
||||
IShellDispatch2* pSD = (IShellDispatch2*)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
runCommand(pSD, p);
|
||||
delete p;
|
||||
break;
|
||||
}
|
||||
case WM_USER+11:
|
||||
DestroyWindow(hWnd);
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return ::DefWindowProc(hWnd,uMsg,wParam,lParam);
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
||||
HWND CreateMessageWindow(void* data)
|
||||
{
|
||||
WNDCLASSEX wincl;
|
||||
ZeroMemory(&wincl, sizeof(WNDCLASSEX));
|
||||
wincl.hInstance = g_hInstance;
|
||||
wincl.lpszClassName = _T("NSIS_DESKTOP_LAUNCH_CLASS");
|
||||
wincl.lpfnWndProc = (WNDPROC)WndProc;
|
||||
wincl.cbSize = sizeof (WNDCLASSEX);
|
||||
|
||||
ATOM atom = RegisterClassEx (&wincl);
|
||||
|
||||
return CreateWindowEx(
|
||||
0,
|
||||
MAKEINTATOM(atom),
|
||||
_T(""),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
HWND_MESSAGE,
|
||||
NULL,
|
||||
wincl.hInstance,
|
||||
data);
|
||||
|
||||
}
|
||||
|
||||
static unsigned __stdcall WorkerThreadProc(void* pParam)
|
||||
{
|
||||
HANDLE hRunEvent = (HANDLE) pParam;
|
||||
::CoInitialize(NULL);
|
||||
{
|
||||
CComPtr<IShellDispatch2> pSD = retrieveDesktop();
|
||||
OutputDebugString(pSD.p ? _T("ExecShellAsUser: got desktop") : _T("ExecShellAsUser: failed to retrieve desktop!"));
|
||||
if (pSD.p) g_hwnd = CreateMessageWindow(pSD.p);
|
||||
SetEvent(hRunEvent);
|
||||
|
||||
if (g_hwnd) {
|
||||
MSG msg;
|
||||
while ( GetMessage(&msg, NULL, 0, 0) > 0 )
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
::CoUninitialize();
|
||||
OutputDebugString(_T("ExecShellAsUser: thread finished"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define EMPTY_TO_NULL(s) (s[0] == 0 ? NULL : s)
|
||||
|
||||
extern "C"
|
||||
void __declspec(dllexport) ShellExecAsUser(HWND hwndParent, int string_size,
|
||||
TCHAR *variables, stack_t **stacktop,
|
||||
extra_parameters *extra)
|
||||
{
|
||||
static int initDone=0;
|
||||
|
||||
g_hwndParent=hwndParent;
|
||||
|
||||
EXDLL_INIT();
|
||||
if (initDone == 0) {
|
||||
initDone=1;
|
||||
extra->RegisterPluginCallback(g_hInstance, NSISPluginCallback);
|
||||
if (IsVista() && IsElevated(NULL) == S_OK) {
|
||||
//note: COM calls to shell interfaces have to be executed on another thread,
|
||||
//otherwise I got RPC_E_CANTCALLOUT_ININPUTSYNCCALL error.
|
||||
HANDLE hRunEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); //manual reset
|
||||
g_hThread = (HANDLE)_beginthreadex( NULL, 0, WorkerThreadProc, hRunEvent, 0, NULL);
|
||||
if (g_hThread) ::WaitForSingleObject(hRunEvent, INFINITE);
|
||||
CloseHandle(hRunEvent);
|
||||
OutputDebugString(_T("ExecShellAsUser: elevated process detected"));
|
||||
} else {
|
||||
OutputDebugString(_T("ExecShellAsUser: process is not elevated, will fallback to ShellExecute"));
|
||||
}
|
||||
}
|
||||
|
||||
// action command [parameters] [SW_SHOWDEFAULT | SW_SHOWNORMAL | SW_SHOWMAXIMIZED | SW_SHOWMINIMIZED | SW_HIDE]
|
||||
ExecShellParams execShellParams;
|
||||
ExecShellParams* params = g_hwnd ? new ExecShellParams : &execShellParams;
|
||||
TCHAR show[50];
|
||||
popstring(params->action);
|
||||
popstring(params->command);
|
||||
popstring(params->params);
|
||||
popstring(show);
|
||||
params->iShow = getShowMode(show);
|
||||
TCHAR* dir = getuservariable(INST_OUTDIR);
|
||||
|
||||
if (g_hwnd) {
|
||||
if (dir) lstrcpyn(params->directory, dir, sizeof(params->directory)/sizeof(params->directory[0]));
|
||||
::PostMessage(g_hwnd, WM_USER+10, 0, (LPARAM)params);
|
||||
} else {
|
||||
::ShellExecute(NULL, EMPTY_TO_NULL(params->action), params->command, EMPTY_TO_NULL(params->params), dir, params->iShow);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
if(ul_reason_for_call==DLL_PROCESS_ATTACH)
|
||||
{
|
||||
g_hInstance = (HINSTANCE) hModule;
|
||||
} else if (ul_reason_for_call==DLL_PROCESS_DETACH) {
|
||||
OutputDebugString(_T("ExecShellAsUser: DLL_PROCESS_DETACH"));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellExecAsUser", "ShellExecAsUser.vcxproj", "{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
ReleaseUnicode|Win32 = ReleaseUnicode|Win32
|
||||
ReleaseUnicode|x64 = ReleaseUnicode|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.Debug|x64.Build.0 = Debug|x64
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.Release|Win32.Build.0 = Release|Win32
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.Release|x64.ActiveCfg = Release|x64
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.Release|x64.Build.0 = Release|x64
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.ReleaseUnicode|Win32.ActiveCfg = ReleaseUnicode|Win32
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.ReleaseUnicode|Win32.Build.0 = ReleaseUnicode|Win32
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.ReleaseUnicode|x64.ActiveCfg = ReleaseUnicode|x64
|
||||
{8384A5B1-BFFE-254C-4F8D-3C865339D9ED}.ReleaseUnicode|x64.Build.0 = ReleaseUnicode|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,394 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="ReleaseUnicode|Win32">
|
||||
<Configuration>ReleaseUnicode</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="ReleaseUnicode|x64">
|
||||
<Configuration>ReleaseUnicode</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<SccProjectName />
|
||||
<SccLocalPath />
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseUnicode|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseUnicode|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseUnicode|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseUnicode|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)..\..\Plugins\x86-ansi\</OutDir>
|
||||
<IntDir>$(SolutionDir)Intermediate\$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)..\..\Plugins\amd64-ansi\</OutDir>
|
||||
<IntDir>$(SolutionDir)Intermediate\$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseUnicode|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)Intermediate\$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\..\Plugins\x86-unicode\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseUnicode|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)Intermediate\$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\..\Plugins\amd64-unicode\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)..\..\Plugins\x86-ansi-debug\</OutDir>
|
||||
<IntDir>$(SolutionDir)Intermediate\$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)..\..\Plugins\amd64-ansi-debug\</OutDir>
|
||||
<IntDir>$(SolutionDir)Intermediate\$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StringPooling>true</StringPooling>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SHELLEXECASUSER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<AdditionalIncludeDirectories>nsis</AdditionalIncludeDirectories>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)\$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TypeLibraryName>.\Release\ShellExecAsUser.tlb</TypeLibraryName>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Release\ShellExecAsUser.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<Link>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<LinkDLL>true</LinkDLL>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<ImportLibrary>
|
||||
</ImportLibrary>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>libc.lib</IgnoreSpecificDefaultLibraries>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StringPooling>true</StringPooling>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SHELLEXECASUSER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<AdditionalIncludeDirectories>nsis</AdditionalIncludeDirectories>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)\$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TypeLibraryName>.\Release\ShellExecAsUser.tlb</TypeLibraryName>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Release\ShellExecAsUser.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<Link>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<LinkDLL>true</LinkDLL>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<ImportLibrary>
|
||||
</ImportLibrary>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>libc.lib</IgnoreSpecificDefaultLibraries>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseUnicode|Win32'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StringPooling>true</StringPooling>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SHELLEXECASUSER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<AdditionalIncludeDirectories>nsis</AdditionalIncludeDirectories>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)\$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TypeLibraryName>.\Release\ShellExecAsUser.tlb</TypeLibraryName>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Release\ShellExecAsUser.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<Link>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<LinkDLL>true</LinkDLL>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>libc.lib</IgnoreSpecificDefaultLibraries>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseUnicode|x64'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<StringPooling>true</StringPooling>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SHELLEXECASUSER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<AdditionalIncludeDirectories>nsis</AdditionalIncludeDirectories>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)\$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TypeLibraryName>.\Release\ShellExecAsUser.tlb</TypeLibraryName>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Release\ShellExecAsUser.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<Link>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<LinkDLL>true</LinkDLL>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>libc.lib</IgnoreSpecificDefaultLibraries>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SHELLEXECASUSER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)\$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TypeLibraryName>.\Debug\ShellExecAsUser.tlb</TypeLibraryName>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Debug\ShellExecAsUser.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<Link>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<LinkDLL>true</LinkDLL>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<ImportLibrary>
|
||||
</ImportLibrary>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SHELLEXECASUSER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)\$(TargetName).pch</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TypeLibraryName>.\Debug\ShellExecAsUser.tlb</TypeLibraryName>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Debug\ShellExecAsUser.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<Link>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<LinkDLL>true</LinkDLL>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<ImportLibrary>
|
||||
</ImportLibrary>
|
||||
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pluginapi.cpp" />
|
||||
<ClCompile Include="ShellExecAsUser.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="api.h" />
|
||||
<ClInclude Include="nsis_tchar.h" />
|
||||
<ClInclude Include="pluginapi.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ShellExecAsUser.cpp" />
|
||||
<ClCompile Include="pluginapi.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="api.h" />
|
||||
<ClInclude Include="nsis_tchar.h" />
|
||||
<ClInclude Include="pluginapi.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,713 @@
|
||||
///////////////////////////////
|
||||
/* VistaTools.cxx - version 2.1
|
||||
|
||||
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
PARTICULAR PURPOSE.
|
||||
|
||||
Copyright (C) 2008. WinAbility Software Corporation. All rights reserved.
|
||||
|
||||
Author: Andrei Belogortseff [ http://www.softblog.com ]
|
||||
|
||||
TERMS OF USE: You are free to use this file in any way you like,
|
||||
for both the commercial and non-commercial purposes, royalty-free,
|
||||
AS LONG AS you agree with the warranty disclaimer above,
|
||||
EXCEPT that you may not remove or modify this or any of the
|
||||
preceeding paragraphs. If you make any changes, please document
|
||||
them in the MODIFICATIONS section below. If the changes are of general
|
||||
interest, please let us know and we will consider incorporating them in
|
||||
this file, as well.
|
||||
|
||||
If you use this file in your own project, an acknowledgment will be appreciated,
|
||||
although it's not required.
|
||||
|
||||
SUMMARY:
|
||||
|
||||
This file contains several Vista-specific functions helpful when dealing with the
|
||||
"elevation" features of Windows Vista. See the descriptions of the functions below
|
||||
for information on what each function does and how to use it.
|
||||
|
||||
This file contains the Win32 stuff only, it can be used with or without other frameworks,
|
||||
such as MFC, ATL, etc.
|
||||
|
||||
HOW TO USE THIS FILE:
|
||||
|
||||
Make sure you have the latest Windows SDK (see msdn.microsoft.com for more information)
|
||||
or this file may not compile!
|
||||
|
||||
This is a "combo" file that contains both the declarations (usually placed in the .h files)
|
||||
as well as the definitions (usually placed in the .cpp files) of the functions.
|
||||
|
||||
To get the declarations only, include it as you would any .h file, for example:
|
||||
|
||||
#include "VistaTools.cxx"
|
||||
|
||||
To get both the declarations and definitions, define IMPLEMENT_VISTA_TOOLS before including the file:
|
||||
|
||||
#define IMPLEMENT_VISTA_TOOLS
|
||||
#include "VistaTools.cxx"
|
||||
|
||||
(The above should be done once and only once per project).
|
||||
|
||||
To use the function RunNonElevated, this file must be compiled into a DLL.
|
||||
In such a case, define DLL_EXPORTS when compiling the DLL,
|
||||
and do not define DLL_EXPORTS when compiling the projects linking to the DLL.
|
||||
|
||||
If you don't need to use RunNonElevated, then this file may be a part of an EXE
|
||||
project. In such a case, define DONTWANT_RunNonElevated and NO_DLL_IMPORTS to make
|
||||
this file compile properly.
|
||||
|
||||
NOTE: The file VistaTools.cxx can be included in the VisualStudio projects, but it should be
|
||||
excluded from the build process (because its contents is compiled when it is included
|
||||
in another .cpp file with IMPLEMENT_VISTA_TOOLS defined, as shown above.)
|
||||
|
||||
MODIFICATIONS:
|
||||
v.1.0 (2006-Dec-16) created by Andrei Belogortseff.
|
||||
|
||||
v.2.0 (2007-Feb-20) deprecated RunAsStdUser();
|
||||
implemented RunNonElevated() to replace RunAsStdUser();
|
||||
added function declarations for use in a DLL project
|
||||
|
||||
v.2.1 (2008-Feb-24) removed RunAsStdUser();
|
||||
*/
|
||||
|
||||
#if ( NTDDI_VERSION < NTDDI_LONGHORN )
|
||||
# error NTDDI_VERSION must be defined as NTDDI_LONGHORN or later
|
||||
#endif
|
||||
|
||||
#if !defined(NTDDI_VISTA) || defined(BUILD_OLDSDK)
|
||||
|
||||
typedef enum _TOKEN_ELEVATION_TYPE {
|
||||
TokenElevationTypeDefault = 1,
|
||||
TokenElevationTypeFull,
|
||||
TokenElevationTypeLimited,
|
||||
} TOKEN_ELEVATION_TYPE, *PTOKEN_ELEVATION_TYPE;
|
||||
|
||||
typedef struct _TOKEN_ELEVATION {
|
||||
DWORD TokenIsElevated;
|
||||
} TOKEN_ELEVATION, *PTOKEN_ELEVATION;
|
||||
|
||||
enum _TOKEN_INFORMATION_CLASS___VISTA {
|
||||
TokenElevationType = (TokenOrigin+1),
|
||||
TokenLinkedToken,
|
||||
TokenElevation,
|
||||
TokenHasRestrictions,
|
||||
TokenAccessInformation,
|
||||
TokenVirtualizationAllowed,
|
||||
TokenVirtualizationEnabled,
|
||||
TokenIntegrityLevel,
|
||||
TokenUIAccess,
|
||||
TokenMandatoryPolicy,
|
||||
TokenLogonSid,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// if ASSERT was not defined already, let's define our own version,
|
||||
// to use the CRT assert()
|
||||
|
||||
#ifndef ASSERT
|
||||
# ifdef _DEBUG
|
||||
# include <assert.h>
|
||||
# define ASSERT(x) assert( x )
|
||||
# define ASSERT_HERE assert( FALSE )
|
||||
# else// _DEBUG
|
||||
# define ASSERT(x)
|
||||
# define ASSERT_HERE
|
||||
# endif//_DEBUG
|
||||
#endif//ASSERT
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// a handy macro to get the number of characters (not bytes!)
|
||||
// a string buffer can hold
|
||||
|
||||
#ifndef _tsizeof
|
||||
# define _tsizeof( s ) (sizeof(s)/sizeof(s[0]))
|
||||
#endif//_tsizeof
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// macros to handle the functions implemented in a DLL properly
|
||||
|
||||
#ifdef DLL_EXPORTS
|
||||
# define DLL_API __declspec(dllexport)
|
||||
#else
|
||||
# ifndef NO_DLL_IMPORTS
|
||||
# define DLL_API __declspec(dllimport)
|
||||
# else
|
||||
# define DLL_API
|
||||
# endif
|
||||
#endif
|
||||
|
||||
BOOL DLL_API
|
||||
IsVista();
|
||||
|
||||
/*
|
||||
Use IsVista() to determine whether the current process is running under Windows Vista or
|
||||
(or a later version of Windows, whatever it will be)
|
||||
|
||||
Return Values:
|
||||
If the function succeeds, and the current version of Windows is Vista or later,
|
||||
the return value is TRUE.
|
||||
If the function fails, or if the current version of Windows is older than Vista
|
||||
(that is, if it is Windows XP, Windows 2000, Windows Server 2003, Windows 98, etc.)
|
||||
the return value is FALSE.
|
||||
*/
|
||||
|
||||
#ifndef WIN64
|
||||
|
||||
BOOL DLL_API
|
||||
IsWow64();
|
||||
|
||||
/*
|
||||
Use IsWow64() to determine whether the current 32-bit process is running under 64-bit Windows
|
||||
(Vista or XP)
|
||||
|
||||
Return Values:
|
||||
If the function succeeds, and the current version of Windows is x64,
|
||||
the return value is TRUE.
|
||||
If the function fails, or if the current version of Windows is 32-bit,
|
||||
the return value is FALSE.
|
||||
|
||||
While this function is not Vista specific (it works under XP as well),
|
||||
we include it here to be able to prevent execution of the 32-bit code under 64-bit Windows,
|
||||
when required.
|
||||
*/
|
||||
|
||||
#endif//WIN64
|
||||
|
||||
|
||||
HRESULT DLL_API
|
||||
GetElevationType( __out TOKEN_ELEVATION_TYPE * ptet );
|
||||
|
||||
/*
|
||||
Use GetElevationType() to determine the elevation type of the current process.
|
||||
|
||||
Parameters:
|
||||
|
||||
ptet
|
||||
[out] Pointer to a variable that receives the elevation type of the current process.
|
||||
|
||||
The possible values are:
|
||||
|
||||
TokenElevationTypeDefault - User is not using a "split" token.
|
||||
This value indicates that either UAC is disabled, or the process is started
|
||||
by a standard user (not a member of the Administrators group).
|
||||
|
||||
The following two values can be returned only if both the UAC is enabled and
|
||||
the user is a member of the Administrator's group (that is, the user has a "split" token):
|
||||
|
||||
TokenElevationTypeFull - the process is running elevated.
|
||||
|
||||
TokenElevationTypeLimited - the process is not running elevated.
|
||||
|
||||
Return Values:
|
||||
If the function succeeds, the return value is S_OK.
|
||||
If the function fails, the return value is E_FAIL. To get extended error information,
|
||||
call GetLastError().
|
||||
*/
|
||||
|
||||
HRESULT DLL_API
|
||||
IsElevated( __out_opt BOOL * pbElevated = NULL );
|
||||
|
||||
/*
|
||||
Use IsElevated() to determine whether the current process is elevated or not.
|
||||
|
||||
Parameters:
|
||||
|
||||
pbElevated
|
||||
[out] [optional] Pointer to a BOOL variable that, if non-NULL, receives the result.
|
||||
|
||||
The possible values are:
|
||||
|
||||
TRUE - the current process is elevated.
|
||||
This value indicates that either UAC is enabled, and the process was elevated by
|
||||
the administrator, or that UAC is disabled and the process was started by a user
|
||||
who is a member of the Administrators group.
|
||||
|
||||
FALSE - the current process is not elevated (limited).
|
||||
This value indicates that either UAC is enabled, and the process was started normally,
|
||||
without the elevation, or that UAC is disabled and the process was started by a standard user.
|
||||
|
||||
Return Values
|
||||
If the function succeeds, and the current process is elevated, the return value is S_OK.
|
||||
If the function succeeds, and the current process is not elevated, the return value is S_FALSE.
|
||||
If the function fails, the return value is E_FAIL. To get extended error information,
|
||||
call GetLastError().
|
||||
*/
|
||||
|
||||
BOOL DLL_API
|
||||
RunElevated(
|
||||
__in HWND hwnd,
|
||||
__in LPCTSTR pszPath,
|
||||
__in_opt LPCTSTR pszParameters = NULL,
|
||||
__in_opt LPCTSTR pszDirectory = NULL );
|
||||
|
||||
/*
|
||||
Use RunElevated() to start an elevated process. This function calls ShellExecEx() with the verb "runas"
|
||||
to start the elevated process.
|
||||
|
||||
Parameters:
|
||||
|
||||
hwnd
|
||||
[in] Window handle to any message boxes that the system might produce while executing this function.
|
||||
|
||||
pszPath
|
||||
[in] Address of a null-terminated string that specifies the name of the executable file that
|
||||
should be used to start the process.
|
||||
|
||||
pszParameters
|
||||
[in] [optional] Address of a null-terminated string that contains the command-line parameters for the process.
|
||||
If NULL, no parameters are passed to the process.
|
||||
|
||||
pszDirectory
|
||||
[in] [optional] Address of a null-terminated string that specifies the name of the working directory.
|
||||
If NULL, the current directory is used as the working directory. .
|
||||
|
||||
Return Values
|
||||
If the function succeeds, the return value is TRUE.
|
||||
If the function fails, the return value is FALSE. To get extended error information,
|
||||
call GetLastError().
|
||||
|
||||
NOTE: This function will start a process elevated no matter which attribute (asInvoker,
|
||||
highestAvailable, or requireAdministrator) is specified in its manifest, and even if
|
||||
there is no such attribute at all.
|
||||
*/
|
||||
|
||||
#ifndef DONTWANT_RunNonElevated
|
||||
|
||||
#ifdef NO_DLL_IMPORTS
|
||||
# error RunNonElevated must be used in a DLL project!
|
||||
#endif//NO_DLL_IMPORTS
|
||||
|
||||
|
||||
BOOL DLL_API
|
||||
RunNonElevated(
|
||||
__in HWND hwnd,
|
||||
__in LPCTSTR pszPath,
|
||||
__in_opt LPCTSTR pszParameters = NULL,
|
||||
__in_opt LPCTSTR pszDirectory = NULL );
|
||||
|
||||
/*
|
||||
Use RunNonElevated() to start a non-elevated process. If the current process is not elevated,
|
||||
it calls ShellExecuteEx() to start the new process. If the current process is elevated,
|
||||
it injects itself into the (non-elevated) shell process, and starts a non-elevated process from there.
|
||||
|
||||
Parameters:
|
||||
|
||||
hwnd
|
||||
[in] Window handle to any message boxes that the system might produce while executing this function.
|
||||
|
||||
pszPath
|
||||
[in] Address of a null-terminated string that specifies the executable file that
|
||||
should be used to start the process.
|
||||
|
||||
pszParameters
|
||||
[in] [optional] Address of a null-terminated string that contains the command-line parameters for
|
||||
the process. If NULL, no parameters are passed to the process.
|
||||
|
||||
pszDirectory
|
||||
[in] [optional] Address of a null-terminated string that specifies the name of the working directory.
|
||||
If NULL, the current directory is used as the working directory. .
|
||||
|
||||
Return Values
|
||||
If the function succeeds, the return value is TRUE.
|
||||
If the function fails, the return value is FALSE. To get extended error information,
|
||||
call GetLastError().
|
||||
|
||||
NOTE: For this function to work, the application must be marked with the asInvoker or
|
||||
highestAvailable attributes in its manifest. If the executable to be started is marked
|
||||
as requireAdministrator, it will be started elevated!
|
||||
*/
|
||||
#endif //DONTWANT_RunNonElevated
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// MyShellExec is just a wrapper around a call to ShellExecuteEx,
|
||||
// to be able to specify the verb easily.
|
||||
|
||||
BOOL DLL_API
|
||||
MyShellExec( HWND hwnd,
|
||||
LPCTSTR pszVerb,
|
||||
LPCTSTR pszPath,
|
||||
LPCTSTR pszParameters = NULL,
|
||||
int nShow = SW_SHOWNORMAL);
|
||||
|
||||
|
||||
#ifdef IMPLEMENT_VISTA_TOOLS
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// MyShellExec is just a wrapper around a call to ShellExecuteEx,
|
||||
// to be able to specify the verb easily.
|
||||
|
||||
/*
|
||||
BOOL
|
||||
MyShellExec( HWND hwnd,
|
||||
LPCTSTR pszVerb,
|
||||
LPCTSTR pszPath,
|
||||
LPCTSTR pszParameters, // = NULL,
|
||||
int nShow)
|
||||
{
|
||||
SHELLEXECUTEINFO shex;
|
||||
|
||||
memset( &shex, 0, sizeof( shex) );
|
||||
|
||||
shex.cbSize = sizeof( SHELLEXECUTEINFO );
|
||||
shex.fMask = 0;
|
||||
shex.hwnd = hwnd;
|
||||
shex.lpVerb = pszVerb;
|
||||
shex.lpFile = pszPath;
|
||||
shex.lpParameters = pszParameters;
|
||||
shex.lpDirectory = NULL;
|
||||
shex.nShow = nShow;
|
||||
|
||||
return ::ShellExecuteEx( &shex );
|
||||
}
|
||||
*/
|
||||
|
||||
BOOL IsVista()
|
||||
{
|
||||
OSVERSIONINFOEX osver;
|
||||
DWORDLONG dwlConditionMask = 0;
|
||||
int op = VER_GREATER_EQUAL;
|
||||
|
||||
ZeroMemory(&osver, sizeof(OSVERSIONINFOEX));
|
||||
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||
osver.dwMajorVersion = 6;
|
||||
osver.dwMinorVersion = 0;
|
||||
osver.dwPlatformId = VER_PLATFORM_WIN32_NT;
|
||||
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
|
||||
VER_SET_CONDITION(dwlConditionMask, VER_PLATFORMID, VER_EQUAL);
|
||||
|
||||
return VerifyVersionInfo(&osver, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID, dwlConditionMask);
|
||||
}
|
||||
|
||||
#ifndef WIN64 // we need this when compiling 32-bit code only
|
||||
|
||||
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE hProcess,PBOOL Wow64Process);
|
||||
|
||||
LPFN_ISWOW64PROCESS fnIsWow64Process =
|
||||
(LPFN_ISWOW64PROCESS)::GetProcAddress( ::GetModuleHandle(_T("kernel32")),"IsWow64Process");
|
||||
|
||||
BOOL
|
||||
IsWow64()
|
||||
{
|
||||
BOOL bIsWow64 = FALSE;
|
||||
|
||||
if (NULL != fnIsWow64Process)
|
||||
{
|
||||
if ( !fnIsWow64Process( ::GetCurrentProcess(),&bIsWow64) )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
}
|
||||
}
|
||||
|
||||
return bIsWow64;
|
||||
}
|
||||
|
||||
#endif//WIN64
|
||||
|
||||
HRESULT
|
||||
GetElevationType( __out TOKEN_ELEVATION_TYPE * ptet )
|
||||
{
|
||||
ASSERT( IsVista() );
|
||||
ASSERT( ptet );
|
||||
|
||||
HRESULT hResult = E_FAIL; // assume an error occured
|
||||
HANDLE hToken = NULL;
|
||||
|
||||
if ( !::OpenProcessToken(
|
||||
::GetCurrentProcess(),
|
||||
TOKEN_QUERY,
|
||||
&hToken ) )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
return hResult;
|
||||
}
|
||||
|
||||
DWORD dwReturnLength = 0;
|
||||
|
||||
if ( !::GetTokenInformation(
|
||||
hToken,
|
||||
(_TOKEN_INFORMATION_CLASS)TokenElevationType,
|
||||
ptet,
|
||||
sizeof( *ptet ),
|
||||
&dwReturnLength ) )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT( dwReturnLength == sizeof( *ptet ) );
|
||||
hResult = S_OK;
|
||||
}
|
||||
|
||||
::CloseHandle( hToken );
|
||||
|
||||
return hResult;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
IsElevated( __out_opt BOOL * pbElevated ) //= NULL )
|
||||
{
|
||||
ASSERT( IsVista() );
|
||||
|
||||
HRESULT hResult = E_FAIL; // assume an error occured
|
||||
HANDLE hToken = NULL;
|
||||
|
||||
if ( !::OpenProcessToken(
|
||||
::GetCurrentProcess(),
|
||||
TOKEN_QUERY,
|
||||
&hToken ) )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
return hResult;
|
||||
}
|
||||
|
||||
TOKEN_ELEVATION te = { 0 };
|
||||
DWORD dwReturnLength = 0;
|
||||
|
||||
if ( !::GetTokenInformation(
|
||||
hToken,
|
||||
(_TOKEN_INFORMATION_CLASS)TokenElevation,
|
||||
&te,
|
||||
sizeof( te ),
|
||||
&dwReturnLength ) )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT( dwReturnLength == sizeof( te ) );
|
||||
|
||||
hResult = te.TokenIsElevated ? S_OK : S_FALSE;
|
||||
|
||||
if ( pbElevated)
|
||||
*pbElevated = (te.TokenIsElevated != 0);
|
||||
}
|
||||
|
||||
::CloseHandle( hToken );
|
||||
|
||||
return hResult;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// RunElevated simply calls ShellExecuteEx with the verb "runas" to start the elevated process.
|
||||
// I wish there was a just as easy way to start a non-elevated process, as well.
|
||||
/*
|
||||
BOOL
|
||||
RunElevated(
|
||||
__in HWND hwnd,
|
||||
__in LPCTSTR pszPath,
|
||||
__in_opt LPCTSTR pszParameters, // = NULL,
|
||||
__in_opt LPCTSTR pszDirectory ) // = NULL );
|
||||
{
|
||||
return MyShellExec( hwnd, _T("runas"), pszPath, pszParameters );
|
||||
}
|
||||
*/
|
||||
|
||||
#ifndef DONTWANT_RunNonElevated
|
||||
///////////////////////////////////////
|
||||
// RunNonElevated() implementation
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// The shared data, to be able to share
|
||||
// data between ours and the shell proceses
|
||||
|
||||
#pragma section( "ve_shared", read, write, shared )
|
||||
|
||||
__declspec(allocate("ve_shared"))
|
||||
HHOOK hHook = NULL;
|
||||
|
||||
__declspec(allocate("ve_shared"))
|
||||
UINT uVistaElevatorMsg = 0;
|
||||
|
||||
__declspec(allocate("ve_shared"))
|
||||
BOOL bSuccess = FALSE;
|
||||
|
||||
__declspec(allocate("ve_shared"))
|
||||
TCHAR szVE_Path[ MAX_PATH ] = _T("");
|
||||
|
||||
__declspec(allocate("ve_shared"))
|
||||
TCHAR szVE_Parameters[ MAX_PATH ] = _T("");
|
||||
|
||||
__declspec(allocate("ve_shared"))
|
||||
TCHAR szVE_Directory[ MAX_PATH ] = _T("");
|
||||
|
||||
//////////////////////////////////e
|
||||
// the hook callback procedure, it is called in the context of th shell proces
|
||||
|
||||
LRESULT CALLBACK
|
||||
VistaEelevator_HookProc_MsgRet( int code, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
if ( code >= 0 && lParam )
|
||||
{
|
||||
CWPRETSTRUCT * pwrs = (CWPRETSTRUCT *)lParam;
|
||||
|
||||
if (pwrs->message == uVistaElevatorMsg )
|
||||
{
|
||||
bSuccess = ::MyShellExec(
|
||||
pwrs->hwnd,
|
||||
NULL,
|
||||
szVE_Path,
|
||||
szVE_Parameters,
|
||||
szVE_Directory );
|
||||
}
|
||||
}
|
||||
|
||||
return ::CallNextHookEx( hHook, code, wParam, lParam );
|
||||
}
|
||||
|
||||
BOOL
|
||||
RunNonElevated(
|
||||
__in HWND hwnd,
|
||||
__in LPCTSTR pszPath,
|
||||
__in_opt LPCTSTR pszParameters, // = NULL,
|
||||
__in_opt LPCTSTR pszDirectory ) // = NULL );
|
||||
{
|
||||
ASSERT( pszPath && *pszPath ); // other args are optional
|
||||
|
||||
ASSERT( IsVista() );
|
||||
ASSERT( pszPath );
|
||||
|
||||
if ( S_FALSE == IsElevated() )
|
||||
{
|
||||
// if the current process is not elevated, we can use ShellExecuteAs directly!
|
||||
|
||||
return MyShellExec( hwnd,
|
||||
NULL,
|
||||
pszPath,
|
||||
pszParameters,
|
||||
pszDirectory );
|
||||
}
|
||||
|
||||
#ifndef WIN64
|
||||
|
||||
// If 32-bit code is executing under x64 version of Windows, it will not work, because
|
||||
// the shell is a 64-bit process, and to hook it successfully this code needs to be 64-bit as well
|
||||
|
||||
if ( IsWow64() )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif//WIN64
|
||||
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
// How this code works:
|
||||
//
|
||||
// To start a non-elevated process, we need to inject our code into a non-elevated
|
||||
// process already running on the target computer. Since Windows shell is non-elevated,
|
||||
// and we can safely assume it to always run, (when was the last time you saw Windows
|
||||
// running without its shell?), we will try to inject our code into the shell process.
|
||||
//
|
||||
// To inject the code, we will install a global hook, and send a message to
|
||||
// a window created by the shell. This will cause our hook callback procedure to be executed
|
||||
// in the context of the shell proces.
|
||||
//
|
||||
// Because this trick uses a global hook, the hook procedure must be in a DLL.
|
||||
//
|
||||
|
||||
/////////////////////
|
||||
// First, register a private message, to communicate with the (hooked) shell process
|
||||
|
||||
if ( !uVistaElevatorMsg )
|
||||
uVistaElevatorMsg = ::RegisterWindowMessage( _T("VistaElevatorMsg") );
|
||||
|
||||
//////////////////////////////////////
|
||||
// Find the shell window (the desktop)
|
||||
|
||||
HWND hwndShell = ::FindWindow( _T("Progman"), NULL);
|
||||
|
||||
if ( !hwndShell )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Install a global hook, to inject our code into the shell proces
|
||||
|
||||
HMODULE hModule = NULL; // we need to know hModule of the DLL to install a global hook
|
||||
|
||||
if ( !::GetModuleHandleEx(
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
(LPCTSTR)VistaEelevator_HookProc_MsgRet,
|
||||
&hModule ) )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ASSERT( hModule );
|
||||
|
||||
hHook = ::SetWindowsHookEx( WH_CALLWNDPROCRET, // hook called after SendMessage() !!!
|
||||
(HOOKPROC)VistaEelevator_HookProc_MsgRet, hModule, 0);
|
||||
|
||||
if ( !hHook )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
// Prepare the parameters for launching the non-elevated process
|
||||
// from the hook callback procedure (they are placed into the shared data section)
|
||||
|
||||
if ( FAILED( StringCchCopy(
|
||||
szVE_Path,
|
||||
_tsizeof(szVE_Path),
|
||||
pszPath ) ) )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( FAILED( StringCchCopy(
|
||||
szVE_Parameters,
|
||||
_tsizeof(szVE_Parameters),
|
||||
pszParameters ? pszParameters : _T("") ) ) )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( FAILED( StringCchCopy(
|
||||
szVE_Directory,
|
||||
_tsizeof(szVE_Directory),
|
||||
pszDirectory ? pszDirectory : _T("") ) ) )
|
||||
{
|
||||
ASSERT_HERE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Activate our hook callback procedure:
|
||||
|
||||
bSuccess = FALSE; // assume failure
|
||||
|
||||
::SendMessage( hwndShell, uVistaElevatorMsg, 0, 0 );
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// At this point our hook procedure has been executed!
|
||||
|
||||
/////////////////////////////////////
|
||||
// The hook is no longer needed, remove it:
|
||||
|
||||
::UnhookWindowsHookEx( hHook );
|
||||
hHook = NULL;
|
||||
|
||||
//////////////////////
|
||||
// All done!
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
#endif //DONTWANT_RunNonElevated
|
||||
|
||||
|
||||
#endif// IMPLEMENT_VISTA_TOOLS
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* apih
|
||||
*
|
||||
* This file is a part of NSIS.
|
||||
*
|
||||
* Copyright (C) 1999-2013 Nullsoft and Contributors
|
||||
*
|
||||
* Licensed under the zlib/libpng license (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
*
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty.
|
||||
*/
|
||||
|
||||
#ifndef _NSIS_EXEHEAD_API_H_
|
||||
#define _NSIS_EXEHEAD_API_H_
|
||||
|
||||
// Starting with NSIS 2.42, you can check the version of the plugin API in exec_flags->plugin_api_version
|
||||
// The format is 0xXXXXYYYY where X is the major version and Y is the minor version (MAKELONG(y,x))
|
||||
// When doing version checks, always remember to use >=, ex: if (pX->exec_flags->plugin_api_version >= NSISPIAPIVER_1_0) {}
|
||||
|
||||
#define NSISPIAPIVER_1_0 0x00010000
|
||||
#define NSISPIAPIVER_CURR NSISPIAPIVER_1_0
|
||||
|
||||
// NSIS Plug-In Callback Messages
|
||||
enum NSPIM
|
||||
{
|
||||
NSPIM_UNLOAD, // This is the last message a plugin gets, do final cleanup
|
||||
NSPIM_GUIUNLOAD, // Called after .onGUIEnd
|
||||
};
|
||||
|
||||
// Prototype for callbacks registered with extra_parameters->RegisterPluginCallback()
|
||||
// Return NULL for unknown messages
|
||||
// Should always be __cdecl for future expansion possibilities
|
||||
typedef UINT_PTR (*NSISPLUGINCALLBACK)(enum NSPIM);
|
||||
|
||||
// extra_parameters data structures containing other interesting stuff
|
||||
// but the stack, variables and HWND passed on to plug-ins.
|
||||
typedef struct
|
||||
{
|
||||
int autoclose;
|
||||
int all_user_var;
|
||||
int exec_error;
|
||||
int abort;
|
||||
int exec_reboot; // NSIS_SUPPORT_REBOOT
|
||||
int reboot_called; // NSIS_SUPPORT_REBOOT
|
||||
int XXX_cur_insttype; // depreacted
|
||||
int plugin_api_version; // see NSISPIAPIVER_CURR
|
||||
// used to be XXX_insttype_changed
|
||||
int silent; // NSIS_CONFIG_SILENT_SUPPORT
|
||||
int instdir_error;
|
||||
int rtl;
|
||||
int errlvl;
|
||||
int alter_reg_view;
|
||||
int status_update;
|
||||
} exec_flags_t;
|
||||
|
||||
#ifndef NSISCALL
|
||||
# define NSISCALL __stdcall
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
exec_flags_t *exec_flags;
|
||||
int (NSISCALL *ExecuteCodeSegment)(int, HWND);
|
||||
void (NSISCALL *validate_filename)(TCHAR *);
|
||||
int (NSISCALL *RegisterPluginCallback)(HMODULE, NSISPLUGINCALLBACK); // returns 0 on success, 1 if already registered and < 0 on errors
|
||||
} extra_parameters;
|
||||
|
||||
// Definitions for page showing plug-ins
|
||||
// See Ui.c to understand better how they're used
|
||||
|
||||
// sent to the outer window to tell it to go to the next inner window
|
||||
#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
|
||||
|
||||
// custom pages should send this message to let NSIS know they're ready
|
||||
#define WM_NOTIFY_CUSTOM_READY (WM_USER+0xd)
|
||||
|
||||
// sent as wParam with WM_NOTIFY_OUTER_NEXT when user cancels - heed its warning
|
||||
#define NOTIFY_BYE_BYE 'x'
|
||||
|
||||
#endif /* _PLUGIN_H_ */
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* nsis_tchar.h
|
||||
*
|
||||
* This file is a part of NSIS.
|
||||
*
|
||||
* Copyright (C) 1999-2013 Nullsoft and Contributors
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty.
|
||||
*
|
||||
* For Unicode support by Jim Park -- 08/30/2007
|
||||
*/
|
||||
|
||||
// Jim Park: Only those we use are listed here.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef _UNICODE
|
||||
|
||||
#ifndef _T
|
||||
#define __T(x) L ## x
|
||||
#define _T(x) __T(x)
|
||||
#define _TEXT(x) __T(x)
|
||||
#endif
|
||||
|
||||
#ifndef _TCHAR_DEFINED
|
||||
#define _TCHAR_DEFINED
|
||||
#if !defined(_NATIVE_WCHAR_T_DEFINED) && !defined(_WCHAR_T_DEFINED)
|
||||
typedef unsigned short TCHAR;
|
||||
#else
|
||||
typedef wchar_t TCHAR;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// program
|
||||
#define _tenviron _wenviron
|
||||
#define __targv __wargv
|
||||
|
||||
// printfs
|
||||
#define _ftprintf fwprintf
|
||||
#define _sntprintf _snwprintf
|
||||
#if (defined(_MSC_VER) && (_MSC_VER<=1310)) || defined(__MINGW32__)
|
||||
# define _stprintf swprintf
|
||||
#else
|
||||
# define _stprintf _swprintf
|
||||
#endif
|
||||
#define _tprintf wprintf
|
||||
#define _vftprintf vfwprintf
|
||||
#define _vsntprintf _vsnwprintf
|
||||
#if defined(_MSC_VER) && (_MSC_VER<=1310)
|
||||
# define _vstprintf vswprintf
|
||||
#else
|
||||
# define _vstprintf _vswprintf
|
||||
#endif
|
||||
|
||||
// scanfs
|
||||
#define _tscanf wscanf
|
||||
#define _stscanf swscanf
|
||||
|
||||
// string manipulations
|
||||
#define _tcscat wcscat
|
||||
#define _tcschr wcschr
|
||||
#define _tcsclen wcslen
|
||||
#define _tcscpy wcscpy
|
||||
#define _tcsdup _wcsdup
|
||||
#define _tcslen wcslen
|
||||
#define _tcsnccpy wcsncpy
|
||||
#define _tcsncpy wcsncpy
|
||||
#define _tcsrchr wcsrchr
|
||||
#define _tcsstr wcsstr
|
||||
#define _tcstok wcstok
|
||||
|
||||
// string comparisons
|
||||
#define _tcscmp wcscmp
|
||||
#define _tcsicmp _wcsicmp
|
||||
#define _tcsncicmp _wcsnicmp
|
||||
#define _tcsncmp wcsncmp
|
||||
#define _tcsnicmp _wcsnicmp
|
||||
|
||||
// upper / lower
|
||||
#define _tcslwr _wcslwr
|
||||
#define _tcsupr _wcsupr
|
||||
#define _totlower towlower
|
||||
#define _totupper towupper
|
||||
|
||||
// conversions to numbers
|
||||
#define _tcstoi64 _wcstoi64
|
||||
#define _tcstol wcstol
|
||||
#define _tcstoul wcstoul
|
||||
#define _tstof _wtof
|
||||
#define _tstoi _wtoi
|
||||
#define _tstoi64 _wtoi64
|
||||
#define _ttoi _wtoi
|
||||
#define _ttoi64 _wtoi64
|
||||
#define _ttol _wtol
|
||||
|
||||
// conversion from numbers to strings
|
||||
#define _itot _itow
|
||||
#define _ltot _ltow
|
||||
#define _i64tot _i64tow
|
||||
#define _ui64tot _ui64tow
|
||||
|
||||
// file manipulations
|
||||
#define _tfopen _wfopen
|
||||
#define _topen _wopen
|
||||
#define _tremove _wremove
|
||||
#define _tunlink _wunlink
|
||||
|
||||
// reading and writing to i/o
|
||||
#define _fgettc fgetwc
|
||||
#define _fgetts fgetws
|
||||
#define _fputts fputws
|
||||
#define _gettchar getwchar
|
||||
|
||||
// directory
|
||||
#define _tchdir _wchdir
|
||||
|
||||
// environment
|
||||
#define _tgetenv _wgetenv
|
||||
#define _tsystem _wsystem
|
||||
|
||||
// time
|
||||
#define _tcsftime wcsftime
|
||||
|
||||
#else // ANSI
|
||||
|
||||
#ifndef _T
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#ifndef _TCHAR_DEFINED
|
||||
#define _TCHAR_DEFINED
|
||||
typedef char TCHAR;
|
||||
#endif
|
||||
|
||||
// program
|
||||
#define _tenviron environ
|
||||
#define __targv __argv
|
||||
|
||||
// printfs
|
||||
#define _ftprintf fprintf
|
||||
#define _sntprintf _snprintf
|
||||
#define _stprintf sprintf
|
||||
#define _tprintf printf
|
||||
#define _vftprintf vfprintf
|
||||
#define _vsntprintf _vsnprintf
|
||||
#define _vstprintf vsprintf
|
||||
|
||||
// scanfs
|
||||
#define _tscanf scanf
|
||||
#define _stscanf sscanf
|
||||
|
||||
// string manipulations
|
||||
#define _tcscat strcat
|
||||
#define _tcschr strchr
|
||||
#define _tcsclen strlen
|
||||
#define _tcscnlen strnlen
|
||||
#define _tcscpy strcpy
|
||||
#define _tcsdup _strdup
|
||||
#define _tcslen strlen
|
||||
#define _tcsnccpy strncpy
|
||||
#define _tcsrchr strrchr
|
||||
#define _tcsstr strstr
|
||||
#define _tcstok strtok
|
||||
|
||||
// string comparisons
|
||||
#define _tcscmp strcmp
|
||||
#define _tcsicmp _stricmp
|
||||
#define _tcsncmp strncmp
|
||||
#define _tcsncicmp _strnicmp
|
||||
#define _tcsnicmp _strnicmp
|
||||
|
||||
// upper / lower
|
||||
#define _tcslwr _strlwr
|
||||
#define _tcsupr _strupr
|
||||
|
||||
#define _totupper toupper
|
||||
#define _totlower tolower
|
||||
|
||||
// conversions to numbers
|
||||
#define _tcstol strtol
|
||||
#define _tcstoul strtoul
|
||||
#define _tstof atof
|
||||
#define _tstoi atoi
|
||||
#define _tstoi64 _atoi64
|
||||
#define _tstoi64 _atoi64
|
||||
#define _ttoi atoi
|
||||
#define _ttoi64 _atoi64
|
||||
#define _ttol atol
|
||||
|
||||
// conversion from numbers to strings
|
||||
#define _i64tot _i64toa
|
||||
#define _itot _itoa
|
||||
#define _ltot _ltoa
|
||||
#define _ui64tot _ui64toa
|
||||
|
||||
// file manipulations
|
||||
#define _tfopen fopen
|
||||
#define _topen _open
|
||||
#define _tremove remove
|
||||
#define _tunlink _unlink
|
||||
|
||||
// reading and writing to i/o
|
||||
#define _fgettc fgetc
|
||||
#define _fgetts fgets
|
||||
#define _fputts fputs
|
||||
#define _gettchar getchar
|
||||
|
||||
// directory
|
||||
#define _tchdir _chdir
|
||||
|
||||
// environment
|
||||
#define _tgetenv getenv
|
||||
#define _tsystem system
|
||||
|
||||
// time
|
||||
#define _tcsftime strftime
|
||||
|
||||
#endif
|
||||
|
||||
// is functions (the same in Unicode / ANSI)
|
||||
#define _istgraph isgraph
|
||||
#define _istascii __isascii
|
||||
|
||||
#define __TFILE__ _T(__FILE__)
|
||||
#define __TDATE__ _T(__DATE__)
|
||||
#define __TTIME__ _T(__TIME__)
|
||||
@@ -0,0 +1,296 @@
|
||||
//#include "StdAfx.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include "pluginapi.h"
|
||||
|
||||
#ifdef _countof
|
||||
#define COUNTOF _countof
|
||||
#else
|
||||
#define COUNTOF(a) (sizeof(a)/sizeof(a[0]))
|
||||
#endif
|
||||
|
||||
unsigned int g_stringsize;
|
||||
stack_t **g_stacktop;
|
||||
TCHAR *g_variables;
|
||||
|
||||
// utility functions (not required but often useful)
|
||||
|
||||
int NSISCALL popstring(TCHAR *str)
|
||||
{
|
||||
stack_t *th;
|
||||
if (!g_stacktop || !*g_stacktop) return 1;
|
||||
th=(*g_stacktop);
|
||||
if (str) lstrcpy(str,th->text);
|
||||
*g_stacktop = th->next;
|
||||
GlobalFree((HGLOBAL)th);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NSISCALL popstringn(TCHAR *str, int maxlen)
|
||||
{
|
||||
stack_t *th;
|
||||
if (!g_stacktop || !*g_stacktop) return 1;
|
||||
th=(*g_stacktop);
|
||||
if (str) lstrcpyn(str,th->text,maxlen?maxlen:g_stringsize);
|
||||
*g_stacktop = th->next;
|
||||
GlobalFree((HGLOBAL)th);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NSISCALL pushstring(const TCHAR *str)
|
||||
{
|
||||
stack_t *th;
|
||||
if (!g_stacktop) return;
|
||||
th=(stack_t*)GlobalAlloc(GPTR,(sizeof(stack_t)+(g_stringsize)*sizeof(TCHAR)));
|
||||
lstrcpyn(th->text,str,g_stringsize);
|
||||
th->next=*g_stacktop;
|
||||
*g_stacktop=th;
|
||||
}
|
||||
|
||||
TCHAR* NSISCALL getuservariable(const int varnum)
|
||||
{
|
||||
if (varnum < 0 || varnum >= __INST_LAST) return NULL;
|
||||
return g_variables+varnum*g_stringsize;
|
||||
}
|
||||
|
||||
void NSISCALL setuservariable(const int varnum, const TCHAR *var)
|
||||
{
|
||||
if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
|
||||
lstrcpy(g_variables + varnum*g_stringsize, var);
|
||||
}
|
||||
|
||||
#ifdef _UNICODE
|
||||
int NSISCALL PopStringA(char* ansiStr)
|
||||
{
|
||||
wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t));
|
||||
int rval = popstring(wideStr);
|
||||
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
|
||||
GlobalFree((HGLOBAL)wideStr);
|
||||
return rval;
|
||||
}
|
||||
|
||||
int NSISCALL PopStringNA(char* ansiStr, int maxlen)
|
||||
{
|
||||
int realLen = maxlen ? maxlen : g_stringsize;
|
||||
wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, realLen*sizeof(wchar_t));
|
||||
int rval = popstringn(wideStr, realLen);
|
||||
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, realLen, NULL, NULL);
|
||||
GlobalFree((HGLOBAL)wideStr);
|
||||
return rval;
|
||||
}
|
||||
|
||||
void NSISCALL PushStringA(const char* ansiStr)
|
||||
{
|
||||
wchar_t* wideStr = (wchar_t*) GlobalAlloc(GPTR, g_stringsize*sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
|
||||
pushstring(wideStr);
|
||||
GlobalFree((HGLOBAL)wideStr);
|
||||
return;
|
||||
}
|
||||
|
||||
void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr)
|
||||
{
|
||||
lstrcpyW(wideStr, getuservariable(varnum));
|
||||
}
|
||||
|
||||
void NSISCALL GetUserVariableA(const int varnum, char* ansiStr)
|
||||
{
|
||||
wchar_t* wideStr = getuservariable(varnum);
|
||||
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
|
||||
}
|
||||
|
||||
void NSISCALL SetUserVariableA(const int varnum, const char* ansiStr)
|
||||
{
|
||||
if (ansiStr != NULL && varnum >= 0 && varnum < __INST_LAST)
|
||||
{
|
||||
wchar_t* wideStr = g_variables + varnum * g_stringsize;
|
||||
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
// ANSI defs
|
||||
int NSISCALL PopStringW(wchar_t* wideStr)
|
||||
{
|
||||
char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize);
|
||||
int rval = popstring(ansiStr);
|
||||
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
|
||||
GlobalFree((HGLOBAL)ansiStr);
|
||||
return rval;
|
||||
}
|
||||
|
||||
int NSISCALL PopStringNW(wchar_t* wideStr, int maxlen)
|
||||
{
|
||||
int realLen = maxlen ? maxlen : g_stringsize;
|
||||
char* ansiStr = (char*) GlobalAlloc(GPTR, realLen);
|
||||
int rval = popstringn(ansiStr, realLen);
|
||||
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, realLen);
|
||||
GlobalFree((HGLOBAL)ansiStr);
|
||||
return rval;
|
||||
}
|
||||
|
||||
void NSISCALL PushStringW(wchar_t* wideStr)
|
||||
{
|
||||
char* ansiStr = (char*) GlobalAlloc(GPTR, g_stringsize);
|
||||
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
|
||||
pushstring(ansiStr);
|
||||
GlobalFree((HGLOBAL)ansiStr);
|
||||
}
|
||||
|
||||
void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr)
|
||||
{
|
||||
char* ansiStr = getuservariable(varnum);
|
||||
MultiByteToWideChar(CP_ACP, 0, ansiStr, -1, wideStr, g_stringsize);
|
||||
}
|
||||
|
||||
void NSISCALL GetUserVariableA(const int varnum, char* ansiStr)
|
||||
{
|
||||
lstrcpyA(ansiStr, getuservariable(varnum));
|
||||
}
|
||||
|
||||
void NSISCALL SetUserVariableW(const int varnum, const wchar_t* wideStr)
|
||||
{
|
||||
if (wideStr != NULL && varnum >= 0 && varnum < __INST_LAST)
|
||||
{
|
||||
char* ansiStr = g_variables + varnum * g_stringsize;
|
||||
WideCharToMultiByte(CP_ACP, 0, wideStr, -1, ansiStr, g_stringsize, NULL, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// playing with integers
|
||||
|
||||
INT_PTR NSISCALL nsishelper_str_to_ptr(const TCHAR *s)
|
||||
{
|
||||
INT_PTR v=0;
|
||||
if (*s == _T('0') && (s[1] == _T('x') || s[1] == _T('X')))
|
||||
{
|
||||
s++;
|
||||
for (;;)
|
||||
{
|
||||
int c=*(++s);
|
||||
if (c >= _T('0') && c <= _T('9')) c-=_T('0');
|
||||
else if (c >= _T('a') && c <= _T('f')) c-=_T('a')-10;
|
||||
else if (c >= _T('A') && c <= _T('F')) c-=_T('A')-10;
|
||||
else break;
|
||||
v<<=4;
|
||||
v+=c;
|
||||
}
|
||||
}
|
||||
else if (*s == _T('0') && s[1] <= _T('7') && s[1] >= _T('0'))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int c=*(++s);
|
||||
if (c >= _T('0') && c <= _T('7')) c-=_T('0');
|
||||
else break;
|
||||
v<<=3;
|
||||
v+=c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int sign=0;
|
||||
if (*s == _T('-')) sign++; else s--;
|
||||
for (;;)
|
||||
{
|
||||
int c=*(++s) - _T('0');
|
||||
if (c < 0 || c > 9) break;
|
||||
v*=10;
|
||||
v+=c;
|
||||
}
|
||||
if (sign) v = -v;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
unsigned int NSISCALL myatou(const TCHAR *s)
|
||||
{
|
||||
unsigned int v=0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
unsigned int c=*s++;
|
||||
if (c >= _T('0') && c <= _T('9')) c-=_T('0');
|
||||
else break;
|
||||
v*=10;
|
||||
v+=c;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
int NSISCALL myatoi_or(const TCHAR *s)
|
||||
{
|
||||
int v=0;
|
||||
if (*s == _T('0') && (s[1] == _T('x') || s[1] == _T('X')))
|
||||
{
|
||||
s++;
|
||||
for (;;)
|
||||
{
|
||||
int c=*(++s);
|
||||
if (c >= _T('0') && c <= _T('9')) c-=_T('0');
|
||||
else if (c >= _T('a') && c <= _T('f')) c-=_T('a')-10;
|
||||
else if (c >= _T('A') && c <= _T('F')) c-=_T('A')-10;
|
||||
else break;
|
||||
v<<=4;
|
||||
v+=c;
|
||||
}
|
||||
}
|
||||
else if (*s == _T('0') && s[1] <= _T('7') && s[1] >= _T('0'))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int c=*(++s);
|
||||
if (c >= _T('0') && c <= _T('7')) c-=_T('0');
|
||||
else break;
|
||||
v<<=3;
|
||||
v+=c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int sign=0;
|
||||
if (*s == _T('-')) sign++; else s--;
|
||||
for (;;)
|
||||
{
|
||||
int c=*(++s) - _T('0');
|
||||
if (c < 0 || c > 9) break;
|
||||
v*=10;
|
||||
v+=c;
|
||||
}
|
||||
if (sign) v = -v;
|
||||
}
|
||||
|
||||
// Support for simple ORed expressions
|
||||
if (*s == _T('|'))
|
||||
{
|
||||
v |= myatoi_or(s+1);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
INT_PTR NSISCALL popintptr()
|
||||
{
|
||||
TCHAR buf[128];
|
||||
if (popstringn(buf,COUNTOF(buf)))
|
||||
return 0;
|
||||
return nsishelper_str_to_ptr(buf);
|
||||
}
|
||||
|
||||
int NSISCALL popint_or()
|
||||
{
|
||||
TCHAR buf[128];
|
||||
if (popstringn(buf,COUNTOF(buf)))
|
||||
return 0;
|
||||
return myatoi_or(buf);
|
||||
}
|
||||
|
||||
void NSISCALL pushintptr(INT_PTR value)
|
||||
{
|
||||
TCHAR buffer[30];
|
||||
wsprintf(buffer, sizeof(void*) > 4 ? _T("%Id") : _T("%d"), value);
|
||||
pushstring(buffer);
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
#ifndef ___NSIS_PLUGIN__H___
|
||||
#define ___NSIS_PLUGIN__H___
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "api.h"
|
||||
#ifdef _UNICODE
|
||||
#ifndef _T
|
||||
#define __T(x) L ## x
|
||||
#define _T(x) __T(x)
|
||||
#define _TEXT(x) __T(x)
|
||||
#endif
|
||||
#else
|
||||
#ifndef _T
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NSISCALL
|
||||
# define NSISCALL __stdcall
|
||||
#endif
|
||||
|
||||
#define EXDLL_INIT() { \
|
||||
g_stringsize=string_size; \
|
||||
g_stacktop=stacktop; \
|
||||
g_variables=variables; }
|
||||
|
||||
typedef struct _stack_t {
|
||||
struct _stack_t *next;
|
||||
TCHAR text[1]; // this should be the length of string_size
|
||||
} stack_t;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
extern unsigned int g_stringsize;
|
||||
extern stack_t **g_stacktop;
|
||||
extern TCHAR *g_variables;
|
||||
|
||||
void NSISCALL pushstring(const TCHAR *str);
|
||||
void NSISCALL pushintptr(INT_PTR value);
|
||||
#define pushint(v) pushintptr((INT_PTR)(v))
|
||||
int NSISCALL popstring(TCHAR *str); // 0 on success, 1 on empty stack
|
||||
int NSISCALL popstringn(TCHAR *str, int maxlen); // with length limit, pass 0 for g_stringsize
|
||||
INT_PTR NSISCALL popintptr();
|
||||
#define popint() ( (int) popintptr() )
|
||||
int NSISCALL popint_or(); // with support for or'ing (2|4|8)
|
||||
INT_PTR NSISCALL nsishelper_str_to_ptr(const TCHAR *s);
|
||||
#define myatoi(s) ( (int) nsishelper_str_to_ptr(s) ) // converts a string to an integer
|
||||
unsigned int NSISCALL myatou(const TCHAR *s); // converts a string to an unsigned integer, decimal only
|
||||
int NSISCALL myatoi_or(const TCHAR *s); // with support for or'ing (2|4|8)
|
||||
TCHAR* NSISCALL getuservariable(const int varnum);
|
||||
void NSISCALL setuservariable(const int varnum, const TCHAR *var);
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define PopStringW(x) popstring(x)
|
||||
#define PushStringW(x) pushstring(x)
|
||||
#define SetUserVariableW(x,y) setuservariable(x,y)
|
||||
|
||||
int NSISCALL PopStringA(char* ansiStr);
|
||||
void NSISCALL PushStringA(const char* ansiStr);
|
||||
void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr);
|
||||
void NSISCALL GetUserVariableA(const int varnum, char* ansiStr);
|
||||
void NSISCALL SetUserVariableA(const int varnum, const char* ansiStr);
|
||||
|
||||
#else
|
||||
// ANSI defs
|
||||
|
||||
#define PopStringA(x) popstring(x)
|
||||
#define PushStringA(x) pushstring(x)
|
||||
#define SetUserVariableA(x,y) setuservariable(x,y)
|
||||
|
||||
int NSISCALL PopStringW(wchar_t* wideStr);
|
||||
void NSISCALL PushStringW(wchar_t* wideStr);
|
||||
void NSISCALL GetUserVariableW(const int varnum, wchar_t* wideStr);
|
||||
void NSISCALL GetUserVariableA(const int varnum, char* ansiStr);
|
||||
void NSISCALL SetUserVariableW(const int varnum, const wchar_t* wideStr);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif//!___NSIS_PLUGIN__H___
|
||||
Reference in New Issue
Block a user