mirror of
				https://github.com/chibicitiberiu/rainmeter-studio.git
				synced 2024-02-24 04:33:31 +00:00 
			
		
		
		
	New installer: Implement basic install and elevation handling
This commit is contained in:
		@@ -17,52 +17,53 @@
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "StdAfx.h"
 | 
			
		||||
#include "DialogInstall.h"
 | 
			
		||||
#include "Resource.h"
 | 
			
		||||
#include "Application.h"
 | 
			
		||||
#include "DialogInstall.h"
 | 
			
		||||
#include "Install.h"
 | 
			
		||||
#include "Resource.h"
 | 
			
		||||
 | 
			
		||||
bool IsSupportedPlatform();
 | 
			
		||||
bool IsSupportedCPU();
 | 
			
		||||
 | 
			
		||||
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
 | 
			
		||||
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR cmdLine, int)
 | 
			
		||||
{
 | 
			
		||||
	int argCount = 0;
 | 
			
		||||
	LPWSTR* args = CommandLineToArgvW(GetCommandLine(), &argCount);
 | 
			
		||||
	if (args)
 | 
			
		||||
	{
 | 
			
		||||
		for (int i = 1; i < argCount; ++i)
 | 
			
		||||
		{
 | 
			
		||||
			WCHAR* name = &args[i][(args[i][0] == L'/') ? 1 : 0];
 | 
			
		||||
			WCHAR* value = wcschr(name, L':');
 | 
			
		||||
			if (value)
 | 
			
		||||
			{
 | 
			
		||||
				*value = L'\0';
 | 
			
		||||
				++value;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (wcscmp(name, L"Silent") == 0)
 | 
			
		||||
			{
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (argCount >= 2 && wcscmp(args[1], L"/ElevatedInstall") == 0)
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		LocalFree(args);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CoInitialize(nullptr);
 | 
			
		||||
	InitCommonControls();
 | 
			
		||||
 | 
			
		||||
	if (*cmdLine)
 | 
			
		||||
	{
 | 
			
		||||
		InstallOptions options;
 | 
			
		||||
		const int scans = swscanf(
 | 
			
		||||
			cmdLine, L"OPT:%259[^|]|%ld|%hd|%hd|%d",
 | 
			
		||||
			options.targetPath,
 | 
			
		||||
			&options.language,
 | 
			
		||||
			&options.type,
 | 
			
		||||
			&options.arch,
 | 
			
		||||
			&options.launchOnLogin);
 | 
			
		||||
		if (scans == 5)
 | 
			
		||||
		{
 | 
			
		||||
			DoInstall(options);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!IsSupportedPlatform())
 | 
			
		||||
	{
 | 
			
		||||
		MessageBox(nullptr, L"Windows XP SP2 or higher is required to install Rainmeter.", nullptr, MB_OK | MB_ICONERROR);
 | 
			
		||||
		MessageBox(
 | 
			
		||||
			nullptr,
 | 
			
		||||
			L"Windows XP SP2 or higher is required to install Rainmeter.",
 | 
			
		||||
			L"Rainmeter Setup", MB_OK | MB_ICONERROR);
 | 
			
		||||
		return (int)InstallStatus::UnsupportedPlatform;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!IsSupportedCPU())
 | 
			
		||||
	{
 | 
			
		||||
		MessageBox(nullptr, L"A Pentium III or later processor is required to install Rainmeter.", nullptr, MB_OK | MB_ICONERROR);
 | 
			
		||||
		MessageBox(
 | 
			
		||||
			nullptr,
 | 
			
		||||
			L"A Pentium III or later processor is required to install Rainmeter.",
 | 
			
		||||
			L"Rainmeter Setup", MB_OK | MB_ICONERROR);
 | 
			
		||||
		return (int)InstallStatus::UnsupportedPlatform;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,8 +18,11 @@
 | 
			
		||||
 | 
			
		||||
#include "StdAfx.h"
 | 
			
		||||
#include "DialogInstall.h"
 | 
			
		||||
#include "Install.h"
 | 
			
		||||
#include "Resource.h"
 | 
			
		||||
#include "Util.h"
 | 
			
		||||
#include "../Common/ControlTemplate.h"
 | 
			
		||||
#include "../Common/Platform.h"
 | 
			
		||||
 | 
			
		||||
CDialogInstall* CDialogInstall::c_Dialog = nullptr;
 | 
			
		||||
 | 
			
		||||
@@ -74,7 +77,9 @@ WCHAR* GetString(UINT id)
 | 
			
		||||
	return L"";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CDialogInstall::CDialogInstall() : Dialog()
 | 
			
		||||
CDialogInstall::CDialogInstall() : Dialog(),
 | 
			
		||||
	m_InstallProcess(),
 | 
			
		||||
	m_InstallProcessWaitThread()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -87,7 +92,7 @@ CDialogInstall* CDialogInstall::Create()
 | 
			
		||||
	c_Dialog = new CDialogInstall();
 | 
			
		||||
 | 
			
		||||
	c_Dialog->ShowDialogWindow(
 | 
			
		||||
		L"Installer",
 | 
			
		||||
		L"Rainmeter Setup",
 | 
			
		||||
		0, 0, 350, 210,
 | 
			
		||||
		DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU,
 | 
			
		||||
		WS_EX_APPWINDOW | WS_EX_CONTROLPARENT,
 | 
			
		||||
@@ -128,7 +133,7 @@ INT_PTR CDialogInstall::OnInitDialog(WPARAM wParam, LPARAM lParam)
 | 
			
		||||
	static const ControlTemplate::Control s_Controls[] =
 | 
			
		||||
	{
 | 
			
		||||
		CT_ICON(Id_HeaderIcon, 0,
 | 
			
		||||
			8, 10, 24, 24,
 | 
			
		||||
			10, 10, 24, 24,
 | 
			
		||||
			WS_VISIBLE, 0),
 | 
			
		||||
 | 
			
		||||
		CT_LABEL(Id_HeaderTitleLabel, 2,
 | 
			
		||||
@@ -139,7 +144,6 @@ INT_PTR CDialogInstall::OnInitDialog(WPARAM wParam, LPARAM lParam)
 | 
			
		||||
			40, 20, 250, 9,
 | 
			
		||||
			WS_VISIBLE | SS_ENDELLIPSIS | SS_NOPREFIX, 0),
 | 
			
		||||
 | 
			
		||||
			
 | 
			
		||||
		CT_BUTTON(Id_InstallButton, 1,
 | 
			
		||||
			199, 191, 70, 14,
 | 
			
		||||
			WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON, 0),
 | 
			
		||||
@@ -149,7 +153,7 @@ INT_PTR CDialogInstall::OnInitDialog(WPARAM wParam, LPARAM lParam)
 | 
			
		||||
			WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON, 0),
 | 
			
		||||
 | 
			
		||||
		CT_TAB(Id_Tab, 0,
 | 
			
		||||
			-2, 38, 400, 148,
 | 
			
		||||
			-2, 36, 400, 150,
 | 
			
		||||
			WS_VISIBLE | WS_TABSTOP | TCS_FIXEDWIDTH, 0)  // Last for correct tab order.
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
@@ -168,7 +172,11 @@ INT_PTR CDialogInstall::OnInitDialog(WPARAM wParam, LPARAM lParam)
 | 
			
		||||
 | 
			
		||||
	item = GetControl(Id_InstallButton);
 | 
			
		||||
	SendMessage(m_Window, WM_NEXTDLGCTL, (WPARAM)item, TRUE);
 | 
			
		||||
	
 | 
			
		||||
	if (Platform::IsAtLeastWinVista() && !Util::IsProcessUserAdmin())
 | 
			
		||||
	{
 | 
			
		||||
		Button_SetElevationRequiredState(item, TRUE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -180,6 +188,10 @@ INT_PTR CDialogInstall::OnCommand(WPARAM wParam, LPARAM lParam)
 | 
			
		||||
		PostMessage(m_Window, WM_CLOSE, 0, 0);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case Id_InstallButton:
 | 
			
		||||
		LaunchInstallProcess();
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
@@ -192,6 +204,84 @@ INT_PTR CDialogInstall::OnNotify(WPARAM wParam, LPARAM lParam)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CDialogInstall::LaunchInstallProcess()
 | 
			
		||||
{
 | 
			
		||||
	const bool isProcsesUserAdmin = Util::IsProcessUserAdmin();
 | 
			
		||||
	if (!isProcsesUserAdmin && (Platform::IsAtLeastWinVista() && !Util::CanProcessUserElevate()))
 | 
			
		||||
	{
 | 
			
		||||
		MessageBox(
 | 
			
		||||
			m_Window,
 | 
			
		||||
			L"Adminstrative privileges are required to install Rainmeter.\n\nClick OK to close setup.",
 | 
			
		||||
			L"Rainmeter Setup", MB_OK | MB_ICONERROR);
 | 
			
		||||
		PostMessage(m_Window, WM_CLOSE, 0, 0);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_InstallProcessWaitThread = CreateThread(
 | 
			
		||||
		nullptr, 0, ElevatedProcessWaitThreadProc, nullptr, CREATE_SUSPENDED, nullptr);
 | 
			
		||||
	if (!m_InstallProcessWaitThread)
 | 
			
		||||
	{
 | 
			
		||||
		// TODO.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	WCHAR exePath[MAX_PATH];
 | 
			
		||||
	GetModuleFileName(nullptr, exePath, _countof(exePath));
 | 
			
		||||
 | 
			
		||||
	HWND item = m_TabContents.GetControl(TabContents::Id_LanguageComboBox); 
 | 
			
		||||
	const LCID lcid = (LCID)ComboBox_GetItemData(item, ComboBox_GetCurSel(item));
 | 
			
		||||
 | 
			
		||||
	item = m_TabContents.GetControl(TabContents::Id_InstallationTypeComboBox); 
 | 
			
		||||
	const LPARAM typeData = ComboBox_GetItemData(item, ComboBox_GetCurSel(item));
 | 
			
		||||
 | 
			
		||||
	WCHAR targetPath[MAX_PATH];
 | 
			
		||||
	item = m_TabContents.GetControl(TabContents::Id_DestinationEdit);
 | 
			
		||||
	Edit_GetText(item, targetPath, _countof(targetPath));
 | 
			
		||||
 | 
			
		||||
	item = m_TabContents.GetControl(TabContents::Id_LaunchOnLoginCheckBox);
 | 
			
		||||
	const int launchOnLogin = Button_GetCheck(item) == BST_CHECKED ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
	WCHAR params[512];
 | 
			
		||||
	wsprintf(
 | 
			
		||||
		params, L"OPT:%s|%ld|%hd|%hd|%d",
 | 
			
		||||
		targetPath, lcid, LOWORD(typeData), HIWORD(typeData), launchOnLogin);
 | 
			
		||||
 | 
			
		||||
	// Launch the installer process and, if needed, request elevation.
 | 
			
		||||
	SHELLEXECUTEINFO sei = {sizeof(sei)};
 | 
			
		||||
	sei.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS;
 | 
			
		||||
	sei.lpVerb = isProcsesUserAdmin ? L"open" : L"runas";
 | 
			
		||||
	sei.lpFile = exePath;
 | 
			
		||||
	sei.lpParameters = params;
 | 
			
		||||
	sei.hwnd = m_Window;
 | 
			
		||||
	sei.nShow = SW_NORMAL;
 | 
			
		||||
 | 
			
		||||
	if (!ShellExecuteEx(&sei) || !sei.hProcess)
 | 
			
		||||
	{
 | 
			
		||||
		MessageBox(m_Window,
 | 
			
		||||
			L"Adminstrative privileges are required to install Rainmeter.\n\nClick OK to close setup.",
 | 
			
		||||
			L"Rainmeter Setup", MB_OK | MB_ICONERROR);
 | 
			
		||||
		PostMessage(m_Window, WM_CLOSE, 0, 0);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_InstallProcess = sei.hProcess;
 | 
			
		||||
	ResumeThread(m_InstallProcessWaitThread);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DWORD WINAPI CDialogInstall::ElevatedProcessWaitThreadProc(void* param)
 | 
			
		||||
{
 | 
			
		||||
	WaitForSingleObject(c_Dialog->m_InstallProcess, INFINITE);
 | 
			
		||||
 | 
			
		||||
	CloseHandle(c_Dialog->m_InstallProcess);
 | 
			
		||||
	c_Dialog->m_InstallProcess = nullptr;
 | 
			
		||||
 | 
			
		||||
	CloseHandle(c_Dialog->m_InstallProcessWaitThread);
 | 
			
		||||
	c_Dialog->m_InstallProcessWaitThread = nullptr;
 | 
			
		||||
 | 
			
		||||
	PostMessage(c_Dialog->m_Window, WM_CLOSE, 0, 0);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
** Constructor.
 | 
			
		||||
**
 | 
			
		||||
@@ -247,9 +337,13 @@ void CDialogInstall::TabContents::Create(HWND owner)
 | 
			
		||||
 | 
			
		||||
	item = GetControl(Id_InstallationTypeComboBox);
 | 
			
		||||
	ComboBox_AddString(item, L"Standard 64-bit installation (reccomended)");
 | 
			
		||||
	ComboBox_SetItemData(item, 0, MAKELPARAM(InstallType::Standard, InstallArch::X64));
 | 
			
		||||
	ComboBox_AddString(item, L"Standard 32-bit installation");
 | 
			
		||||
	ComboBox_SetItemData(item, 1, MAKELPARAM(InstallType::Standard, InstallArch::X32));
 | 
			
		||||
	ComboBox_AddString(item, L"Portable 64-bit installation");
 | 
			
		||||
	ComboBox_SetItemData(item, 2, MAKELPARAM(InstallType::Portable, InstallArch::X64));
 | 
			
		||||
	ComboBox_AddString(item, L"Portable 32-bit installation");
 | 
			
		||||
	ComboBox_SetItemData(item, 3, MAKELPARAM(InstallType::Portable, InstallArch::X32));
 | 
			
		||||
	ComboBox_SetCurSel(item, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -270,5 +364,28 @@ INT_PTR CDialogInstall::TabContents::HandleMessage(UINT uMsg, WPARAM wParam, LPA
 | 
			
		||||
 | 
			
		||||
INT_PTR CDialogInstall::TabContents::OnCommand(WPARAM wParam, LPARAM lParam)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
	switch (LOWORD(wParam))
 | 
			
		||||
	{
 | 
			
		||||
	case Id_DestinationBrowseButton:
 | 
			
		||||
		{
 | 
			
		||||
			WCHAR buffer[MAX_PATH];
 | 
			
		||||
			BROWSEINFO bi = {0};
 | 
			
		||||
			bi.hwndOwner = c_Dialog->GetWindow();
 | 
			
		||||
			bi.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
 | 
			
		||||
 | 
			
		||||
			PIDLIST_ABSOLUTE pidl = SHBrowseForFolder(&bi);
 | 
			
		||||
			if (pidl && SHGetPathFromIDList(pidl, buffer))
 | 
			
		||||
			{
 | 
			
		||||
				HWND item = GetControl(Id_DestinationEdit);
 | 
			
		||||
				Static_SetText(item, buffer);
 | 
			
		||||
				CoTaskMemFree(pidl);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -65,8 +65,6 @@ protected:
 | 
			
		||||
	INT_PTR OnCommand(WPARAM wParam, LPARAM lParam);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	TabContents m_TabContents;
 | 
			
		||||
 | 
			
		||||
	enum Id
 | 
			
		||||
	{
 | 
			
		||||
		Id_CancelButton = IDCANCEL,
 | 
			
		||||
@@ -76,6 +74,15 @@ private:
 | 
			
		||||
		Id_InstallButton,
 | 
			
		||||
		Id_Tab
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	TabContents m_TabContents;
 | 
			
		||||
 | 
			
		||||
	HANDLE m_InstallProcess;
 | 
			
		||||
	HANDLE m_InstallProcessWaitThread;
 | 
			
		||||
 | 
			
		||||
	void LaunchInstallProcess();
 | 
			
		||||
 | 
			
		||||
	static DWORD WINAPI ElevatedProcessWaitThreadProc(void* param);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										147
									
								
								Installer/Install.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								Installer/Install.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,147 @@
 | 
			
		||||
/*
 | 
			
		||||
  Copyright (C) 2013 Birunthan Mohanathas
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or
 | 
			
		||||
  modify it under the terms of the GNU General Public License
 | 
			
		||||
  as published by the Free Software Foundation; either version 2
 | 
			
		||||
  of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "StdAfx.h"
 | 
			
		||||
#include "Install.h"
 | 
			
		||||
#include "Resource.h"
 | 
			
		||||
 | 
			
		||||
extern "C" {
 | 
			
		||||
#include "lzma/Alloc.h"
 | 
			
		||||
#include "lzma/7zFile.h"
 | 
			
		||||
#include "lzma/7zVersion.h"
 | 
			
		||||
#include "lzma/LzmaDec.h"
 | 
			
		||||
#include "lzma/7zCrc.h"
 | 
			
		||||
#include "lzma/7z.h"
 | 
			
		||||
#include "lzma/7zMemInStream.h"
 | 
			
		||||
#include "lzma/7zAlloc.h"
 | 
			
		||||
}  // extern "C"
 | 
			
		||||
 | 
			
		||||
void ExtractPayload(const void* payload, size_t payloadSize, const WCHAR* prefix)
 | 
			
		||||
{
 | 
			
		||||
	CMemInStream memStream;
 | 
			
		||||
	MemInStream_Init(&memStream, payload, payloadSize);
 | 
			
		||||
 | 
			
		||||
	CrcGenerateTable();
 | 
			
		||||
 | 
			
		||||
	ISzAlloc alloc = { SzAlloc, SzFree };
 | 
			
		||||
	CSzArEx db;
 | 
			
		||||
	SzArEx_Init(&db);
 | 
			
		||||
	SRes res = SzArEx_Open(&db, &memStream.s, &alloc, &alloc);
 | 
			
		||||
	if (res != SZ_OK)
 | 
			
		||||
	{
 | 
			
		||||
		SzArEx_Free(&db, &alloc);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	WCHAR buffer[MAX_PATH];
 | 
			
		||||
	UInt32 blockIndex = 0xFFFFFFFF;
 | 
			
		||||
	Byte* outBuffer = 0;
 | 
			
		||||
	size_t outBufferSize = 0;
 | 
			
		||||
 | 
			
		||||
	for (UInt32 i = 0; i < db.db.NumFiles; i++)
 | 
			
		||||
	{
 | 
			
		||||
		size_t offset = 0;
 | 
			
		||||
		size_t outSizeProcessed = 0;
 | 
			
		||||
		const CSzFileItem* f = db.db.Files + i;
 | 
			
		||||
 | 
			
		||||
		SzArEx_GetFileNameUtf16(&db, i, (UInt16*)buffer);
 | 
			
		||||
		WCHAR* destPath = buffer;
 | 
			
		||||
		if (wcsncmp(destPath, prefix, 3) == 0 ||
 | 
			
		||||
			wcsncmp(destPath, L"ALL", 3) == 0)
 | 
			
		||||
		{
 | 
			
		||||
			// Skip the prefix (X64/X32/ALL) and the path separater.
 | 
			
		||||
			destPath += 4;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			// This file isn't for this arch.
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!f->IsDir)
 | 
			
		||||
		{
 | 
			
		||||
			res = SzArEx_Extract(
 | 
			
		||||
				&db, &memStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset,
 | 
			
		||||
				&outSizeProcessed, &alloc, &alloc);
 | 
			
		||||
			if (res != SZ_OK)
 | 
			
		||||
			{
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (size_t j = 0; destPath[j] != L'\0'; ++j)
 | 
			
		||||
		{
 | 
			
		||||
			if (destPath[j] == L'/')
 | 
			
		||||
			{
 | 
			
		||||
				destPath[j] = L'\0';
 | 
			
		||||
				CreateDirectory(destPath, NULL);
 | 
			
		||||
				destPath[j] = CHAR_PATH_SEPARATOR;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (f->IsDir)
 | 
			
		||||
		{
 | 
			
		||||
			CreateDirectory(destPath, NULL);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		CSzFile outFile;
 | 
			
		||||
		if (OutFile_OpenW(&outFile, destPath))
 | 
			
		||||
		{
 | 
			
		||||
			res = SZ_ERROR_FAIL;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		size_t processedSize = outSizeProcessed;
 | 
			
		||||
		if (File_Write(&outFile, outBuffer + offset, &processedSize) != 0 ||
 | 
			
		||||
			processedSize != outSizeProcessed)
 | 
			
		||||
		{
 | 
			
		||||
			res = SZ_ERROR_FAIL;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		if (File_Close(&outFile))
 | 
			
		||||
		{
 | 
			
		||||
			res = SZ_ERROR_FAIL;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (f->AttribDefined) SetFileAttributesW(destPath, f->Attrib);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	IAlloc_Free(&alloc, outBuffer);
 | 
			
		||||
	SzArEx_Free(&db, &alloc);
 | 
			
		||||
 | 
			
		||||
	if (res == SZ_OK)
 | 
			
		||||
	{
 | 
			
		||||
		// Success.
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DoInstall(InstallOptions& options)
 | 
			
		||||
{
 | 
			
		||||
#ifdef INSTALLER_INCLUDE_PAYLOAD
 | 
			
		||||
	const auto module = GetModuleHandle(nullptr);
 | 
			
		||||
	HRSRC payload = FindResource(
 | 
			
		||||
		module, MAKEINTRESOURCE(IDR_PAYLOAD), MAKEINTRESOURCE(PAYLOAD_RESOURCE_TYPEID));
 | 
			
		||||
	const size_t payloadSize = SizeofResource(module, payload);
 | 
			
		||||
	const void* payloadData = LockResource(LoadResource(module, payload));
 | 
			
		||||
 | 
			
		||||
	SetCurrentDirectory(options.targetPath);
 | 
			
		||||
	ExtractPayload(
 | 
			
		||||
		payloadData, payloadSize, options.arch == InstallArch::X32 ? L"X32" : L"X64");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								Installer/Install.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Installer/Install.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
/*
 | 
			
		||||
  Copyright (C) 2013 Birunthan Mohanathas
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or
 | 
			
		||||
  modify it under the terms of the GNU General Public License
 | 
			
		||||
  as published by the Free Software Foundation; either version 2
 | 
			
		||||
  of the License, or (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef RM_INSTALLER_INSTALL_H_
 | 
			
		||||
#define RM_INSTALLER_INSTALL_H_
 | 
			
		||||
 | 
			
		||||
enum InstallType : char
 | 
			
		||||
{
 | 
			
		||||
	Standard,
 | 
			
		||||
	Portable
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum InstallArch : char
 | 
			
		||||
{
 | 
			
		||||
	X32,
 | 
			
		||||
	X64
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct InstallOptions
 | 
			
		||||
{
 | 
			
		||||
	WCHAR targetPath[MAX_PATH];
 | 
			
		||||
	InstallType type;
 | 
			
		||||
	InstallArch arch;
 | 
			
		||||
	LCID language;
 | 
			
		||||
	BOOL launchOnLogin;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void DoInstall(InstallOptions& options);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -47,5 +47,8 @@ VS_VERSION_INFO VERSIONINFO
 | 
			
		||||
// Icon
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
IDI_APPICON             ICON                    "Installer.ico"
 | 
			
		||||
IDI_APPICON  ICON  "Installer.ico"
 | 
			
		||||
 | 
			
		||||
#ifdef INSTALLER_INCLUDE_PAYLOAD
 | 
			
		||||
IDR_PAYLOAD  PAYLOAD_RESOURCE_TYPEID  payload.7z
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
    <Link>
 | 
			
		||||
      <SubSystem>Windows</SubSystem>
 | 
			
		||||
      <AdditionalDependencies>Imagehlp.lib;Wininet.lib;Comctl32.lib;Version.lib;UxTheme.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
 | 
			
		||||
      <AdditionalDependencies Condition="'$(Configuration)'=='Release'">$(WinDDK71Dir)\lib\Crt\i386\msvcrt.lib;%(AdditionalDependencies)</AdditionalDependencies>
 | 
			
		||||
      <AdditionalDependencies Condition="'$(Configuration)'=='Release'">D:\Biru\Projects\WinDDK\7600.16385.1\lib\Crt\i386\msvcrt.lib;%(AdditionalDependencies)</AdditionalDependencies>
 | 
			
		||||
      <IgnoreAllDefaultLibraries Condition="'$(Configuration)'=='Release'">true</IgnoreAllDefaultLibraries>
 | 
			
		||||
    </Link>
 | 
			
		||||
    <Manifest>
 | 
			
		||||
@@ -29,10 +29,9 @@
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClCompile Include="..\Common\ControlTemplate.cpp" />
 | 
			
		||||
    <ClCompile Include="..\Common\Dialog.cpp" />
 | 
			
		||||
    <ClCompile Include="Application.cpp" />
 | 
			
		||||
    <ClCompile Include="DialogInstall.cpp" />
 | 
			
		||||
    <ClCompile Include="Install.cpp" />
 | 
			
		||||
    <ClCompile Include="lzma\7zAlloc.c" />
 | 
			
		||||
    <ClCompile Include="lzma\7zBuf.c" />
 | 
			
		||||
    <ClCompile Include="lzma\7zCrc.c" />
 | 
			
		||||
@@ -52,10 +51,9 @@
 | 
			
		||||
    <ClCompile Include="Util.cpp" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClInclude Include="..\Common\ControlTemplate.h" />
 | 
			
		||||
    <ClInclude Include="..\Common\Dialog.h" />
 | 
			
		||||
    <ClInclude Include="Application.h" />
 | 
			
		||||
    <ClInclude Include="DialogInstall.h" />
 | 
			
		||||
    <ClInclude Include="Install.h" />
 | 
			
		||||
    <ClInclude Include="lzma\7z.h" />
 | 
			
		||||
    <ClInclude Include="lzma\7zAlloc.h" />
 | 
			
		||||
    <ClInclude Include="lzma\7zBuf.h" />
 | 
			
		||||
@@ -69,12 +67,18 @@
 | 
			
		||||
    <ClInclude Include="lzma\CpuArch.h" />
 | 
			
		||||
    <ClInclude Include="lzma\LzmaDec.h" />
 | 
			
		||||
    <ClInclude Include="lzma\Types.h" />
 | 
			
		||||
    <ClInclude Include="Resource.h" />
 | 
			
		||||
    <ClInclude Include="StdAfx.h" />
 | 
			
		||||
    <ClInclude Include="Util.h" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ResourceCompile Include="Installer.rc" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\Common\Common.vcxproj">
 | 
			
		||||
      <Project>{19312085-aa51-4bd6-be92-4b6098cca539}</Project>
 | 
			
		||||
    </ProjectReference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
 | 
			
		||||
  <ImportGroup Label="ExtensionTargets">
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,14 +16,14 @@
 | 
			
		||||
    <Filter Include="lzma">
 | 
			
		||||
      <UniqueIdentifier>{9588f54f-9188-40b7-b750-260f5f514ee5}</UniqueIdentifier>
 | 
			
		||||
    </Filter>
 | 
			
		||||
    <Filter Include="Common">
 | 
			
		||||
      <UniqueIdentifier>{f19567fb-ab8f-4193-a3b3-826685cf8db3}</UniqueIdentifier>
 | 
			
		||||
    </Filter>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClCompile Include="Application.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="Install.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="StdAfx.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
@@ -78,14 +78,20 @@
 | 
			
		||||
    <ClCompile Include="DialogInstall.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="..\Common\Dialog.cpp">
 | 
			
		||||
      <Filter>Common</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="..\Common\ControlTemplate.cpp">
 | 
			
		||||
      <Filter>Common</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClInclude Include="Application.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="DialogInstall.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="Install.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="Resource.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="Util.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
@@ -131,18 +137,6 @@
 | 
			
		||||
    <ClInclude Include="lzma\7zVersion.h">
 | 
			
		||||
      <Filter>lzma</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="DialogInstall.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="..\Common\Dialog.h">
 | 
			
		||||
      <Filter>Common</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="..\Common\ControlTemplate.h">
 | 
			
		||||
      <Filter>Common</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="Application.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ResourceCompile Include="Installer.rc">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,2 +1,6 @@
 | 
			
		||||
#define IDI_APPICON                                  101
 | 
			
		||||
#define IDR_PAYLOAD                                  102
 | 
			
		||||
 | 
			
		||||
#define PAYLOAD_RESOURCE_TYPEID                      1000
 | 
			
		||||
 | 
			
		||||
#define IDC_STATIC                                   -1
 | 
			
		||||
 
 | 
			
		||||
@@ -99,7 +99,7 @@ bool CanProcessUserElevate()
 | 
			
		||||
			// Try checking registry.
 | 
			
		||||
			const WCHAR* subKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
 | 
			
		||||
			DWORD data;
 | 
			
		||||
			if (GetRegistryDword(HKEY_LOCAL_MACHINE, subKey, L"EnableLUA", &data) == ERROR_SUCCESS &&
 | 
			
		||||
			if (GetRegistryDword(HKEY_LOCAL_MACHINE, subKey, L"EnableLUA", &data) &&
 | 
			
		||||
				data != 0)
 | 
			
		||||
			{
 | 
			
		||||
				return true;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user