diff --git a/.gitignore b/.gitignore index 587a6e6..47615a4 100644 --- a/.gitignore +++ b/.gitignore @@ -13,17 +13,5 @@ MSICA/MSIBuild/*.Icon-2 MSICA/MSIBuild/*.lst MSICA/MSIBuild/*.msm MSICA/temp -MSICALib/*.user -MSICALib/L10N/*.mo -MSICALib/MSIBuild/*-1.idt -MSICALib/MSIBuild/*-2.idt -MSICALib/MSIBuild/*-2.idtx -MSICALib/MSIBuild/*.Binary-1 -MSICALib/MSIBuild/*.Binary-2 -MSICALib/MSIBuild/*.Icon-1 -MSICALib/MSIBuild/*.Icon-2 -MSICALib/MSIBuild/*.lst -MSICALib/MSIBuild/*.msm -MSICALib/temp /ipch /output diff --git a/MSICA.sln b/MSICA.sln index 6e9f31c..9085655 100644 --- a/MSICA.sln +++ b/MSICA.sln @@ -1,14 +1,13 @@  Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MSICALib", "MSICALib\MSICALib.vcxproj", "{8552EE55-177E-4F51-B51B-BAF7D6462CDE}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "atlex", "..\lib\atlex\build\atlex.vcxproj", "{5A4EADF2-3237-457A-9DA8-BB9942A91019}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MSICALib", "..\lib\MSICALib\build\MSICALib.vcxproj", "{8552EE55-177E-4F51-B51B-BAF7D6462CDE}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MSICA", "MSICA\MSICA.vcxproj", "{A7D9EBC1-1E64-4399-9C88-6692F8742153}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F3D5C008-7728-49CA-84F1-12C186FC87F8}" - ProjectSection(SolutionItems) = preProject - include\version.h = include\version.h - EndProjectSection +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{26350A68-2F55-4732-972C-4A5E9077699E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -18,6 +17,14 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5A4EADF2-3237-457A-9DA8-BB9942A91019}.Debug|Win32.ActiveCfg = Debug|Win32 + {5A4EADF2-3237-457A-9DA8-BB9942A91019}.Debug|Win32.Build.0 = Debug|Win32 + {5A4EADF2-3237-457A-9DA8-BB9942A91019}.Debug|x64.ActiveCfg = Debug|x64 + {5A4EADF2-3237-457A-9DA8-BB9942A91019}.Debug|x64.Build.0 = Debug|x64 + {5A4EADF2-3237-457A-9DA8-BB9942A91019}.Release|Win32.ActiveCfg = Release|Win32 + {5A4EADF2-3237-457A-9DA8-BB9942A91019}.Release|Win32.Build.0 = Release|Win32 + {5A4EADF2-3237-457A-9DA8-BB9942A91019}.Release|x64.ActiveCfg = Release|x64 + {5A4EADF2-3237-457A-9DA8-BB9942A91019}.Release|x64.Build.0 = Release|x64 {8552EE55-177E-4F51-B51B-BAF7D6462CDE}.Debug|Win32.ActiveCfg = Debug|Win32 {8552EE55-177E-4F51-B51B-BAF7D6462CDE}.Debug|Win32.Build.0 = Debug|Win32 {8552EE55-177E-4F51-B51B-BAF7D6462CDE}.Debug|x64.ActiveCfg = Debug|x64 @@ -38,4 +45,8 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {5A4EADF2-3237-457A-9DA8-BB9942A91019} = {26350A68-2F55-4732-972C-4A5E9077699E} + {8552EE55-177E-4F51-B51B-BAF7D6462CDE} = {26350A68-2F55-4732-972C-4A5E9077699E} + EndGlobalSection EndGlobal diff --git a/MSICA/L10N/sl_SI.po b/MSICA/L10N/sl_SI.po index 95eee6a..3c4dd3c 100644 --- a/MSICA/L10N/sl_SI.po +++ b/MSICA/L10N/sl_SI.po @@ -15,7 +15,6 @@ msgstr "" "X-Poedit-Basepath: ..\n" "X-Generator: Poedit 1.7.4\n" "X-Poedit-SearchPath-0: MSIBuild\n" -"X-Poedit-SearchPath-1: res\n" # Language Code and Windows Charset (hexadecimal) # If we do not intend to provide different localization of same base language (like merging Portugal Portugeese and Brasil Portugese into the same Portugeese), use the code of Microsoft defined default sublanguage. diff --git a/MSICA/MSICA.h b/MSICA/MSICA.h index 6d6b5e9..9bbd5b9 100644 --- a/MSICA/MSICA.h +++ b/MSICA/MSICA.h @@ -20,8 +20,23 @@ #ifndef __MSICA_H__ #define __MSICA_H__ -#include +//////////////////////////////////////////////////////////////////// +// Version +//////////////////////////////////////////////////////////////////// +#define MSICA_VERSION 0x00ff0400 + +#define MSICA_VERSION_MAJ 0 +#define MSICA_VERSION_MIN 255 +#define MSICA_VERSION_REV 4 +#define MSICA_VERSION_BUILD 0 + +#define MSICA_VERSION_STR "1.0-pre4" +#define MSICA_BUILD_YEAR_STR "2015" + +#if !defined(RC_INVOKED) && !defined(MIDL_PASS) + +#include //////////////////////////////////////////////////////////////////// // Calling declaration @@ -50,4 +65,5 @@ extern "C" { } #endif +#endif // !RC_INVOKED && !MIDL_PASS #endif // __MSICA_H__ diff --git a/MSICA/MSICA.props b/MSICA/MSICA.props index b8eb6ae..57fe259 100644 --- a/MSICA/MSICA.props +++ b/MSICA/MSICA.props @@ -3,7 +3,7 @@ - ..\output\$(Platform).$(Configuration)\ + ..\..\output\$(Platform).$(Configuration)\ true @@ -13,6 +13,9 @@ L10N\sl_SI.po + + ..\include;..\..\lib\MSICALib\include;..\..\lib\atlex\include;%(AdditionalIncludeDirectories) + \ No newline at end of file diff --git a/MSICA/res/MSICA.rcx b/MSICA/MSICA.rc similarity index 57% rename from MSICA/res/MSICA.rcx rename to MSICA/MSICA.rc index d182a10..a44bdb2 100644 Binary files a/MSICA/res/MSICA.rcx and b/MSICA/MSICA.rc differ diff --git a/MSICA/MSICA.vcxproj b/MSICA/MSICA.vcxproj index 39ce530..0207075 100644 --- a/MSICA/MSICA.vcxproj +++ b/MSICA/MSICA.vcxproj @@ -46,35 +46,33 @@ Unicode - - - + - - - + + + - - - + + + - - - + + + - - - + + + @@ -98,22 +96,17 @@ - - - - - - - + {8552ee55-177e-4f51-b51b-baf7d6462cde} + + + - - - + \ No newline at end of file diff --git a/MSICA/MSICA.vcxproj.filters b/MSICA/MSICA.vcxproj.filters index f30cae1..7b43fa9 100644 --- a/MSICA/MSICA.vcxproj.filters +++ b/MSICA/MSICA.vcxproj.filters @@ -30,19 +30,14 @@ Header Files - - - Resource Files - - - - - Resource Files - - Resource Files + + + Resource Files + + \ No newline at end of file diff --git a/MSICA/res/MSICA.rc b/MSICA/res/MSICA.rc deleted file mode 100644 index 28e49c1..0000000 Binary files a/MSICA/res/MSICA.rc and /dev/null differ diff --git a/MSICA/stdafx.h b/MSICA/stdafx.h index 704a6c8..cd320f4 100644 --- a/MSICA/stdafx.h +++ b/MSICA/stdafx.h @@ -32,6 +32,6 @@ #include #include -#include "..\MSICALib\MSICALib.h" +#include #include "MSICA.h" diff --git a/MSICALib/L10N/sl_SI.po b/MSICALib/L10N/sl_SI.po deleted file mode 100644 index 5005f33..0000000 --- a/MSICALib/L10N/sl_SI.po +++ /dev/null @@ -1,253 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: MSICALib\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-01 08:17+0100\n" -"PO-Revision-Date: \n" -"Last-Translator: Simon Rozman \n" -"Language-Team: Amebis, d. o. o., Kamnik \n" -"Language: sl\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-SourceCharset: UTF-8\n" -"X-Poedit-KeywordsList: __\n" -"X-Poedit-Basepath: ..\n" -"X-Generator: Poedit 1.7.5\n" -"X-Poedit-SearchPath-0: MSIBuild\n" - -# Windows charset for this language (decimal) -#: MSIBuild/En.Win32.Debug.Error-2.idtx:3 -#: MSIBuild/En.Win32.Release.Error-2.idtx:3 -#: MSIBuild/En.x64.Debug.Error-2.idtx:3 MSIBuild/En.x64.Release.Error-2.idtx:3 -msgid "1252" -msgstr "1250" - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:5 -#: MSIBuild/En.Win32.Release.Error-2.idtx:5 -#: MSIBuild/En.x64.Debug.Error-2.idtx:5 MSIBuild/En.x64.Release.Error-2.idtx:5 -msgid "Error [2] creating task list. Please, contact your support personnel." -msgstr "" -"Pri pripravi seznama opravil je prišlo do napake [2]. Obrnite se na svojo " -"tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:21 -#: MSIBuild/En.Win32.Release.Error-2.idtx:21 -#: MSIBuild/En.x64.Debug.Error-2.idtx:21 -#: MSIBuild/En.x64.Release.Error-2.idtx:21 -msgid "Error [2] opening WLAN handle. Please, contact your support personnel." -msgstr "" -"Pri odpiranju ročice WLAN je prišlo do napake [2]. Obrnite se na svojo " -"tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:17 -#: MSIBuild/En.Win32.Release.Error-2.idtx:17 -#: MSIBuild/En.x64.Debug.Error-2.idtx:17 -#: MSIBuild/En.x64.Release.Error-2.idtx:17 -msgid "" -"Error [3] changing service \"[2]\" start type. Please, contact your support " -"personnel." -msgstr "" -"Pri nastavljanju servisa »[2]« je prišlo do napake [3]. Obrnite se na svojo " -"tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:11 -#: MSIBuild/En.Win32.Release.Error-2.idtx:11 -#: MSIBuild/En.x64.Debug.Error-2.idtx:11 -#: MSIBuild/En.x64.Release.Error-2.idtx:11 -msgid "" -"Error [3] creating \"[2]\" scheduled task. Please, contact your support " -"personnel." -msgstr "" -"Pri stvaritvi razporejenega opravila »[2]« je prišlo do napake [3]. Obrnite " -"se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:9 -#: MSIBuild/En.Win32.Release.Error-2.idtx:9 -#: MSIBuild/En.x64.Debug.Error-2.idtx:9 MSIBuild/En.x64.Release.Error-2.idtx:9 -msgid "" -"Error [3] deleting \"[2]\" file. Please, contact your support personnel." -msgstr "" -"Pri brisanju datoteke »[2]« je prišlo do napake [3]. Obrnite se na svojo " -"tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:12 -#: MSIBuild/En.Win32.Release.Error-2.idtx:12 -#: MSIBuild/En.x64.Debug.Error-2.idtx:12 -#: MSIBuild/En.x64.Release.Error-2.idtx:12 -msgid "" -"Error [3] deleting \"[2]\" scheduled task. Please, contact your support " -"personnel." -msgstr "" -"Pri brisanju razporejenega opravila »[2]« je prišlo do napake [3]. Obrnite " -"se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:13 -#: MSIBuild/En.Win32.Release.Error-2.idtx:13 -#: MSIBuild/En.x64.Debug.Error-2.idtx:13 -#: MSIBuild/En.x64.Release.Error-2.idtx:13 -msgid "" -"Error [3] enabling/disabling \"[2]\" scheduled task. Please, contact your " -"support personnel." -msgstr "" -"Pri o(ne)mogočanju razporejenega opravila »[2]« je prišlo do napake [3]. " -"Obrnite se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:15 -#: MSIBuild/En.Win32.Release.Error-2.idtx:15 -#: MSIBuild/En.x64.Debug.Error-2.idtx:15 -#: MSIBuild/En.x64.Release.Error-2.idtx:15 -msgid "" -"Error [3] installing certificate to certificate store \"[2]\". Please, " -"contact your support personnel." -msgstr "" -"Pri nameščanju digitalnega potrdila v shrambo »[2]« je prišlo do napake [3]. " -"Obrnite se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:7 -#: MSIBuild/En.Win32.Release.Error-2.idtx:7 -#: MSIBuild/En.x64.Debug.Error-2.idtx:7 MSIBuild/En.x64.Release.Error-2.idtx:7 -msgid "" -"Error [3] reading from \"[2]\" task list file. Please, contact your support " -"personnel." -msgstr "" -"Pri branju iz datoteke seznama opravil »[2]« je prišlo do napake [3]. " -"Obrnite se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:16 -#: MSIBuild/En.Win32.Release.Error-2.idtx:16 -#: MSIBuild/En.x64.Debug.Error-2.idtx:16 -#: MSIBuild/En.x64.Release.Error-2.idtx:16 -msgid "" -"Error [3] removing certificate from certificate store \"[2]\". Please, " -"contact your support personnel." -msgstr "" -"Pri odstranjevanju digitalnega potrdila iz shrambe »[2]« je prišlo do napake " -"[3]. Obrnite se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:8 -#: MSIBuild/En.Win32.Release.Error-2.idtx:8 -#: MSIBuild/En.x64.Debug.Error-2.idtx:8 MSIBuild/En.x64.Release.Error-2.idtx:8 -msgid "" -"Error [3] setting \"[2]\" parameter. Please, contact your support personnel." -msgstr "" -"Pri nastavljanju parametra »[2]« je prišlo do napake [3]. Obrnite se na " -"svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:18 -#: MSIBuild/En.Win32.Release.Error-2.idtx:18 -#: MSIBuild/En.x64.Debug.Error-2.idtx:18 -#: MSIBuild/En.x64.Release.Error-2.idtx:18 -msgid "" -"Error [3] starting service \"[2]\". Please, contact your support personnel." -msgstr "" -"Pri zagonu servisa »[2]« je prišlo do napake [3]. Obrnite se na svojo " -"tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:19 -#: MSIBuild/En.Win32.Release.Error-2.idtx:19 -#: MSIBuild/En.x64.Debug.Error-2.idtx:19 -#: MSIBuild/En.x64.Release.Error-2.idtx:19 -msgid "" -"Error [3] stopping service \"[2]\". Please, contact your support personnel." -msgstr "" -"Pri zaustavitvi servisa »[2]« je prišlo do napake [3]. Obrnite se na svojo " -"tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:6 -#: MSIBuild/En.Win32.Release.Error-2.idtx:6 -#: MSIBuild/En.x64.Debug.Error-2.idtx:6 MSIBuild/En.x64.Release.Error-2.idtx:6 -msgid "" -"Error [3] writing to \"[2]\" task list file. Please, contact your support " -"personnel." -msgstr "" -"Pri pisanju v datoteko seznama opravil »[2]« je prišlo do napake [3]. " -"Obrnite se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:14 -#: MSIBuild/En.Win32.Release.Error-2.idtx:14 -#: MSIBuild/En.x64.Debug.Error-2.idtx:14 -#: MSIBuild/En.x64.Release.Error-2.idtx:14 -msgid "" -"Error [4] copying \"[2]\" scheduled task to \"[3]\". Please, contact your " -"support personnel." -msgstr "" -"Pri kopiranju razporejenega opravila »[2]« v »[3]« je prišlo do napake [4]. " -"Obrnite se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:23 -#: MSIBuild/En.Win32.Release.Error-2.idtx:23 -#: MSIBuild/En.x64.Debug.Error-2.idtx:23 -#: MSIBuild/En.x64.Release.Error-2.idtx:23 -msgid "" -"Error [4] deleting profile \"[3]\" on WLAN interface [2]. Please, contact " -"your support personnel." -msgstr "" -"Pri brisanju profila »[3]« na vmesniku WLAN [2] je prišlo do napake [4]. " -"Obrnite se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:10 -#: MSIBuild/En.Win32.Release.Error-2.idtx:10 -#: MSIBuild/En.x64.Debug.Error-2.idtx:10 -#: MSIBuild/En.x64.Release.Error-2.idtx:10 -msgid "" -"Error [4] moving \"[2]\" file to \"[3]\". Please, contact your support " -"personnel." -msgstr "" -"Pri premikanju datoteke »[2]« v »[3]« je prišlo do napake [4]. Obrnite se na " -"svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:24 -#: MSIBuild/En.Win32.Release.Error-2.idtx:24 -#: MSIBuild/En.x64.Debug.Error-2.idtx:24 -#: MSIBuild/En.x64.Release.Error-2.idtx:24 -msgid "" -"Error [5] renaming profile \"[3]\" to \"[4]\" on WLAN interface [2]. Please, " -"contact your support personnel." -msgstr "" -"Pri preimenovanju profila »[3]« v »[4]« na vmesniku WLAN [2] je prišlo do " -"napake [5]. Obrnite se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:25 -#: MSIBuild/En.Win32.Release.Error-2.idtx:25 -#: MSIBuild/En.x64.Debug.Error-2.idtx:25 -#: MSIBuild/En.x64.Release.Error-2.idtx:25 -msgid "" -"Error [5] setting profile \"[3]\" on WLAN interface [2] (WLAN reason is " -"[4]). Please, contact your support personnel." -msgstr "" -"Pri nastavljanju profila »[3]« na vmesniku WLAN [2] je prišlo do napake [5] " -"(vzrok WLAN je [4]). Obrnite se na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:4 -#: MSIBuild/En.Win32.Release.Error-2.idtx:4 -#: MSIBuild/En.x64.Debug.Error-2.idtx:4 MSIBuild/En.x64.Release.Error-2.idtx:4 -msgid "" -"Error opening installation package. Please, contact your support personnel." -msgstr "" -"Pri odpiranju namestitvenega paketa je prišlo do napake. Obrnite se na svojo " -"tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:20 -#: MSIBuild/En.Win32.Release.Error-2.idtx:20 -#: MSIBuild/En.x64.Debug.Error-2.idtx:20 -#: MSIBuild/En.x64.Release.Error-2.idtx:20 -msgid "" -"Error opening WLAN handle, because WLAN AutoConfig service is not started. " -"Please, enable and start WLAN AutoConfig service, or contact your support " -"personnel." -msgstr "" -"Pri odpiranju ročice WLAN je prišlo do napake, ker storitev WLAN AutoConfig " -"ni zagnana. Omogočite in zaženite storitev WLAN AutoConfig, ali se obrnite " -"na svojo tehnično službo." - -#: MSIBuild/En.Win32.Debug.Error-2.idtx:22 -#: MSIBuild/En.Win32.Release.Error-2.idtx:22 -#: MSIBuild/En.x64.Debug.Error-2.idtx:22 -#: MSIBuild/En.x64.Release.Error-2.idtx:22 -msgid "" -"WLAN profile \"[2]\" XML data is not UTF-16 encoded. Please, contact your " -"support personnel." -msgstr "" -"Zapis XML profila WLAN »[2]« ni zapisan v UTF-16. Obrnite se na svojo " -"tehnično službo." diff --git a/MSICALib/MSIBuild/Makefile b/MSICALib/MSIBuild/Makefile deleted file mode 100644 index d883704..0000000 --- a/MSICALib/MSIBuild/Makefile +++ /dev/null @@ -1,87 +0,0 @@ -# -# Copyright 1991-2015 Amebis -# -# This file is part of MSICA. -# -# MSICA 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 3 of the License, or -# (at your option) any later version. -# -# MSICA 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 MSICA. If not, see . -# - -!INCLUDE "..\..\..\include\MSIBuildCfg.mak" - -MSIBUILD_IS_LOCALIZEABLE=1 - - -###################################################################### -# Error - -All :: \ - "$(LANG).$(PLAT).$(CFG).Error-1.idt" \ - "$(LANG).$(PLAT).$(CFG).Error-2.idt" - -"$(LANG).$(PLAT).$(CFG).Error-1.idt" : "Makefile" "..\..\..\include\MSIBuildCfg.mak" - -if exist $@ del /f /q $@ - move /y << $@ > NUL -Error Message -i2 L0 -Error Error -< NUL -Error Message -i2 L0 -1252 Error Error -2550 Error opening installation package. Please, contact your support personnel. -2551 Error [2] creating task list. Please, contact your support personnel. -2552 Error [3] writing to "[2]" task list file. Please, contact your support personnel. -2560 Error [3] reading from "[2]" task list file. Please, contact your support personnel. -2553 Error [3] setting "[2]" parameter. Please, contact your support personnel. -2554 Error [3] deleting "[2]" file. Please, contact your support personnel. -2555 Error [4] moving "[2]" file to "[3]". Please, contact your support personnel. -2556 Error [3] creating "[2]" scheduled task. Please, contact your support personnel. -2557 Error [3] deleting "[2]" scheduled task. Please, contact your support personnel. -2558 Error [3] enabling/disabling "[2]" scheduled task. Please, contact your support personnel. -2559 Error [4] copying "[2]" scheduled task to "[3]". Please, contact your support personnel. -2569 Error [3] installing certificate to certificate store "[2]". Please, contact your support personnel. -2570 Error [3] removing certificate from certificate store "[2]". Please, contact your support personnel. -2571 Error [3] changing service "[2]" start type. Please, contact your support personnel. -2572 Error [3] starting service "[2]". Please, contact your support personnel. -2573 Error [3] stopping service "[2]". Please, contact your support personnel. -2579 Error opening WLAN handle, because WLAN AutoConfig service is not started. Please, enable and start WLAN AutoConfig service, or contact your support personnel. -2577 Error [2] opening WLAN handle. Please, contact your support personnel. -2578 WLAN profile "[2]" XML data is not UTF-16 encoded. Please, contact your support personnel. -2574 Error [4] deleting profile "[3]" on WLAN interface [2]. Please, contact your support personnel. -2575 Error [5] renaming profile "[3]" to "[4]" on WLAN interface [2]. Please, contact your support personnel. -2576 Error [5] setting profile "[3]" on WLAN interface [2] (WLAN reason is [4]). Please, contact your support personnel. -< NUL - -"It.$(PLAT).$(CFG).Error-2.idt" : "En.$(PLAT).$(CFG).Error-2.idtx" "..\L10N\it_IT.po" - rcxgettext.exe idtp $@ $** - -"Sl.$(PLAT).$(CFG).Error-2.idt" : "En.$(PLAT).$(CFG).Error-2.idtx" "..\L10N\sl_SI.po" - rcxgettext.exe idtp $@ $** - - -###################################################################### -# Build MSM module! -###################################################################### - -!INCLUDE "..\..\..\MSIBuild\MSM.mak" diff --git a/MSICALib/MSIBuild/build_all.bat b/MSICALib/MSIBuild/build_all.bat deleted file mode 100644 index 16b8bc7..0000000 --- a/MSICALib/MSIBuild/build_all.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo off -nmake.exe /ls All LANG=En CFG=Debug PLAT=Win32 -nmake.exe /ls All LANG=Sl CFG=Debug PLAT=Win32 -nmake.exe /ls All LANG=En CFG=Debug PLAT=x64 -nmake.exe /ls All LANG=Sl CFG=Debug PLAT=x64 -nmake.exe /ls All LANG=En CFG=Release PLAT=Win32 -nmake.exe /ls All LANG=Sl CFG=Release PLAT=Win32 -nmake.exe /ls All LANG=En CFG=Release PLAT=x64 -nmake.exe /ls All LANG=Sl CFG=Release PLAT=x64 diff --git a/MSICALib/MSIBuild/clean_all.bat b/MSICALib/MSIBuild/clean_all.bat deleted file mode 100644 index b1ff08a..0000000 --- a/MSICALib/MSIBuild/clean_all.bat +++ /dev/null @@ -1,9 +0,0 @@ -@echo off -nmake.exe /ls Clean LANG=En CFG=Debug PLAT=Win32 -nmake.exe /ls Clean LANG=Sl CFG=Debug PLAT=Win32 -nmake.exe /ls Clean LANG=En CFG=Debug PLAT=x64 -nmake.exe /ls Clean LANG=Sl CFG=Debug PLAT=x64 -nmake.exe /ls Clean LANG=En CFG=Release PLAT=Win32 -nmake.exe /ls Clean LANG=Sl CFG=Release PLAT=Win32 -nmake.exe /ls Clean LANG=En CFG=Release PLAT=x64 -nmake.exe /ls Clean LANG=Sl CFG=Release PLAT=x64 diff --git a/MSICALib/MSICALib.cpp b/MSICALib/MSICALib.cpp deleted file mode 100644 index aabdc23..0000000 --- a/MSICALib/MSICALib.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#include "stdafx.h" - -#pragma comment(lib, "msi.lib") - - -namespace MSICA { - -//////////////////////////////////////////////////////////////////////////// -// COperation -//////////////////////////////////////////////////////////////////////////// - -COperation::COperation(int iTicks) : - m_iTicks(iTicks) -{ -} - - -//////////////////////////////////////////////////////////////////////////// -// COpTypeSingleString -//////////////////////////////////////////////////////////////////////////// - -COpTypeSingleString::COpTypeSingleString(LPCWSTR pszValue, int iTicks) : - m_sValue(pszValue), - COperation(iTicks) -{ -} - - -//////////////////////////////////////////////////////////////////////////// -// COpTypeSrcDstString -//////////////////////////////////////////////////////////////////////////// - -COpTypeSrcDstString::COpTypeSrcDstString(LPCWSTR pszValue1, LPCWSTR pszValue2, int iTicks) : - m_sValue1(pszValue1), - m_sValue2(pszValue2), - COperation(iTicks) -{ -} - - -//////////////////////////////////////////////////////////////////////////// -// COpTypeBoolean -//////////////////////////////////////////////////////////////////////////// - -COpTypeBoolean::COpTypeBoolean(BOOL bValue, int iTicks) : - m_bValue(bValue), - COperation(iTicks) -{ -} - - -//////////////////////////////////////////////////////////////////////////// -// COpRollbackEnable -//////////////////////////////////////////////////////////////////////////// - -COpRollbackEnable::COpRollbackEnable(BOOL bEnable, int iTicks) : - COpTypeBoolean(bEnable, iTicks) -{ -} - - -HRESULT COpRollbackEnable::Execute(CSession *pSession) -{ - pSession->m_bRollbackEnabled = m_bValue; - return S_OK; -} - - -//////////////////////////////////////////////////////////////////////////// -// COpList -//////////////////////////////////////////////////////////////////////////// - -COpList::COpList(int iTicks) : - COperation(iTicks), - ATL::CAtlList(sizeof(COperation*)) -{ -} - - -void COpList::Free() -{ - POSITION pos; - - for (pos = GetHeadPosition(); pos;) { - COperation *pOp = GetNext(pos); - COpList *pOpList = dynamic_cast(pOp); - - if (pOpList) { - // Recursivelly free sublists. - pOpList->Free(); - } - delete pOp; - } - - RemoveAll(); -} - - -HRESULT COpList::LoadFromFile(LPCTSTR pszFileName) -{ - HRESULT hr; - ATL::CAtlFile fSequence; - - hr = fSequence.Create(pszFileName, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN); - if (FAILED(hr)) return hr; - - // Load operation sequence. - return fSequence >> *this; -} - - -HRESULT COpList::SaveToFile(LPCTSTR pszFileName) const -{ - HRESULT hr; - ATL::CAtlFile fSequence; - - hr = fSequence.Create(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN); - if (FAILED(hr)) return hr; - - // Save execute sequence to file. - hr = fSequence << *this; - fSequence.Close(); - - if (FAILED(hr)) ::DeleteFile(pszFileName); - return hr; -} - - -HRESULT COpList::Execute(CSession *pSession) -{ - POSITION pos; - HRESULT hr; - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - - // Tell the installer to use explicit progress messages. - ::MsiRecordSetInteger(hRecordProg, 1, 1); - ::MsiRecordSetInteger(hRecordProg, 2, 1); - ::MsiRecordSetInteger(hRecordProg, 3, 0); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg); - - // Prepare hRecordProg for progress messages. - ::MsiRecordSetInteger(hRecordProg, 1, 2); - ::MsiRecordSetInteger(hRecordProg, 3, 0); - - for (pos = GetHeadPosition(); pos;) { - COperation *pOp = GetNext(pos); - - hr = pOp->Execute(pSession); - if (!pSession->m_bContinueOnError && FAILED(hr)) { - // Operation failed. Its Execute() method should have sent error message to Installer. - // Therefore, just quit here. - return hr; - } - - ::MsiRecordSetInteger(hRecordProg, 2, pOp->m_iTicks); - if (::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL) - return AtlHresultFromWin32(ERROR_INSTALL_USEREXIT); - } - - ::MsiRecordSetInteger(hRecordProg, 2, m_iTicks); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg); - - return S_OK; -} - - -//////////////////////////////////////////////////////////////////////////// -// CSession -//////////////////////////////////////////////////////////////////////////// - -CSession::CSession() : - m_hInstall(NULL), - m_bContinueOnError(FALSE), - m_bRollbackEnabled(FALSE) -{ -} - - -CSession::~CSession() -{ - m_olRollback.Free(); - m_olCommit.Free(); -} - - -//////////////////////////////////////////////////////////////////////////// -// Helper functions -//////////////////////////////////////////////////////////////////////////// - -UINT SaveSequence(MSIHANDLE hInstall, LPCTSTR szActionExecute, LPCTSTR szActionCommit, LPCTSTR szActionRollback, const COpList &olExecute) -{ - HRESULT hr; - UINT uiResult; - ATL::CAtlString sSequenceFilename; - ATL::CAtlFile fSequence; - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - - // Prepare our own sequence script file. - // The InstallCertificates is a deferred custom action, thus all this information will be unavailable to it. - // Therefore save all required info to file now. - { - LPTSTR szBuffer = sSequenceFilename.GetBuffer(MAX_PATH); - ::GetTempPath(MAX_PATH, szBuffer); - ::GetTempFileName(szBuffer, _T("MSICA"), 0, szBuffer); - sSequenceFilename.ReleaseBuffer(); - } - // Save execute sequence to file. - hr = olExecute.SaveToFile(sSequenceFilename); - if (SUCCEEDED(hr)) { - // Store sequence script file names to properties for deferred custiom actions. - uiResult = ::MsiSetProperty(hInstall, szActionExecute, sSequenceFilename); - if (uiResult == NO_ERROR) { - LPCTSTR pszExtension = ::PathFindExtension(sSequenceFilename); - ATL::CAtlString sSequenceFilename2; - - sSequenceFilename2.Format(_T("%.*ls-rb%ls"), pszExtension - (LPCTSTR)sSequenceFilename, (LPCTSTR)sSequenceFilename, pszExtension); - uiResult = ::MsiSetProperty(hInstall, szActionRollback, sSequenceFilename2); - if (uiResult == NO_ERROR) { - sSequenceFilename2.Format(_T("%.*ls-cm%ls"), pszExtension - (LPCTSTR)sSequenceFilename, (LPCTSTR)sSequenceFilename, pszExtension); - uiResult = ::MsiSetProperty(hInstall, szActionCommit, sSequenceFilename2); - if (uiResult != NO_ERROR) { - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_PROPERTY_SET); - ::MsiRecordSetString (hRecordProg, 2, szActionCommit ); - ::MsiRecordSetInteger(hRecordProg, 3, uiResult ); - ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - } else { - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_PROPERTY_SET); - ::MsiRecordSetString (hRecordProg, 2, szActionRollback ); - ::MsiRecordSetInteger(hRecordProg, 3, uiResult ); - ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - } else { - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_PROPERTY_SET); - ::MsiRecordSetString (hRecordProg, 2, szActionExecute ); - ::MsiRecordSetInteger(hRecordProg, 3, uiResult ); - ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - if (uiResult != NO_ERROR) ::DeleteFile(sSequenceFilename); - } else { - uiResult = ERROR_INSTALL_SCRIPT_WRITE; - ::MsiRecordSetInteger(hRecordProg, 1, uiResult ); - ::MsiRecordSetString (hRecordProg, 2, sSequenceFilename); - ::MsiRecordSetInteger(hRecordProg, 3, hr ); - ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - - return uiResult; -} - - -UINT ExecuteSequence(MSIHANDLE hInstall) -{ - UINT uiResult; - HRESULT hr; - BOOL bIsCoInitialized = SUCCEEDED(::CoInitialize(NULL)); - ATL::CAtlString sSequenceFilename; - - uiResult = ::MsiGetProperty(hInstall, _T("CustomActionData"), sSequenceFilename); - if (uiResult == NO_ERROR) { - MSICA::COpList lstOperations; - BOOL bIsCleanup = ::MsiGetMode(hInstall, MSIRUNMODE_COMMIT) || ::MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK); - - // Load operation sequence. - hr = lstOperations.LoadFromFile(sSequenceFilename); - if (SUCCEEDED(hr)) { - MSICA::CSession session; - - session.m_hInstall = hInstall; - - // In case of commit/rollback, continue sequence on error, to do as much cleanup as possible. - session.m_bContinueOnError = bIsCleanup; - - // Execute the operations. - hr = lstOperations.Execute(&session); - if (!bIsCleanup) { - // Save cleanup scripts of delayed action regardless of action's execution status. - // Rollback action MUST be scheduled in InstallExecuteSequence before this action! Otherwise cleanup won't be performed in case this action execution failed. - LPCTSTR pszExtension = ::PathFindExtension(sSequenceFilename); - ATL::CAtlString sSequenceFilenameCM, sSequenceFilenameRB; - HRESULT hr; - - sSequenceFilenameRB.Format(_T("%.*ls-rb%ls"), pszExtension - (LPCTSTR)sSequenceFilename, (LPCTSTR)sSequenceFilename, pszExtension); - sSequenceFilenameCM.Format(_T("%.*ls-cm%ls"), pszExtension - (LPCTSTR)sSequenceFilename, (LPCTSTR)sSequenceFilename, pszExtension); - - // After commit, delete rollback file. After rollback, delete commit file. - session.m_olCommit.AddTail(new MSICA::COpFileDelete( -#ifdef _UNICODE - sSequenceFilenameRB -#else - ATL::CAtlStringW(sSequenceFilenameRB) -#endif - )); - session.m_olRollback.AddTail(new MSICA::COpFileDelete( -#ifdef _UNICODE - sSequenceFilenameCM -#else - ATL::CAtlStringW(sSequenceFilenameCM) -#endif - )); - - // Save commit file first. - hr = session.m_olCommit.SaveToFile(sSequenceFilenameCM); - if (SUCCEEDED(hr)) { - // Save rollback file next. - hr = session.m_olRollback.SaveToFile(sSequenceFilenameRB); - if (SUCCEEDED(hr)) { - uiResult = NO_ERROR; - } else { - // Saving rollback file failed. - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - uiResult = ERROR_INSTALL_SCRIPT_WRITE; - ::MsiRecordSetInteger(hRecordProg, 1, uiResult ); - ::MsiRecordSetString (hRecordProg, 2, sSequenceFilenameRB); - ::MsiRecordSetInteger(hRecordProg, 3, hr ); - ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - } else { - // Saving commit file failed. - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - uiResult = ERROR_INSTALL_SCRIPT_WRITE; - ::MsiRecordSetInteger(hRecordProg, 1, uiResult ); - ::MsiRecordSetString (hRecordProg, 2, sSequenceFilenameCM); - ::MsiRecordSetInteger(hRecordProg, 3, hr ); - ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - - if (uiResult != NO_ERROR) { - // The commit and/or rollback scripts were not written to file successfully. Perform the cleanup immediately. - session.m_bContinueOnError = TRUE; - session.m_bRollbackEnabled = FALSE; - session.m_olRollback.Execute(&session); - ::DeleteFile(sSequenceFilenameRB); - } - } else { - // No cleanup after cleanup support. - uiResult = NO_ERROR; - } - - if (FAILED(hr)) { - // Execution of the action failed. - uiResult = HRESULT_CODE(hr); - } - - ::DeleteFile(sSequenceFilename); - } else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) && bIsCleanup) { - // Sequence file not found and this is rollback/commit action. Either of the following scenarios are possible: - // - The delayed action failed to save the rollback/commit file. The delayed action performed cleanup itself. No further action is required. - // - Somebody removed the rollback/commit file between delayed action and rollback/commit action. No further action is possible. - uiResult = NO_ERROR; - } else { - // Sequence loading failed. Probably, LOCAL SYSTEM doesn't have read access to user's temp directory. - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - uiResult = ERROR_INSTALL_SCRIPT_READ; - ::MsiRecordSetInteger(hRecordProg, 1, uiResult ); - ::MsiRecordSetString (hRecordProg, 2, sSequenceFilename); - ::MsiRecordSetInteger(hRecordProg, 3, hr ); - ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - - lstOperations.Free(); - } else { - // Couldn't get CustomActionData property. uiResult has the error code. - } - - if (bIsCoInitialized) ::CoUninitialize(); - return uiResult; -} - -} // namespace MSICA diff --git a/MSICALib/MSICALib.h b/MSICALib/MSICALib.h deleted file mode 100644 index 118c449..0000000 --- a/MSICALib/MSICALib.h +++ /dev/null @@ -1,1550 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#ifndef __MSICALib_H__ -#define __MSICALib_H__ - -#include -#include -#include -#include -#include -#include -#include -#include - - -//////////////////////////////////////////////////////////////////// -// Error codes (next unused 2580L) -//////////////////////////////////////////////////////////////////// - -#define ERROR_INSTALL_DATABASE_OPEN 2550L -#define ERROR_INSTALL_OPLIST_CREATE 2551L -#define ERROR_INSTALL_PROPERTY_SET 2553L -#define ERROR_INSTALL_SCRIPT_WRITE 2552L -#define ERROR_INSTALL_SCRIPT_READ 2560L -#define ERROR_INSTALL_FILE_DELETE 2554L -#define ERROR_INSTALL_FILE_MOVE 2555L -#define ERROR_INSTALL_REGKEY_CREATE 2561L -#define ERROR_INSTALL_REGKEY_COPY 2562L -#define ERROR_INSTALL_REGKEY_PROBING 2563L -#define ERROR_INSTALL_REGKEY_DELETE 2564L -#define ERROR_INSTALL_REGKEY_SETVALUE 2565L -#define ERROR_INSTALL_REGKEY_DELETEVALUE 2567L -#define ERROR_INSTALL_REGKEY_COPYVALUE 2568L -#define ERROR_INSTALL_REGKEY_PROBINGVAL 2566L -#define ERROR_INSTALL_TASK_CREATE 2556L -#define ERROR_INSTALL_TASK_DELETE 2557L -#define ERROR_INSTALL_TASK_ENABLE 2558L -#define ERROR_INSTALL_TASK_COPY 2559L -#define ERROR_INSTALL_CERT_INSTALL 2569L -#define ERROR_INSTALL_CERT_REMOVE 2570L -#define ERROR_INSTALL_SVC_SET_START 2571L -#define ERROR_INSTALL_SVC_START 2572L -#define ERROR_INSTALL_SVC_STOP 2573L -#define ERROR_INSTALL_WLAN_SVC_NOT_STARTED 2579L -#define ERROR_INSTALL_WLAN_HANDLE_OPEN 2577L -#define ERROR_INSTALL_WLAN_PROFILE_NOT_UTF16 2578L -#define ERROR_INSTALL_WLAN_PROFILE_DELETE 2574L -#define ERROR_INSTALL_WLAN_PROFILE_RENAME 2575L -#define ERROR_INSTALL_WLAN_PROFILE_SET 2576L - - -namespace MSICA { - - -//////////////////////////////////////////////////////////////////////////// -// Forward declarations -//////////////////////////////////////////////////////////////////////////// - -class CSession; - - -//////////////////////////////////////////////////////////////////////////// -// COperation -//////////////////////////////////////////////////////////////////////////// - -class COperation -{ -public: - COperation(int iTicks = 0); - - virtual HRESULT Execute(CSession *pSession) = 0; - - friend class COpList; - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COperation &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COperation &op); - -protected: - int m_iTicks; // Number of ticks on a progress bar required for this action execution -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpTypeSingleString -//////////////////////////////////////////////////////////////////////////// - -class COpTypeSingleString : public COperation -{ -public: - COpTypeSingleString(LPCWSTR pszValue = L"", int iTicks = 0); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpTypeSingleString &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeSingleString &op); - -protected: - ATL::CAtlStringW m_sValue; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpTypeSrcDstString -//////////////////////////////////////////////////////////////////////////// - -class COpTypeSrcDstString : public COperation -{ -public: - COpTypeSrcDstString(LPCWSTR pszValue1 = L"", LPCWSTR pszValue2 = L"", int iTicks = 0); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpTypeSrcDstString &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeSrcDstString &op); - -protected: - ATL::CAtlStringW m_sValue1; - ATL::CAtlStringW m_sValue2; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpTypeBoolean -//////////////////////////////////////////////////////////////////////////// - -class COpTypeBoolean : public COperation -{ -public: - COpTypeBoolean(BOOL bValue = TRUE, int iTicks = 0); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpTypeBoolean &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeBoolean &op); - -protected: - BOOL m_bValue; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRollbackEnable -//////////////////////////////////////////////////////////////////////////// - -class COpRollbackEnable : public COpTypeBoolean -{ -public: - COpRollbackEnable(BOOL bEnable = TRUE, int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpFileDelete -//////////////////////////////////////////////////////////////////////////// - -class COpFileDelete : public COpTypeSingleString -{ -public: - COpFileDelete(LPCWSTR pszFileName = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpFileMove -//////////////////////////////////////////////////////////////////////////// - -class COpFileMove : public COpTypeSrcDstString -{ -public: - COpFileMove(LPCWSTR pszFileSrc = L"", LPCWSTR pszFileDst = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRegKeySingle -//////////////////////////////////////////////////////////////////////////// - -class COpRegKeySingle : public COpTypeSingleString -{ -public: - COpRegKeySingle(HKEY hKeyRoot = NULL, LPCWSTR pszKeyName = L"", int iTicks = 0); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegKeySingle &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpRegKeySingle &op); - -protected: - HKEY m_hKeyRoot; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRegKeySrcDst -//////////////////////////////////////////////////////////////////////////// - -class COpRegKeySrcDst : public COpTypeSrcDstString -{ -public: - COpRegKeySrcDst(HKEY hKeyRoot = NULL, LPCWSTR pszKeyNameSrc = L"", LPCWSTR pszKeyNameDst = L"", int iTicks = 0); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegKeySrcDst &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpRegKeySrcDst &op); - -protected: - HKEY m_hKeyRoot; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRegKeyCreate -//////////////////////////////////////////////////////////////////////////// - -class COpRegKeyCreate : public COpRegKeySingle -{ -public: - COpRegKeyCreate(HKEY hKeyRoot = NULL, LPCWSTR pszKeyName = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRegKeyCopy -//////////////////////////////////////////////////////////////////////////// - -class COpRegKeyCopy : public COpRegKeySrcDst -{ -public: - COpRegKeyCopy(HKEY hKeyRoot = NULL, LPCWSTR pszKeyNameSrc = L"", LPCWSTR pszKeyNameDst = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); - -private: - static LONG CopyKeyRecursively(HKEY hKeyRoot, LPCWSTR pszKeyNameSrc, LPCWSTR pszKeyNameDst, REGSAM samAdditional); - static LONG CopyKeyRecursively(HKEY hKeySrc, HKEY hKeyDst, REGSAM samAdditional); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRegKeyDelete -//////////////////////////////////////////////////////////////////////////// - -class COpRegKeyDelete : public COpRegKeySingle -{ -public: - COpRegKeyDelete(HKEY hKeyRoot = NULL, LPCWSTR pszKeyName = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); - -private: - static LONG DeleteKeyRecursively(HKEY hKeyRoot, LPCWSTR pszKeyName, REGSAM samAdditional); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRegValueSingle -//////////////////////////////////////////////////////////////////////////// - -class COpRegValueSingle : public COpRegKeySingle -{ -public: - COpRegValueSingle(HKEY hKeyRoot = NULL, LPCWSTR pszKeyName = L"", LPCWSTR pszValueName = L"", int iTicks = 0); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegValueSingle &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpRegValueSingle &op); - -protected: - ATL::CAtlStringW m_sValueName; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRegValueSrcDst -//////////////////////////////////////////////////////////////////////////// - -class COpRegValueSrcDst : public COpRegKeySingle -{ -public: - COpRegValueSrcDst(HKEY hKeyRoot = NULL, LPCWSTR pszKeyName = L"", LPCWSTR pszValueNameSrc = L"", LPCWSTR pszValueNameDst = L"", int iTicks = 0); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegValueSrcDst &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpRegValueSrcDst &op); - -protected: - ATL::CAtlStringW m_sValueName1; - ATL::CAtlStringW m_sValueName2; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRegValueCreate -//////////////////////////////////////////////////////////////////////////// - -class COpRegValueCreate : public COpRegValueSingle -{ -public: - COpRegValueCreate(HKEY hKeyRoot = NULL, LPCWSTR pszKeyName = L"", LPCWSTR pszValueName = L"", int iTicks = 0); - COpRegValueCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, DWORD dwData, int iTicks = 0); - COpRegValueCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, LPCVOID lpData, SIZE_T nSize, int iTicks = 0); - COpRegValueCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, LPCWSTR pszData, int iTicks = 0); - COpRegValueCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, DWORDLONG qwData, int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegValueCreate &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpRegValueCreate &op); - -protected: - DWORD m_dwType; - ATL::CAtlStringW m_sData; - ATL::CAtlArray m_binData; - DWORD m_dwData; - ATL::CAtlArray m_szData; - DWORDLONG m_qwData; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRegValueCopy -//////////////////////////////////////////////////////////////////////////// - -class COpRegValueCopy : public COpRegValueSrcDst -{ -public: - COpRegValueCopy(HKEY hKeyRoot = NULL, LPCWSTR pszKeyName = L"", LPCWSTR pszValueNameSrc = L"", LPCWSTR pszValueNameDst = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpRegValueDelete -//////////////////////////////////////////////////////////////////////////// - -class COpRegValueDelete : public COpRegValueSingle -{ -public: - COpRegValueDelete(HKEY hKeyRoot = NULL, LPCWSTR pszKeyName = L"", LPCWSTR pszValueName = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpTaskCreate -//////////////////////////////////////////////////////////////////////////// - -class COpTaskCreate : public COpTypeSingleString -{ -public: - COpTaskCreate(LPCWSTR pszTaskName = L"", int iTicks = 0); - virtual ~COpTaskCreate(); - virtual HRESULT Execute(CSession *pSession); - - UINT SetFromRecord(MSIHANDLE hInstall, MSIHANDLE hRecord); - UINT SetTriggersFromView(MSIHANDLE hView); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpTaskCreate &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpTaskCreate &op); - -protected: - ATL::CAtlStringW m_sApplicationName; - ATL::CAtlStringW m_sParameters; - ATL::CAtlStringW m_sWorkingDirectory; - ATL::CAtlStringW m_sAuthor; - ATL::CAtlStringW m_sComment; - DWORD m_dwFlags; - DWORD m_dwPriority; - ATL::CAtlStringW m_sAccountName; - ATL::CAtlStringW m_sPassword; - WORD m_wIdleMinutes; - WORD m_wDeadlineMinutes; - DWORD m_dwMaxRuntimeMS; - - ATL::CAtlList m_lTriggers; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpTaskDelete -//////////////////////////////////////////////////////////////////////////// - -class COpTaskDelete : public COpTypeSingleString -{ -public: - COpTaskDelete(LPCWSTR pszTaskName = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpTaskEnable -//////////////////////////////////////////////////////////////////////////// - -class COpTaskEnable : public COpTypeSingleString -{ -public: - COpTaskEnable(LPCWSTR pszTaskName = L"", BOOL bEnable = TRUE, int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpTaskEnable &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpTaskEnable &op); - -protected: - BOOL m_bEnable; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpTaskCopy -//////////////////////////////////////////////////////////////////////////// - -class COpTaskCopy : public COpTypeSrcDstString -{ -public: - COpTaskCopy(LPCWSTR pszTaskSrc = L"", LPCWSTR pszTaskDst = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpCertStore -//////////////////////////////////////////////////////////////////////////// - -class COpCertStore : public COpTypeSingleString -{ -public: - COpCertStore(LPCWSTR pszStore = L"", DWORD dwEncodingType = 0, DWORD dwFlags = 0, int iTicks = 0); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpCertStore &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpCertStore &op); - -protected: - DWORD m_dwEncodingType; - DWORD m_dwFlags; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpCert -//////////////////////////////////////////////////////////////////////////// - -class COpCert : public COpCertStore -{ -public: - COpCert(LPCVOID lpCert = NULL, SIZE_T nSize = 0, LPCWSTR pszStore = L"", DWORD dwEncodingType = 0, DWORD dwFlags = 0, int iTicks = 0); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpCert &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpCert &op); - -protected: - ATL::CAtlArray m_binCert; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpCertInstall -//////////////////////////////////////////////////////////////////////////// - -class COpCertInstall : public COpCert -{ -public: - COpCertInstall(LPCVOID lpCert = NULL, SIZE_T nSize = 0, LPCWSTR pszStore = L"", DWORD dwEncodingType = 0, DWORD dwFlags = 0, int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpCertRemove -//////////////////////////////////////////////////////////////////////////// - -class COpCertRemove : public COpCert -{ -public: - COpCertRemove(LPCVOID lpCert = NULL, SIZE_T nSize = 0, LPCWSTR pszStore = L"", DWORD dwEncodingType = 0, DWORD dwFlags = 0, int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpSvcSetStart -//////////////////////////////////////////////////////////////////////////// - -class COpSvcSetStart : public COpTypeSingleString -{ -public: - COpSvcSetStart(LPCWSTR pszService = L"", DWORD dwStartType = SERVICE_DEMAND_START, int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpSvcSetStart &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpSvcSetStart &op); - -protected: - DWORD m_dwStartType; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpSvcControl -//////////////////////////////////////////////////////////////////////////// - -class COpSvcControl : public COpTypeSingleString -{ -public: - COpSvcControl(LPCWSTR pszService = L"", BOOL bWait = FALSE, int iTicks = 0); - - static DWORD WaitForState(CSession *pSession, SC_HANDLE hService, DWORD dwPendingState, DWORD dwFinalState); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpSvcControl &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpSvcControl &op); - -protected: - BOOL m_bWait; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpSvcStart -//////////////////////////////////////////////////////////////////////////// - -class COpSvcStart : public COpSvcControl -{ -public: - COpSvcStart(LPCWSTR pszService = L"", BOOL bWait = FALSE, int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpSvcStop -//////////////////////////////////////////////////////////////////////////// - -class COpSvcStop : public COpSvcControl -{ -public: - COpSvcStop(LPCWSTR pszService = L"", BOOL bWait = FALSE, int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpWLANProfile -//////////////////////////////////////////////////////////////////////////// - -class COpWLANProfile : public COpTypeSingleString -{ -public: - COpWLANProfile(const GUID &guidInterface = GUID_NULL, LPCWSTR pszProfileName = L"", int iTicks = 0); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpWLANProfile &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpWLANProfile &op); - -protected: - GUID m_guidInterface; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpWLANProfileDelete -//////////////////////////////////////////////////////////////////////////// - -class COpWLANProfileDelete : public COpWLANProfile -{ -public: - COpWLANProfileDelete(const GUID &guidInterface = GUID_NULL, LPCWSTR pszProfileName = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpWLANProfileSet -//////////////////////////////////////////////////////////////////////////// - -class COpWLANProfileSet : public COpWLANProfile -{ -public: - COpWLANProfileSet(const GUID &guidInterface = GUID_NULL, DWORD dwFlags = 0, LPCWSTR pszProfileName = L"", LPCWSTR pszProfileXML = L"", int iTicks = 0); - virtual HRESULT Execute(CSession *pSession); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpWLANProfileSet &op); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpWLANProfileSet &op); - -protected: - DWORD m_dwFlags; - ATL::CAtlStringW m_sProfileXML; -}; - - -//////////////////////////////////////////////////////////////////////////// -// COpList -//////////////////////////////////////////////////////////////////////////// - -class COpList : public COperation, public ATL::CAtlList -{ -public: - COpList(int iTicks = 0); - - void Free(); - HRESULT LoadFromFile(LPCTSTR pszFileName); - HRESULT SaveToFile(LPCTSTR pszFileName) const; - - virtual HRESULT Execute(CSession *pSession); - - friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpList &list); - friend inline HRESULT operator >>(ATL::CAtlFile &f, COpList &list); - -protected: - enum OPERATION { - OP_ROLLBACK_ENABLE = 1, - OP_FILE_DELETE, - OP_FILE_MOVE, - OP_REG_KEY_CREATE, - OP_REG_KEY_COPY, - OP_REG_KEY_DELETE, - OP_REG_VALUE_CREATE, - OP_REG_VALUE_COPY, - OP_REG_VALUE_DELETE, - OP_TASK_CREATE, - OP_TASK_DELETE, - OP_TASK_ENABLE, - OP_TASK_COPY, - OP_CERT_INSTALL, - OP_CERT_REMOVE, - OP_SVC_SET_START, - OP_SVC_START, - OP_SVC_STOP, - OP_WLAN_PROFILE_DELETE, - OP_WLAN_PROFILE_SET, - OP_SUBLIST - }; - -protected: - template inline static HRESULT Save(ATL::CAtlFile &f, const COperation *p); - template inline HRESULT LoadAndAddTail(ATL::CAtlFile &f); -}; - - -//////////////////////////////////////////////////////////////////////////// -// CSession -//////////////////////////////////////////////////////////////////////////// - -class CSession -{ -public: - CSession(); - virtual ~CSession(); - - MSIHANDLE m_hInstall; // Installer handle - BOOL m_bContinueOnError; // Continue execution on operation error? - BOOL m_bRollbackEnabled; // Is rollback enabled? - COpList m_olRollback; // Rollback operation list - COpList m_olCommit; // Commit operation list -}; - - -//////////////////////////////////////////////////////////////////////////// -// Helper functions -//////////////////////////////////////////////////////////////////////////// - -UINT SaveSequence(MSIHANDLE hInstall, LPCTSTR szActionExecute, LPCTSTR szActionCommit, LPCTSTR szActionRollback, const COpList &olExecute); -UINT ExecuteSequence(MSIHANDLE hInstall); - -} // namespace MSICA - - -//////////////////////////////////////////////////////////////////// -// Local includes -//////////////////////////////////////////////////////////////////// - -#include "../../../lib/atlex/include/atlex/atlmsi.h" -#include -#include -#include -#include - - -//////////////////////////////////////////////////////////////////// -// Inline helper functions -//////////////////////////////////////////////////////////////////// - -inline UINT MsiRecordFormatStringA(MSIHANDLE hInstall, MSIHANDLE hRecord, unsigned int iField, ATL::CAtlStringA &sValue) -{ - UINT uiResult; - PMSIHANDLE hRecordEx; - - // Read string to format. - uiResult = ::MsiRecordGetStringA(hRecord, iField, sValue); - if (uiResult != NO_ERROR) return uiResult; - - // If the string is empty, there's nothing left to do. - if (sValue.IsEmpty()) return NO_ERROR; - - // Create a record. - hRecordEx = ::MsiCreateRecord(1); - if (!hRecordEx) return ERROR_INVALID_HANDLE; - - // Populate record with data. - uiResult = ::MsiRecordSetStringA(hRecordEx, 0, sValue); - if (uiResult != NO_ERROR) return uiResult; - - // Do the formatting. - return ::MsiFormatRecordA(hInstall, hRecordEx, sValue); -} - - -inline UINT MsiRecordFormatStringW(MSIHANDLE hInstall, MSIHANDLE hRecord, unsigned int iField, ATL::CAtlStringW &sValue) -{ - UINT uiResult; - PMSIHANDLE hRecordEx; - - // Read string to format. - uiResult = ::MsiRecordGetStringW(hRecord, iField, sValue); - if (uiResult != NO_ERROR) return uiResult; - - // If the string is empty, there's nothing left to do. - if (sValue.IsEmpty()) return NO_ERROR; - - // Create a record. - hRecordEx = ::MsiCreateRecord(1); - if (!hRecordEx) return ERROR_INVALID_HANDLE; - - // Populate record with data. - uiResult = ::MsiRecordSetStringW(hRecordEx, 0, sValue); - if (uiResult != NO_ERROR) return uiResult; - - // Do the formatting. - return ::MsiFormatRecordW(hInstall, hRecordEx, sValue); -} - -#ifdef UNICODE -#define MsiRecordFormatString MsiRecordFormatStringW -#else -#define MsiRecordFormatString MsiRecordFormatStringA -#endif // !UNICODE - - -namespace MSICA { - -//////////////////////////////////////////////////////////////////////////// -// Inline operators -//////////////////////////////////////////////////////////////////////////// - -inline HRESULT operator <<(ATL::CAtlFile &f, int i) -{ - HRESULT hr; - DWORD dwWritten; - - hr = f.Write(&i, sizeof(int), &dwWritten); - return SUCCEEDED(hr) ? dwWritten == sizeof(int) ? hr : E_FAIL : hr; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, int &i) -{ - HRESULT hr; - DWORD dwRead; - - hr = f.Read(&i, sizeof(int), dwRead); - return SUCCEEDED(hr) ? dwRead == sizeof(int) ? hr : E_FAIL : hr; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, DWORDLONG i) -{ - HRESULT hr; - DWORD dwWritten; - - hr = f.Write(&i, sizeof(DWORDLONG), &dwWritten); - return SUCCEEDED(hr) ? dwWritten == sizeof(DWORDLONG) ? hr : E_FAIL : hr; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, DWORDLONG &i) -{ - HRESULT hr; - DWORD dwRead; - - hr = f.Read(&i, sizeof(DWORDLONG), dwRead); - return SUCCEEDED(hr) ? dwRead == sizeof(DWORDLONG) ? hr : E_FAIL : hr; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const GUID &guid) -{ - HRESULT hr; - DWORD dwWritten; - - hr = f.Write(&guid, sizeof(GUID), &dwWritten); - return SUCCEEDED(hr) ? dwWritten == sizeof(GUID) ? hr : E_FAIL : hr; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, GUID &guid) -{ - HRESULT hr; - DWORD dwRead; - - hr = f.Read(&guid, sizeof(GUID), dwRead); - return SUCCEEDED(hr) ? dwRead == sizeof(GUID) ? hr : E_FAIL : hr; -} - - -template -inline HRESULT operator <<(ATL::CAtlFile &f, const ATL::CAtlArray &a) -{ - HRESULT hr; - DWORD dwCount = (DWORD)a.GetCount(), dwWritten; - - // Write element count. - hr = f.Write(&dwCount, sizeof(DWORD), &dwWritten); - if (FAILED(hr)) return hr; - if (dwWritten < sizeof(DWORD)) return E_FAIL; - - // Write data. - hr = f.Write(a.GetData(), sizeof(E) * dwCount, &dwWritten); - return SUCCEEDED(hr) ? dwWritten == sizeof(E) * dwCount ? hr : E_FAIL : hr; -} - - -template -inline HRESULT operator >>(ATL::CAtlFile &f, ATL::CAtlArray &a) -{ - HRESULT hr; - DWORD dwCount, dwRead; - - // Read element count as 32-bit integer. - hr = f.Read(&dwCount, sizeof(DWORD), dwRead); - if (FAILED(hr)) return hr; - if (dwRead < sizeof(DWORD)) return E_FAIL; - - // Allocate the buffer. - if (!a.SetCount(dwCount)) return E_OUTOFMEMORY; - - // Read data. - hr = f.Read(a.GetData(), sizeof(E) * dwCount, dwRead); - if (SUCCEEDED(hr)) a.SetCount(dwRead / sizeof(E)); - return hr; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const ATL::CAtlStringA &str) -{ - HRESULT hr; - int iLength = str.GetLength(); - DWORD dwWritten; - - // Write string length (in characters) as 32-bit integer. - hr = f.Write(&iLength, sizeof(int), &dwWritten); - if (FAILED(hr)) return hr; - if (dwWritten < sizeof(int)) return E_FAIL; - - // Write string data (without terminator). - hr = f.Write((LPCSTR)str, sizeof(CHAR) * iLength, &dwWritten); - return SUCCEEDED(hr) ? dwWritten == sizeof(CHAR) * iLength ? hr : E_FAIL : hr; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, ATL::CAtlStringA &str) -{ - HRESULT hr; - int iLength; - LPSTR buf; - DWORD dwRead; - - // Read string length (in characters) as 32-bit integer. - hr = f.Read(&iLength, sizeof(int), dwRead); - if (FAILED(hr)) return hr; - if (dwRead < sizeof(int)) return E_FAIL; - - // Allocate the buffer. - buf = str.GetBuffer(iLength); - if (!buf) return E_OUTOFMEMORY; - - // Read string data (without terminator). - hr = f.Read(buf, sizeof(CHAR) * iLength, dwRead); - str.ReleaseBuffer(SUCCEEDED(hr) ? dwRead / sizeof(CHAR) : 0); - return hr; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const ATL::CAtlStringW &str) -{ - HRESULT hr; - int iLength = str.GetLength(); - DWORD dwWritten; - - // Write string length (in characters) as 32-bit integer. - hr = f.Write(&iLength, sizeof(int), &dwWritten); - if (FAILED(hr)) return hr; - if (dwWritten < sizeof(int)) return E_FAIL; - - // Write string data (without terminator). - hr = f.Write((LPCWSTR)str, sizeof(WCHAR) * iLength, &dwWritten); - return SUCCEEDED(hr) ? dwWritten == sizeof(WCHAR) * iLength ? hr : E_FAIL : hr; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, ATL::CAtlStringW &str) -{ - HRESULT hr; - int iLength; - LPWSTR buf; - DWORD dwRead; - - // Read string length (in characters) as 32-bit integer. - hr = f.Read(&iLength, sizeof(int), dwRead); - if (FAILED(hr)) return hr; - if (dwRead < sizeof(int)) return E_FAIL; - - // Allocate the buffer. - buf = str.GetBuffer(iLength); - if (!buf) return E_OUTOFMEMORY; - - // Read string data (without terminator). - hr = f.Read(buf, sizeof(WCHAR) * iLength, dwRead); - str.ReleaseBuffer(SUCCEEDED(hr) ? dwRead / sizeof(WCHAR) : 0); - return hr; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const TASK_TRIGGER &ttData) -{ - HRESULT hr; - DWORD dwWritten; - - hr = f.Write(&ttData, sizeof(TASK_TRIGGER), &dwWritten); - return SUCCEEDED(hr) ? dwWritten == sizeof(TASK_TRIGGER) ? hr : E_FAIL : hr; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, TASK_TRIGGER &ttData) -{ - HRESULT hr; - DWORD dwRead; - - hr = f.Read(&ttData, sizeof(TASK_TRIGGER), dwRead); - return SUCCEEDED(hr) ? dwRead == sizeof(TASK_TRIGGER) ? hr : E_FAIL : hr; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COperation &op) -{ - return f << op.m_iTicks; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COperation &op) -{ - return f >> op.m_iTicks; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpTypeSingleString &op) -{ - HRESULT hr; - - hr = f << (const COperation &)op; if (FAILED(hr)) return hr; - hr = f << op.m_sValue; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeSingleString &op) -{ - HRESULT hr; - - hr = f >> (COperation &)op; if (FAILED(hr)) return hr; - hr = f >> op.m_sValue; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpTypeSrcDstString &op) -{ - HRESULT hr; - - hr = f << (const COperation &)op; if (FAILED(hr)) return hr; - hr = f << op.m_sValue1; if (FAILED(hr)) return hr; - hr = f << op.m_sValue2; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeSrcDstString &op) -{ - HRESULT hr; - - hr = f >> (COperation &)op; if (FAILED(hr)) return hr; - hr = f >> op.m_sValue1; if (FAILED(hr)) return hr; - hr = f >> op.m_sValue2; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpTypeBoolean &op) -{ - HRESULT hr; - - hr = f << (const COperation &)op; if (FAILED(hr)) return hr; - hr = f << (int)(op.m_bValue); if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeBoolean &op) -{ - HRESULT hr; - int iValue; - - hr = f >> (COperation &)op; if (FAILED(hr)) return hr; - hr = f >> iValue; if (FAILED(hr)) return hr; op.m_bValue = iValue ? TRUE : FALSE; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegKeySingle &op) -{ - HRESULT hr; - - hr = f << (const COpTypeSingleString &)op; if (FAILED(hr)) return hr; - hr = f << (int)(op.m_hKeyRoot); if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpRegKeySingle &op) -{ - HRESULT hr; - int iValue; - - hr = f >> (COpTypeSingleString &)op; if (FAILED(hr)) return hr; - hr = f >> iValue; if (FAILED(hr)) return hr; op.m_hKeyRoot = (HKEY)iValue; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegKeySrcDst &op) -{ - HRESULT hr; - - hr = f << (const COpTypeSrcDstString &)op; if (FAILED(hr)) return hr; - hr = f << (int)(op.m_hKeyRoot); if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpRegKeySrcDst &op) -{ - HRESULT hr; - int iValue; - - hr = f >> (COpTypeSrcDstString &)op; if (FAILED(hr)) return hr; - hr = f >> iValue; if (FAILED(hr)) return hr; op.m_hKeyRoot = (HKEY)iValue; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegValueSingle &op) -{ - HRESULT hr; - - hr = f << (const COpRegKeySingle &)op; if (FAILED(hr)) return hr; - hr = f << op.m_sValueName; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpRegValueSingle &op) -{ - HRESULT hr; - - hr = f >> (COpRegKeySingle &)op; if (FAILED(hr)) return hr; - hr = f >> op.m_sValueName; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegValueSrcDst &op) -{ - HRESULT hr; - - hr = f << (const COpRegKeySingle &)op; if (FAILED(hr)) return hr; - hr = f << op.m_sValueName1; if (FAILED(hr)) return hr; - hr = f << op.m_sValueName2; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpRegValueSrcDst &op) -{ - HRESULT hr; - - hr = f >> (COpRegKeySingle &)op; if (FAILED(hr)) return hr; - hr = f >> op.m_sValueName1; if (FAILED(hr)) return hr; - hr = f >> op.m_sValueName2; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegValueCreate &op) -{ - HRESULT hr; - - hr = f << (const COpRegValueSingle &)op; if (FAILED(hr)) return hr; - hr = f << (int)(op.m_dwType); if (FAILED(hr)) return hr; - switch (op.m_dwType) { - case REG_SZ: - case REG_EXPAND_SZ: - case REG_LINK: hr = f << op.m_sData; if (FAILED(hr)) return hr; break; - case REG_BINARY: hr = f << op.m_binData; if (FAILED(hr)) return hr; break; - case REG_DWORD_LITTLE_ENDIAN: - case REG_DWORD_BIG_ENDIAN: hr = f << (int)(op.m_dwData); if (FAILED(hr)) return hr; break; - case REG_MULTI_SZ: hr = f << op.m_szData; if (FAILED(hr)) return hr; break; - case REG_QWORD_LITTLE_ENDIAN: hr = f << op.m_qwData; if (FAILED(hr)) return hr; break; - default: return E_UNEXPECTED; - } - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpRegValueCreate &op) -{ - HRESULT hr; - - hr = f >> (COpRegValueSingle &)op; if (FAILED(hr)) return hr; - hr = f >> (int&)(op.m_dwType); if (FAILED(hr)) return hr; - switch (op.m_dwType) { - case REG_SZ: - case REG_EXPAND_SZ: - case REG_LINK: hr = f >> op.m_sData; if (FAILED(hr)) return hr; break; - case REG_BINARY: hr = f >> op.m_binData; if (FAILED(hr)) return hr; break; - case REG_DWORD_LITTLE_ENDIAN: - case REG_DWORD_BIG_ENDIAN: hr = f >> (int&)(op.m_dwData); if (FAILED(hr)) return hr; break; - case REG_MULTI_SZ: hr = f >> op.m_szData; if (FAILED(hr)) return hr; break; - case REG_QWORD_LITTLE_ENDIAN: hr = f >> op.m_qwData; if (FAILED(hr)) return hr; break; - default: return E_UNEXPECTED; - } - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpTaskCreate &op) -{ - HRESULT hr; - POSITION pos; - - hr = f << (const COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f << op.m_sApplicationName; if (FAILED(hr)) return hr; - hr = f << op.m_sParameters; if (FAILED(hr)) return hr; - hr = f << op.m_sWorkingDirectory; if (FAILED(hr)) return hr; - hr = f << op.m_sAuthor; if (FAILED(hr)) return hr; - hr = f << op.m_sComment; if (FAILED(hr)) return hr; - hr = f << (int)(op.m_dwFlags); if (FAILED(hr)) return hr; - hr = f << (int)(op.m_dwPriority); if (FAILED(hr)) return hr; - hr = f << op.m_sAccountName; if (FAILED(hr)) return hr; - hr = f << op.m_sPassword; if (FAILED(hr)) return hr; - hr = f << (int)MAKELONG(op.m_wDeadlineMinutes, op.m_wIdleMinutes); if (FAILED(hr)) return hr; - hr = f << (int)(op.m_dwMaxRuntimeMS); if (FAILED(hr)) return hr; - hr = f << (int)(op.m_lTriggers.GetCount()); if (FAILED(hr)) return hr; - for (pos = op.m_lTriggers.GetHeadPosition(); pos;) { - hr = f << op.m_lTriggers.GetNext(pos); - if (FAILED(hr)) return hr; - } - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpTaskCreate &op) -{ - HRESULT hr; - DWORD dwValue; - - hr = f >> (COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f >> op.m_sApplicationName; if (FAILED(hr)) return hr; - hr = f >> op.m_sParameters; if (FAILED(hr)) return hr; - hr = f >> op.m_sWorkingDirectory; if (FAILED(hr)) return hr; - hr = f >> op.m_sAuthor; if (FAILED(hr)) return hr; - hr = f >> op.m_sComment; if (FAILED(hr)) return hr; - hr = f >> (int&)(op.m_dwFlags); if (FAILED(hr)) return hr; - hr = f >> (int&)(op.m_dwPriority); if (FAILED(hr)) return hr; - hr = f >> op.m_sAccountName; if (FAILED(hr)) return hr; - hr = f >> op.m_sPassword; if (FAILED(hr)) return hr; - hr = f >> (int&)dwValue; if (FAILED(hr)) return hr; op.m_wIdleMinutes = HIWORD(dwValue); op.m_wDeadlineMinutes = LOWORD(dwValue); - hr = f >> (int&)(op.m_dwMaxRuntimeMS); if (FAILED(hr)) return hr; - hr = f >> (int&)dwValue; if (FAILED(hr)) return hr; - while (dwValue--) { - TASK_TRIGGER ttData; - hr = f >> ttData; - if (FAILED(hr)) return hr; - op.m_lTriggers.AddTail(ttData); - } - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpTaskEnable &op) -{ - HRESULT hr; - - hr = f << (const COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f << (int)(op.m_bEnable); if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpTaskEnable &op) -{ - HRESULT hr; - int iTemp; - - hr = f >> (COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f >> iTemp; if (FAILED(hr)) return hr; op.m_bEnable = iTemp ? TRUE : FALSE; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpCertStore &op) -{ - HRESULT hr; - - hr = f << (const COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f << (int)(op.m_dwEncodingType); if (FAILED(hr)) return hr; - hr = f << (int)(op.m_dwFlags); if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpCertStore &op) -{ - HRESULT hr; - - hr = f >> (COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f >> (int&)(op.m_dwEncodingType); if (FAILED(hr)) return hr; - hr = f >> (int&)(op.m_dwFlags); if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpCert &op) -{ - HRESULT hr; - - hr = f << (const COpCertStore&)op; if (FAILED(hr)) return hr; - hr = f << op.m_binCert; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpCert &op) -{ - HRESULT hr; - - hr = f >> (COpCertStore&)op; if (FAILED(hr)) return hr; - hr = f >> op.m_binCert; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpSvcSetStart &op) -{ - HRESULT hr; - - hr = f << (const COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f << (int)(op.m_dwStartType); if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpSvcSetStart &op) -{ - HRESULT hr; - - hr = f >> (COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f >> (int&)(op.m_dwStartType); if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpSvcControl &op) -{ - HRESULT hr; - - hr = f << (const COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f << (int)(op.m_bWait); if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpSvcControl &op) -{ - HRESULT hr; - int iValue; - - hr = f >> (COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f >> iValue; if (FAILED(hr)) return hr; op.m_bWait = iValue ? TRUE : FALSE; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpWLANProfile &op) -{ - HRESULT hr; - - hr = f << (const COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f << op.m_guidInterface; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpWLANProfile &op) -{ - HRESULT hr; - - hr = f >> (COpTypeSingleString&)op; if (FAILED(hr)) return hr; - hr = f >> op.m_guidInterface; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpWLANProfileSet &op) -{ - HRESULT hr; - - hr = f << (const COpWLANProfile&)op; if (FAILED(hr)) return hr; - hr = f << (int)(op.m_dwFlags); if (FAILED(hr)) return hr; - hr = f << op.m_sProfileXML; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpWLANProfileSet &op) -{ - HRESULT hr; - - hr = f >> (COpWLANProfile&)op; if (FAILED(hr)) return hr; - hr = f >> (int&)(op.m_dwFlags); if (FAILED(hr)) return hr; - hr = f >> op.m_sProfileXML; if (FAILED(hr)) return hr; - - return S_OK; -} - - -inline HRESULT operator <<(ATL::CAtlFile &f, const COpList &list) -{ - POSITION pos; - HRESULT hr; - - hr = f << (const COperation &)list; - if (FAILED(hr)) return hr; - - hr = f << (int)(list.GetCount()); - if (FAILED(hr)) return hr; - - for (pos = list.GetHeadPosition(); pos;) { - const COperation *pOp = list.GetNext(pos); - if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); - else { - // Unsupported type of operation. - hr = E_UNEXPECTED; - } - - if (FAILED(hr)) return hr; - } - - return S_OK; -} - - -inline HRESULT operator >>(ATL::CAtlFile &f, COpList &list) -{ - HRESULT hr; - int iCount; - - hr = f >> (COperation &)list; - if (FAILED(hr)) return hr; - - hr = f >> iCount; - if (FAILED(hr)) return hr; - - while (iCount--) { - int iTemp; - - hr = f >> iTemp; - if (FAILED(hr)) return hr; - - switch ((COpList::OPERATION)iTemp) { - case COpList::OP_ROLLBACK_ENABLE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_FILE_DELETE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_FILE_MOVE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_KEY_CREATE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_KEY_COPY: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_KEY_DELETE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_VALUE_CREATE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_VALUE_COPY: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_VALUE_DELETE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_TASK_CREATE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_TASK_DELETE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_TASK_ENABLE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_TASK_COPY: hr = list.LoadAndAddTail(f); break; - case COpList::OP_CERT_INSTALL: hr = list.LoadAndAddTail(f); break; - case COpList::OP_CERT_REMOVE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_SVC_SET_START: hr = list.LoadAndAddTail(f); break; - case COpList::OP_SVC_START: hr = list.LoadAndAddTail(f); break; - case COpList::OP_SVC_STOP: hr = list.LoadAndAddTail(f); break; - case COpList::OP_WLAN_PROFILE_DELETE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_WLAN_PROFILE_SET: hr = list.LoadAndAddTail(f); break; - case COpList::OP_SUBLIST: hr = list.LoadAndAddTail(f); break; - default: - // Unsupported type of operation. - hr = E_UNEXPECTED; - } - - if (FAILED(hr)) return hr; - } - - return S_OK; -} - - -//////////////////////////////////////////////////////////////////// -// Inline Functions -//////////////////////////////////////////////////////////////////// - - -inline BOOL IsWow64Process() -{ -#ifndef _WIN64 - // Find IsWow64Process() address in KERNEL32.DLL. - BOOL (WINAPI *_IsWow64Process)(__in HANDLE hProcess, __out PBOOL Wow64Process) = (BOOL(WINAPI*)(__in HANDLE, __out PBOOL))::GetProcAddress(::GetModuleHandle(_T("KERNEL32.DLL")), "IsWow64Process"); - - // See if our 32-bit process is running in 64-bit environment. - if (_IsWow64Process) { - BOOL bResult; - - // See, what IsWow64Process() says about current process. - if (_IsWow64Process(::GetCurrentProcess(), &bResult)) { - // Return result. - return bResult; - } else { - // IsWow64Process() returned an error. Assume, the process is not WOW64. - return FALSE; - } - } else { - // This KERNEL32.DLL doesn't know IsWow64Process().Definitely not a WOW64 process. - return FALSE; - } -#else - // 64-bit processes are never run as WOW64. - return FALSE; -#endif -} - - -//////////////////////////////////////////////////////////////////////////// -// Inline methods -//////////////////////////////////////////////////////////////////////////// - -template inline static HRESULT COpList::Save(ATL::CAtlFile &f, const COperation *p) -{ - HRESULT hr; - const T *pp = dynamic_cast(p); - if (!pp) return E_UNEXPECTED; - - hr = f << (int)ID; - if (FAILED(hr)) return hr; - - return f << *pp; -} - - -template inline HRESULT COpList::LoadAndAddTail(ATL::CAtlFile &f) -{ - HRESULT hr; - - // Create element. - T *p = new T(); - if (!p) return E_OUTOFMEMORY; - - // Load element from file. - hr = f >> *p; - if (FAILED(hr)) { - delete p; - return hr; - } - - // Add element. - AddTail(p); - return S_OK; -} - -} // namespace MSICA - -#endif // __MSICALib_H__ diff --git a/MSICALib/MSICALib.vcxproj b/MSICALib/MSICALib.vcxproj deleted file mode 100644 index 77df5ae..0000000 --- a/MSICALib/MSICALib.vcxproj +++ /dev/null @@ -1,102 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - - {8552EE55-177E-4F51-B51B-BAF7D6462CDE} - Win32Proj - MSICALib - MSICALib - - - - StaticLibrary - Unicode - Static - - - StaticLibrary - Unicode - Static - - - StaticLibrary - Unicode - Static - - - StaticLibrary - Unicode - Static - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/MSICALib/MSICALib.vcxproj.filters b/MSICALib/MSICALib.vcxproj.filters deleted file mode 100644 index 6b2fabb..0000000 --- a/MSICALib/MSICALib.vcxproj.filters +++ /dev/null @@ -1,56 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/MSICALib/OpCert.cpp b/MSICALib/OpCert.cpp deleted file mode 100644 index c2cc6d4..0000000 --- a/MSICALib/OpCert.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#include "stdafx.h" - -#pragma comment(lib, "crypt32.lib") - - -namespace MSICA { - -//////////////////////////////////////////////////////////////////////////// -// COpCertStore -//////////////////////////////////////////////////////////////////////////// - -COpCertStore::COpCertStore(LPCWSTR pszStore, DWORD dwEncodingType, DWORD dwFlags, int iTicks) : - COpTypeSingleString(pszStore, iTicks), - m_dwEncodingType(dwEncodingType), - m_dwFlags(dwFlags) -{ -} - - -//////////////////////////////////////////////////////////////////////////// -// COpCert -//////////////////////////////////////////////////////////////////////////// - -COpCert::COpCert(LPCVOID lpCert, SIZE_T nSize, LPCWSTR pszStore, DWORD dwEncodingType, DWORD dwFlags, int iTicks) : - COpCertStore(pszStore, dwEncodingType, dwFlags, iTicks) -{ - m_binCert.SetCount(nSize); - memcpy(m_binCert.GetData(), lpCert, nSize); -} - - -//////////////////////////////////////////////////////////////////////////// -// COpCertInstall -//////////////////////////////////////////////////////////////////////////// - -COpCertInstall::COpCertInstall(LPCVOID lpCert, SIZE_T nSize, LPCWSTR pszStore, DWORD dwEncodingType, DWORD dwFlags, int iTicks) : COpCert(lpCert, nSize, pszStore, dwEncodingType, dwFlags, iTicks) -{ -} - - -HRESULT COpCertInstall::Execute(CSession *pSession) -{ - DWORD dwError; - HCERTSTORE hCertStore; - - // Open certificate store. - hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM_W, m_dwEncodingType, NULL, m_dwFlags, m_sValue); - if (hCertStore) { - // Create certificate context. - PCCERT_CONTEXT pCertContext = ::CertCreateCertificateContext(m_dwEncodingType, m_binCert.GetData(), (DWORD)(m_binCert.GetCount())); - if (pCertContext) { - PMSIHANDLE hRecordMsg = ::MsiCreateRecord(1); - ATL::CAtlStringW sCertName; - - // Display our custom message in the progress bar. - ::CertGetNameStringW(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, sCertName); - ::MsiRecordSetStringW(hRecordMsg, 1, sCertName); - if (MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ACTIONDATA, hRecordMsg) == IDCANCEL) - return AtlHresultFromWin32(ERROR_INSTALL_USEREXIT); - - // Add certificate to certificate store. - if (::CertAddCertificateContextToStore(hCertStore, pCertContext, CERT_STORE_ADD_NEW, NULL)) { - if (pSession->m_bRollbackEnabled) { - // Order rollback action to delete the certificate. - pSession->m_olRollback.AddHead(new COpCertRemove(m_binCert.GetData(), m_binCert.GetCount(), m_sValue, m_dwEncodingType, m_dwFlags)); - } - dwError = NO_ERROR; - } else { - dwError = ::GetLastError(); - if (dwError == CRYPT_E_EXISTS) { - // Certificate store already contains given certificate. Nothing to install then. - dwError = NO_ERROR; - } - } - ::CertFreeCertificateContext(pCertContext); - } else - dwError = ::GetLastError(); - ::CertCloseStore(hCertStore, 0); - } else - dwError = ::GetLastError(); - - if (dwError == NO_ERROR) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_CERT_INSTALL); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(dwError); - } -} - - -//////////////////////////////////////////////////////////////////////////// -// COpCertRemove -//////////////////////////////////////////////////////////////////////////// - -COpCertRemove::COpCertRemove(LPCVOID lpCert, SIZE_T nSize, LPCWSTR pszStore, DWORD dwEncodingType, DWORD dwFlags, int iTicks) : COpCert(lpCert, nSize, pszStore, dwEncodingType, dwFlags, iTicks) -{ -} - - -HRESULT COpCertRemove::Execute(CSession *pSession) -{ - DWORD dwError; - HCERTSTORE hCertStore; - - // Open certificate store. - hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM_W, m_dwEncodingType, NULL, m_dwFlags, m_sValue); - if (hCertStore) { - // Create certificate context. - PCCERT_CONTEXT pCertContext = ::CertCreateCertificateContext(m_dwEncodingType, m_binCert.GetData(), (DWORD)(m_binCert.GetCount())); - if (pCertContext) { - PMSIHANDLE hRecordMsg = ::MsiCreateRecord(1); - ATL::CAtlStringW sCertName; - PCCERT_CONTEXT pCertContextExisting; - - // Display our custom message in the progress bar. - ::CertGetNameStringW(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, sCertName); - ::MsiRecordSetStringW(hRecordMsg, 1, sCertName); - if (MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ACTIONDATA, hRecordMsg) == IDCANCEL) - return AtlHresultFromWin32(ERROR_INSTALL_USEREXIT); - - pCertContextExisting = ::CertFindCertificateInStore(hCertStore, m_dwEncodingType, 0, CERT_FIND_EXISTING, pCertContext, NULL); - if (pCertContextExisting) { - // Delete certificate from certificate store. - if (::CertDeleteCertificateFromStore(pCertContextExisting)) { - if (pSession->m_bRollbackEnabled) { - // Order rollback action to reinstall the certificate. - pSession->m_olRollback.AddHead(new COpCertInstall(m_binCert.GetData(), m_binCert.GetCount(), m_sValue, m_dwEncodingType, m_dwFlags)); - } - dwError = NO_ERROR; - } else { - dwError = ::GetLastError(); - ::CertFreeCertificateContext(pCertContextExisting); - } - } else { - // We haven't found the certificate. Nothing to delete then. - dwError = NO_ERROR; - } - ::CertFreeCertificateContext(pCertContext); - } else - dwError = ::GetLastError(); - ::CertCloseStore(hCertStore, 0); - } else - dwError = ::GetLastError(); - - if (dwError == NO_ERROR) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_CERT_REMOVE); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(dwError); - } -} - -} // namespace MSICA diff --git a/MSICALib/OpFile.cpp b/MSICALib/OpFile.cpp deleted file mode 100644 index 4a4f4ce..0000000 --- a/MSICALib/OpFile.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#include "stdafx.h" - - -namespace MSICA { - -//////////////////////////////////////////////////////////////////////////// -// COpFileDelete -//////////////////////////////////////////////////////////////////////////// - -COpFileDelete::COpFileDelete(LPCWSTR pszFileName, int iTicks) : - COpTypeSingleString(pszFileName, iTicks) -{ -} - - -HRESULT COpFileDelete::Execute(CSession *pSession) -{ - DWORD dwError; - - if (pSession->m_bRollbackEnabled) { - ATL::CAtlStringW sBackupName; - UINT uiCount = 0; - - do { - // Rename the file to make a backup. - sBackupName.Format(L"%ls (orig %u)", (LPCWSTR)m_sValue, ++uiCount); - dwError = ::MoveFileW(m_sValue, sBackupName) ? NO_ERROR : ::GetLastError(); - } while (dwError == ERROR_ALREADY_EXISTS); - if (dwError == NO_ERROR) { - // Order rollback action to restore from backup copy. - pSession->m_olRollback.AddHead(new COpFileMove(sBackupName, m_sValue)); - - // Order commit action to delete backup copy. - pSession->m_olCommit.AddTail(new COpFileDelete(sBackupName)); - } - } else { - // Delete the file. - dwError = ::DeleteFileW(m_sValue) ? NO_ERROR : ::GetLastError(); - } - - if (dwError == NO_ERROR || dwError == ERROR_FILE_NOT_FOUND) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_FILE_DELETE); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(dwError); - } -} - - -//////////////////////////////////////////////////////////////////////////// -// COpFileMove -//////////////////////////////////////////////////////////////////////////// - -COpFileMove::COpFileMove(LPCWSTR pszFileSrc, LPCWSTR pszFileDst, int iTicks) : - COpTypeSrcDstString(pszFileSrc, pszFileDst, iTicks) -{ -} - - -HRESULT COpFileMove::Execute(CSession *pSession) -{ - DWORD dwError; - - // Move the file. - dwError = ::MoveFileW(m_sValue1, m_sValue2) ? NO_ERROR : ::GetLastError(); - if (dwError == NO_ERROR) { - if (pSession->m_bRollbackEnabled) { - // Order rollback action to move it back. - pSession->m_olRollback.AddHead(new COpFileMove(m_sValue2, m_sValue1)); - } - - return S_OK; - } else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_FILE_MOVE); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue1 ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue2 ); - ::MsiRecordSetInteger(hRecordProg, 4, dwError ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(dwError); - } -} - -} // namespace MSICA diff --git a/MSICALib/OpReg.cpp b/MSICALib/OpReg.cpp deleted file mode 100644 index 420a925..0000000 --- a/MSICALib/OpReg.cpp +++ /dev/null @@ -1,743 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#include "stdafx.h" - - -namespace MSICA { - - -//////////////////////////////////////////////////////////////////////////// -// COpRegKeySingle -//////////////////////////////////////////////////////////////////////////// - -COpRegKeySingle::COpRegKeySingle(HKEY hKeyRoot, LPCWSTR pszKeyName, int iTicks) : - m_hKeyRoot(hKeyRoot), - COpTypeSingleString(pszKeyName, iTicks) -{ -} - - -//////////////////////////////////////////////////////////////////////////// -// COpRegKeySrcDst -//////////////////////////////////////////////////////////////////////////// - -COpRegKeySrcDst::COpRegKeySrcDst(HKEY hKeyRoot, LPCWSTR pszKeyNameSrc, LPCWSTR pszKeyNameDst, int iTicks) : - m_hKeyRoot(hKeyRoot), - COpTypeSrcDstString(pszKeyNameSrc, pszKeyNameDst, iTicks) -{ -} - - -//////////////////////////////////////////////////////////////////////////// -// COpRegKeyCreate -//////////////////////////////////////////////////////////////////////////// - -COpRegKeyCreate::COpRegKeyCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, int iTicks) : COpRegKeySingle(hKeyRoot, pszKeyName, iTicks) -{ -} - - -HRESULT COpRegKeyCreate::Execute(CSession *pSession) -{ - LONG lResult; - REGSAM samAdditional = 0; - ATL::CAtlStringW sPartialName; - int iStart = 0; - -#ifndef _WIN64 - if (IsWow64Process()) { - // 32-bit processes run as WOW64 should use 64-bit registry too. - samAdditional |= KEY_WOW64_64KEY; - } -#endif - - for (;;) { - HKEY hKey; - - int iStartNext = m_sValue.Find(L'\\', iStart); - if (iStartNext >= 0) - sPartialName.SetString(m_sValue, iStartNext); - else - sPartialName = m_sValue; - - // Try to open the key, to see if it exists. - lResult = ::RegOpenKeyExW(m_hKeyRoot, sPartialName, 0, KEY_ENUMERATE_SUB_KEYS | samAdditional, &hKey); - if (lResult == ERROR_FILE_NOT_FOUND) { - // The key doesn't exist yet. Create it. - - if (pSession->m_bRollbackEnabled) { - // Order rollback action to delete the key. ::RegCreateEx() might create a key but return failure. - pSession->m_olRollback.AddHead(new COpRegKeyDelete(m_hKeyRoot, sPartialName)); - } - - // Create the key. - lResult = ::RegCreateKeyExW(m_hKeyRoot, sPartialName, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_ENUMERATE_SUB_KEYS | samAdditional, NULL, &hKey, NULL); - if (lResult != NO_ERROR) break; - ::RegCloseKey(hKey); - } else if (lResult == NO_ERROR) { - // This key already exists. Release its handle and continue. - ::RegCloseKey(hKey); - } else - break; - - if (iStartNext < 0) break; - iStart = iStartNext + 1; - } - - if (lResult == NO_ERROR) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_CREATE ); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 4, lResult ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(lResult); - } -} - - -//////////////////////////////////////////////////////////////////////////// -// COpRegKeyCopy -//////////////////////////////////////////////////////////////////////////// - -COpRegKeyCopy::COpRegKeyCopy(HKEY hKeyRoot, LPCWSTR pszKeyNameSrc, LPCWSTR pszKeyNameDst, int iTicks) : COpRegKeySrcDst(hKeyRoot, pszKeyNameSrc, pszKeyNameDst, iTicks) -{ -} - - -HRESULT COpRegKeyCopy::Execute(CSession *pSession) -{ - LONG lResult; - REGSAM samAdditional = 0; - - { - // Delete existing destination key first. - // Since deleting registry key is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it. - // Don't worry, COpRegKeyDelete::Execute() returns S_OK if key doesn't exist. - COpRegKeyDelete opDelete(m_hKeyRoot, m_sValue2); - HRESULT hr = opDelete.Execute(pSession); - if (FAILED(hr)) return hr; - } - -#ifndef _WIN64 - if (IsWow64Process()) { - // 32-bit processes run as WOW64 should use 64-bit registry too. - samAdditional |= KEY_WOW64_64KEY; - } -#endif - - if (pSession->m_bRollbackEnabled) { - // Order rollback action to delete the destination key. - pSession->m_olRollback.AddHead(new COpRegKeyDelete(m_hKeyRoot, m_sValue2)); - } - - // Copy the registry key. - lResult = CopyKeyRecursively(m_hKeyRoot, m_sValue1, m_sValue2, samAdditional); - if (lResult == NO_ERROR) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(5); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_COPY ); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue1 ); - ::MsiRecordSetStringW(hRecordProg, 4, m_sValue2 ); - ::MsiRecordSetInteger(hRecordProg, 5, lResult ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(lResult); - } -} - - -LONG COpRegKeyCopy::CopyKeyRecursively(HKEY hKeyRoot, LPCWSTR pszKeyNameSrc, LPCWSTR pszKeyNameDst, REGSAM samAdditional) -{ - LONG lResult; - HKEY hKeySrc, hKeyDst; - - // Open source key. - lResult = ::RegOpenKeyExW(hKeyRoot, pszKeyNameSrc, 0, READ_CONTROL | KEY_READ | samAdditional, &hKeySrc); - if (lResult != NO_ERROR) return lResult; - - { - DWORD dwSecurityDescriptorSize, dwClassLen = MAX_PATH; - SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES) }; - LPWSTR pszClass = new WCHAR[dwClassLen]; - - // Get source key class length and security descriptor size. - lResult = ::RegQueryInfoKeyW(hKeySrc, pszClass, &dwClassLen, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwSecurityDescriptorSize, NULL); - if (lResult != NO_ERROR) { - delete [] pszClass; - return lResult; - } - pszClass[dwClassLen] = 0; - - // Get source key security descriptor. - sa.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(new BYTE[dwSecurityDescriptorSize]); - lResult = ::RegGetKeySecurity(hKeySrc, DACL_SECURITY_INFORMATION, sa.lpSecurityDescriptor, &dwSecurityDescriptorSize); - if (lResult != NO_ERROR) { - delete [] (LPBYTE)(sa.lpSecurityDescriptor); - delete [] pszClass; - return lResult; - } - - // Create new destination key of the same class and security. - lResult = ::RegCreateKeyExW(hKeyRoot, pszKeyNameDst, 0, pszClass, REG_OPTION_NON_VOLATILE, KEY_WRITE | samAdditional, &sa, &hKeyDst, NULL); - delete [] (LPBYTE)(sa.lpSecurityDescriptor); - delete [] pszClass; - if (lResult != NO_ERROR) return lResult; - } - - // Copy subkey recursively. - return CopyKeyRecursively(hKeySrc, hKeyDst, samAdditional); -} - - -LONG COpRegKeyCopy::CopyKeyRecursively(HKEY hKeySrc, HKEY hKeyDst, REGSAM samAdditional) -{ - LONG lResult; - DWORD dwMaxSubKeyLen, dwMaxValueNameLen, dwMaxClassLen, dwMaxDataSize, dwIndex; - LPWSTR pszName, pszClass; - LPBYTE lpData; - - // Query the source key. - lResult = ::RegQueryInfoKeyW(hKeySrc, NULL, NULL, NULL, NULL, &dwMaxSubKeyLen, &dwMaxClassLen, NULL, &dwMaxValueNameLen, &dwMaxDataSize, NULL, NULL); - if (lResult != NO_ERROR) return lResult; - - // Copy values first. - dwMaxValueNameLen++; - pszName = new WCHAR[dwMaxValueNameLen]; - lpData = new BYTE[dwMaxDataSize]; - for (dwIndex = 0; ; dwIndex++) { - DWORD dwNameLen = dwMaxValueNameLen, dwType, dwValueSize = dwMaxDataSize; - - // Read value. - lResult = ::RegEnumValueW(hKeySrc, dwIndex, pszName, &dwNameLen, NULL, &dwType, lpData, &dwValueSize); - if (lResult == ERROR_NO_MORE_ITEMS) { - lResult = NO_ERROR; - break; - } else if (lResult != NO_ERROR) - break; - - // Save value. - lResult = ::RegSetValueExW(hKeyDst, pszName, 0, dwType, lpData, dwValueSize); - if (lResult != NO_ERROR) - break; - } - delete [] lpData; - delete [] pszName; - if (lResult != NO_ERROR) return lResult; - - // Iterate over all subkeys and copy them. - dwMaxSubKeyLen++; - pszName = new WCHAR[dwMaxSubKeyLen]; - dwMaxClassLen++; - pszClass = new WCHAR[dwMaxClassLen]; - for (dwIndex = 0; ; dwIndex++) { - DWORD dwNameLen = dwMaxSubKeyLen, dwClassLen = dwMaxClassLen; - HKEY hKeySrcSub, hKeyDstSub; - - // Read subkey. - lResult = ::RegEnumKeyExW(hKeySrc, dwIndex, pszName, &dwNameLen, NULL, pszClass, &dwClassLen, NULL); - if (lResult == ERROR_NO_MORE_ITEMS) { - lResult = NO_ERROR; - break; - } else if (lResult != NO_ERROR) - break; - - // Open source subkey. - lResult = ::RegOpenKeyExW(hKeySrc, pszName, 0, READ_CONTROL | KEY_READ | samAdditional, &hKeySrcSub); - if (lResult != NO_ERROR) break; - - { - DWORD dwSecurityDescriptorSize; - SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES) }; - - // Get source subkey security descriptor size. - lResult = ::RegQueryInfoKeyW(hKeySrcSub, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwSecurityDescriptorSize, NULL); - if (lResult != NO_ERROR) break; - - // Get source subkey security descriptor. - sa.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(new BYTE[dwSecurityDescriptorSize]); - lResult = ::RegGetKeySecurity(hKeySrc, DACL_SECURITY_INFORMATION, sa.lpSecurityDescriptor, &dwSecurityDescriptorSize); - if (lResult != NO_ERROR) { - delete [] (LPBYTE)(sa.lpSecurityDescriptor); - break; - } - - // Create new destination subkey of the same class and security. - lResult = ::RegCreateKeyExW(hKeyDst, pszName, 0, pszClass, REG_OPTION_NON_VOLATILE, KEY_WRITE | samAdditional, &sa, &hKeyDstSub, NULL); - delete [] (LPBYTE)(sa.lpSecurityDescriptor); - if (lResult != NO_ERROR) break; - } - - // Copy subkey recursively. - lResult = CopyKeyRecursively(hKeySrcSub, hKeyDstSub, samAdditional); - if (lResult != NO_ERROR) break; - } - delete [] pszClass; - delete [] pszName; - - return lResult; -} - - -//////////////////////////////////////////////////////////////////////////// -// COpRegKeyDelete -//////////////////////////////////////////////////////////////////////////// - -COpRegKeyDelete::COpRegKeyDelete(HKEY hKey, LPCWSTR pszKeyName, int iTicks) : COpRegKeySingle(hKey, pszKeyName, iTicks) -{ -} - - -HRESULT COpRegKeyDelete::Execute(CSession *pSession) -{ - LONG lResult; - HKEY hKey; - REGSAM samAdditional = 0; - -#ifndef _WIN64 - if (IsWow64Process()) { - // 32-bit processes run as WOW64 should use 64-bit registry too. - samAdditional |= KEY_WOW64_64KEY; - } -#endif - - // Probe to see if the key exists. - lResult = ::RegOpenKeyExW(m_hKeyRoot, m_sValue, 0, DELETE | samAdditional, &hKey); - if (lResult == NO_ERROR) { - ::RegCloseKey(hKey); - - if (pSession->m_bRollbackEnabled) { - // Make a backup of the key first. - ATL::CAtlStringW sBackupName; - UINT uiCount = 0; - int iLength = m_sValue.GetLength(); - - // Trim trailing backslashes. - while (iLength && m_sValue.GetAt(iLength - 1) == L'\\') iLength--; - - for (;;) { - HKEY hKey; - sBackupName.Format(L"%.*ls (orig %u)", iLength, (LPCWSTR)m_sValue, ++uiCount); - lResult = ::RegOpenKeyExW(m_hKeyRoot, sBackupName, 0, KEY_ENUMERATE_SUB_KEYS | samAdditional, &hKey); - if (lResult != NO_ERROR) break; - ::RegCloseKey(hKey); - } - if (lResult == ERROR_FILE_NOT_FOUND) { - // Since copying registry key is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it. - COpRegKeyCopy opCopy(m_hKeyRoot, m_sValue, sBackupName); - HRESULT hr = opCopy.Execute(pSession); - if (FAILED(hr)) return hr; - - // Order rollback action to restore the key from backup copy. - pSession->m_olRollback.AddHead(new COpRegKeyCopy(m_hKeyRoot, sBackupName, m_sValue)); - - // Order commit action to delete backup copy. - pSession->m_olCommit.AddTail(new COpRegKeyDelete(m_hKeyRoot, sBackupName)); - } else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_PROBING ); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff); - ::MsiRecordSetStringW(hRecordProg, 3, sBackupName ); - ::MsiRecordSetInteger(hRecordProg, 4, lResult ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(lResult); - } - } - - // Delete the registry key. - lResult = DeleteKeyRecursively(m_hKeyRoot, m_sValue, samAdditional); - } - - if (lResult == NO_ERROR || lResult == ERROR_FILE_NOT_FOUND) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_DELETE ); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 4, lResult ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(lResult); - } -} - - -LONG COpRegKeyDelete::DeleteKeyRecursively(HKEY hKeyRoot, LPCWSTR pszKeyName, REGSAM samAdditional) -{ - HKEY hKey; - LONG lResult; - - // Open the key. - lResult = ::RegOpenKeyExW(hKeyRoot, pszKeyName, 0, DELETE | KEY_READ | samAdditional, &hKey); - if (lResult == NO_ERROR) { - DWORD dwMaxSubKeyLen; - - // Determine the largest subkey name. - lResult = ::RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL); - if (lResult == NO_ERROR) { - LPWSTR pszSubKeyName; - - // Prepare buffer to hold the subkey names (including zero terminator). - dwMaxSubKeyLen++; - pszSubKeyName = new WCHAR[dwMaxSubKeyLen]; - if (pszSubKeyName) { - DWORD dwIndex; - - // Iterate over all subkeys and delete them. Skip failed. - for (dwIndex = 0; ;) { - DWORD dwNameLen = dwMaxSubKeyLen; - lResult = ::RegEnumKeyExW(hKey, dwIndex, pszSubKeyName, &dwNameLen, NULL, NULL, NULL, NULL); - if (lResult == NO_ERROR) { - lResult = DeleteKeyRecursively(hKey, pszSubKeyName, samAdditional); - if (lResult != NO_ERROR) - dwIndex++; - } else if (lResult == ERROR_NO_MORE_ITEMS) { - lResult = NO_ERROR; - break; - } else - dwIndex++; - } - - delete [] pszSubKeyName; - } else - lResult = ERROR_OUTOFMEMORY; - } - - ::RegCloseKey(hKey); - - // Finally try to delete the key. - lResult = ::RegDeleteKeyW(hKeyRoot, pszKeyName); - } else if (lResult == ERROR_FILE_NOT_FOUND) { - // The key doesn't exist. Not really an error in this case. - lResult = NO_ERROR; - } - - return lResult; -} - - -//////////////////////////////////////////////////////////////////////////// -// COpRegValueSingle -//////////////////////////////////////////////////////////////////////////// - -COpRegValueSingle::COpRegValueSingle(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, int iTicks) : - m_sValueName(pszValueName), - COpRegKeySingle(hKeyRoot, pszKeyName, iTicks) -{ -} - - -//////////////////////////////////////////////////////////////////////////// -// COpRegValueSrcDst -//////////////////////////////////////////////////////////////////////////// - -COpRegValueSrcDst::COpRegValueSrcDst(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueNameSrc, LPCWSTR pszValueNameDst, int iTicks) : - m_sValueName1(pszValueNameSrc), - m_sValueName2(pszValueNameDst), - COpRegKeySingle(hKeyRoot, pszKeyName, iTicks) -{ -} - - -//////////////////////////////////////////////////////////////////////////// -// COpRegValueCreate -//////////////////////////////////////////////////////////////////////////// - -COpRegValueCreate::COpRegValueCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, int iTicks) : - m_dwType(REG_NONE), - COpRegValueSingle(hKeyRoot, pszKeyName, pszValueName, iTicks) -{ -} - - -COpRegValueCreate::COpRegValueCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, DWORD dwData, int iTicks) : - m_dwType(REG_DWORD), - m_dwData(dwData), - COpRegValueSingle(hKeyRoot, pszKeyName, pszValueName, iTicks) -{ -} - - -COpRegValueCreate::COpRegValueCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, LPCVOID lpData, SIZE_T nSize, int iTicks) : - m_dwType(REG_BINARY), - COpRegValueSingle(hKeyRoot, pszKeyName, pszValueName, iTicks) -{ - m_binData.SetCount(nSize); - memcpy(m_binData.GetData(), lpData, nSize); -} - - -COpRegValueCreate::COpRegValueCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, LPCWSTR pszData, int iTicks) : - m_dwType(REG_SZ), - m_sData(pszData), - COpRegValueSingle(hKeyRoot, pszKeyName, pszValueName, iTicks) -{ -} - - -COpRegValueCreate::COpRegValueCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, DWORDLONG qwData, int iTicks) : - m_dwType(REG_QWORD), - m_qwData(qwData), - COpRegValueSingle(hKeyRoot, pszKeyName, pszValueName, iTicks) -{ -} - - -HRESULT COpRegValueCreate::Execute(CSession *pSession) -{ - LONG lResult; - REGSAM sam = KEY_QUERY_VALUE | STANDARD_RIGHTS_WRITE | KEY_SET_VALUE; - HKEY hKey; - - { - // Delete existing value first. - // Since deleting registry value is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it. - // Don't worry, COpRegValueDelete::Execute() returns S_OK if key doesn't exist. - COpRegValueDelete opDelete(m_hKeyRoot, m_sValue, m_sValueName); - HRESULT hr = opDelete.Execute(pSession); - if (FAILED(hr)) return hr; - } - -#ifndef _WIN64 - if (IsWow64Process()) { - // 32-bit processes run as WOW64 should use 64-bit registry too. - sam |= KEY_WOW64_64KEY; - } -#endif - - // Open the key. - lResult = ::RegOpenKeyExW(m_hKeyRoot, m_sValue, 0, sam, &hKey); - if (lResult == NO_ERROR) { - if (pSession->m_bRollbackEnabled) { - // Order rollback action to delete the value. - pSession->m_olRollback.AddHead(new COpRegValueDelete(m_hKeyRoot, m_sValue, m_sValueName)); - } - - // Set the registry value. - switch (m_dwType) { - case REG_SZ: - case REG_EXPAND_SZ: - case REG_LINK: - lResult = ::RegSetValueExW(hKey, m_sValueName, 0, m_dwType, (const BYTE*)(LPCWSTR)m_sData, (m_sData.GetLength() + 1) * sizeof(WCHAR)); break; - break; - - case REG_BINARY: - lResult = ::RegSetValueExW(hKey, m_sValueName, 0, m_dwType, m_binData.GetData(), (DWORD)m_binData.GetCount() * sizeof(BYTE)); break; - - case REG_DWORD_LITTLE_ENDIAN: - case REG_DWORD_BIG_ENDIAN: - lResult = ::RegSetValueExW(hKey, m_sValueName, 0, m_dwType, (const BYTE*)&m_dwData, sizeof(DWORD)); break; - break; - - case REG_MULTI_SZ: - lResult = ::RegSetValueExW(hKey, m_sValueName, 0, m_dwType, (const BYTE*)m_szData.GetData(), (DWORD)m_szData.GetCount() * sizeof(WCHAR)); break; - break; - - case REG_QWORD_LITTLE_ENDIAN: - lResult = ::RegSetValueExW(hKey, m_sValueName, 0, m_dwType, (const BYTE*)&m_qwData, sizeof(DWORDLONG)); break; - break; - - default: - lResult = ERROR_UNSUPPORTED_TYPE; - } - - ::RegCloseKey(hKey); - } - - if (lResult == NO_ERROR) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(5); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_SETVALUE); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetStringW(hRecordProg, 4, m_sValueName ); - ::MsiRecordSetInteger(hRecordProg, 5, lResult ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(lResult); - } -} - - -//////////////////////////////////////////////////////////////////////////// -// COpRegValueCopy -//////////////////////////////////////////////////////////////////////////// - -COpRegValueCopy::COpRegValueCopy(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueNameSrc, LPCWSTR pszValueNameDst, int iTicks) : COpRegValueSrcDst(hKeyRoot, pszKeyName, pszValueNameSrc, pszValueNameDst, iTicks) -{ -} - - -HRESULT COpRegValueCopy::Execute(CSession *pSession) -{ - LONG lResult; - REGSAM sam = KEY_QUERY_VALUE | KEY_SET_VALUE; - HKEY hKey; - - { - // Delete existing destination value first. - // Since deleting registry value is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it. - // Don't worry, COpRegValueDelete::Execute() returns S_OK if key doesn't exist. - COpRegValueDelete opDelete(m_hKeyRoot, m_sValue, m_sValueName2); - HRESULT hr = opDelete.Execute(pSession); - if (FAILED(hr)) return hr; - } - -#ifndef _WIN64 - if (IsWow64Process()) { - // 32-bit processes run as WOW64 should use 64-bit registry too. - sam |= KEY_WOW64_64KEY; - } -#endif - - // Open the key. - lResult = ::RegOpenKeyExW(m_hKeyRoot, m_sValue, 0, sam, &hKey); - if (lResult == NO_ERROR) { - DWORD dwType, dwSize; - - // Query the source registry value size. - lResult = ::RegQueryValueExW(hKey, m_sValueName1, 0, NULL, NULL, &dwSize); - if (lResult == NO_ERROR) { - LPBYTE lpData = new BYTE[dwSize]; - // Read the source registry value. - lResult = ::RegQueryValueExW(hKey, m_sValueName1, 0, &dwType, lpData, &dwSize); - if (lResult == NO_ERROR) { - if (pSession->m_bRollbackEnabled) { - // Order rollback action to delete the destination copy. - pSession->m_olRollback.AddHead(new COpRegValueDelete(m_hKeyRoot, m_sValue, m_sValueName2)); - } - - // Store the value to destination. - lResult = ::RegSetValueExW(hKey, m_sValueName2, 0, dwType, lpData, dwSize); - } - delete [] lpData; - } - - ::RegCloseKey(hKey); - } - - if (lResult == NO_ERROR) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(6); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_COPYVALUE); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetStringW(hRecordProg, 4, m_sValueName1 ); - ::MsiRecordSetStringW(hRecordProg, 5, m_sValueName2 ); - ::MsiRecordSetInteger(hRecordProg, 6, lResult ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(lResult); - } -} - - -//////////////////////////////////////////////////////////////////////////// -// COpRegValueDelete -//////////////////////////////////////////////////////////////////////////// - -COpRegValueDelete::COpRegValueDelete(HKEY hKeyRoot, LPCWSTR pszKeyName, LPCWSTR pszValueName, int iTicks) : COpRegValueSingle(hKeyRoot, pszKeyName, pszValueName, iTicks) -{ -} - - -HRESULT COpRegValueDelete::Execute(CSession *pSession) -{ - LONG lResult; - REGSAM sam = KEY_QUERY_VALUE | KEY_SET_VALUE; - HKEY hKey; - -#ifndef _WIN64 - if (IsWow64Process()) { - // 32-bit processes run as WOW64 should use 64-bit registry too. - sam |= KEY_WOW64_64KEY; - } -#endif - - // Open the key. - lResult = ::RegOpenKeyExW(m_hKeyRoot, m_sValue, 0, sam, &hKey); - if (lResult == NO_ERROR) { - DWORD dwType; - - // See if the value exists at all. - lResult = ::RegQueryValueExW(hKey, m_sValueName, 0, &dwType, NULL, NULL); - if (lResult == NO_ERROR) { - if (pSession->m_bRollbackEnabled) { - // Make a backup of the value first. - ATL::CAtlStringW sBackupName; - UINT uiCount = 0; - - for (;;) { - sBackupName.Format(L"%ls (orig %u)", (LPCWSTR)m_sValueName, ++uiCount); - lResult = ::RegQueryValueExW(hKey, sBackupName, 0, &dwType, NULL, NULL); - if (lResult != NO_ERROR) break; - } - if (lResult == ERROR_FILE_NOT_FOUND) { - // Since copying registry value is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it. - COpRegValueCopy opCopy(m_hKeyRoot, m_sValue, m_sValueName, sBackupName); - HRESULT hr = opCopy.Execute(pSession); - if (FAILED(hr)) { - ::RegCloseKey(hKey); - return hr; - } - - // Order rollback action to restore the key from backup copy. - pSession->m_olRollback.AddHead(new COpRegValueCopy(m_hKeyRoot, m_sValue, sBackupName, m_sValueName)); - - // Order commit action to delete backup copy. - pSession->m_olCommit.AddTail(new COpRegValueDelete(m_hKeyRoot, m_sValue, sBackupName)); - } else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(5); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_PROBINGVAL); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetStringW(hRecordProg, 3, sBackupName ); - ::MsiRecordSetInteger(hRecordProg, 4, lResult ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - ::RegCloseKey(hKey); - return AtlHresultFromWin32(lResult); - } - } - - // Delete the registry value. - lResult = ::RegDeleteValueW(hKey, m_sValueName); - } - - ::RegCloseKey(hKey); - } - - if (lResult == NO_ERROR || lResult == ERROR_FILE_NOT_FOUND) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(5); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_DELETEVALUE); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetStringW(hRecordProg, 4, m_sValueName ); - ::MsiRecordSetInteger(hRecordProg, 5, lResult ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(lResult); - } -} - -} // namespace MSICA diff --git a/MSICALib/OpSvc.cpp b/MSICALib/OpSvc.cpp deleted file mode 100644 index d0f29e3..0000000 --- a/MSICALib/OpSvc.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#include "stdafx.h" - -#pragma comment(lib, "advapi32.lib") - - -namespace MSICA { - -//////////////////////////////////////////////////////////////////////////// -// COpSvcSetStart -//////////////////////////////////////////////////////////////////////////// - -COpSvcSetStart::COpSvcSetStart(LPCWSTR pszService, DWORD dwStartType, int iTicks) : - COpTypeSingleString(pszService, iTicks), - m_dwStartType(dwStartType) -{ -} - - -HRESULT COpSvcSetStart::Execute(CSession *pSession) -{ - DWORD dwError; - SC_HANDLE hSCM; - - // Open Service Control Manager. - hSCM = ::OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); - if (hSCM) { - SC_HANDLE hService; - - // Open the specified service. - hService = ::OpenServiceW(hSCM, m_sValue, SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG); - if (hService) { - QUERY_SERVICE_CONFIG *sc; - DWORD dwSize; - HANDLE hHeap = ::GetProcessHeap(); - - ::QueryServiceConfig(hService, NULL, 0, &dwSize); - sc = (QUERY_SERVICE_CONFIG*)::HeapAlloc(hHeap, 0, dwSize); - if (sc) { - // Query current service config. - if (::QueryServiceConfig(hService, sc, dwSize, &dwSize)) { - if (sc->dwStartType != m_dwStartType) { - // Set requested service start. - if (::ChangeServiceConfig(hService, SERVICE_NO_CHANGE, m_dwStartType, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) { - if (pSession->m_bRollbackEnabled) { - // Order rollback action to revert the service start change. - pSession->m_olRollback.AddHead(new COpSvcSetStart(m_sValue, sc->dwStartType)); - } - dwError = NO_ERROR; - } else - dwError = ::GetLastError(); - } else { - // Service is already configured to start the requested way. - dwError = NO_ERROR; - } - } else - dwError = ::GetLastError(); - - ::HeapFree(hHeap, 0, sc); - } else - dwError = ERROR_OUTOFMEMORY; - } else - dwError = ::GetLastError(); - } else - dwError = ::GetLastError(); - - if (dwError == NO_ERROR) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_SVC_SET_START); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(dwError); - } -} - - -//////////////////////////////////////////////////////////////////////////// -// COpSvcControl -//////////////////////////////////////////////////////////////////////////// - -COpSvcControl::COpSvcControl(LPCWSTR pszService, BOOL bWait, int iTicks) : - COpTypeSingleString(pszService, iTicks), - m_bWait(bWait) -{ -} - - -DWORD COpSvcControl::WaitForState(CSession *pSession, SC_HANDLE hService, DWORD dwPendingState, DWORD dwFinalState) -{ - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - - // Prepare hRecordProg for progress messages. - ::MsiRecordSetInteger(hRecordProg, 1, 2); - ::MsiRecordSetInteger(hRecordProg, 3, 0); - - // Wait for the service to start. - for (;;) { - SERVICE_STATUS_PROCESS ssp; - DWORD dwSize; - - // Check service status. - if (::QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwSize)) { - if (ssp.dwCurrentState == dwPendingState) { - // Service is pending. Wait some more ... - ::Sleep(ssp.dwWaitHint < 1000 ? ssp.dwWaitHint : 1000); - } else if (ssp.dwCurrentState == dwFinalState) { - // Service is in expected state. - return NO_ERROR; - } else { - // Service is in unexpected state. - return ERROR_ASSERTION_FAILURE; - } - } else { - // Service query failed. - return ::GetLastError(); - } - - // Check if user cancelled installation. - ::MsiRecordSetInteger(hRecordProg, 2, 0); - if (::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL) - return ERROR_INSTALL_USEREXIT; - } -} - - -//////////////////////////////////////////////////////////////////////////// -// COpSvcStart -//////////////////////////////////////////////////////////////////////////// - -COpSvcStart::COpSvcStart(LPCWSTR pszService, BOOL bWait, int iTicks) : COpSvcControl(pszService, bWait, iTicks) -{ -} - - -HRESULT COpSvcStart::Execute(CSession *pSession) -{ - DWORD dwError; - SC_HANDLE hSCM; - - // Open Service Control Manager. - hSCM = ::OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); - if (hSCM) { - SC_HANDLE hService; - - // Open the specified service. - hService = ::OpenServiceW(hSCM, m_sValue, SERVICE_START | (m_bWait ? SERVICE_QUERY_STATUS : 0)); - if (hService) { - // Start the service. - if (::StartService(hService, 0, NULL)) { - dwError = m_bWait ? WaitForState(pSession, hService, SERVICE_START_PENDING, SERVICE_RUNNING) : NO_ERROR; - if (dwError == NO_ERROR && pSession->m_bRollbackEnabled) { - // Order rollback action to stop the service. - pSession->m_olRollback.AddHead(new COpSvcStop(m_sValue)); - } - } else { - dwError = ::GetLastError(); - if (dwError == ERROR_SERVICE_ALREADY_RUNNING) { - // Service is already running. Not an error. - dwError = NO_ERROR; - } - } - } else - dwError = ::GetLastError(); - } else - dwError = ::GetLastError(); - - if (dwError == NO_ERROR) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_SVC_START); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(dwError); - } -} - - -//////////////////////////////////////////////////////////////////////////// -// COpSvcStop -//////////////////////////////////////////////////////////////////////////// - -COpSvcStop::COpSvcStop(LPCWSTR pszService, BOOL bWait, int iTicks) : COpSvcControl(pszService, bWait, iTicks) -{ -} - - -HRESULT COpSvcStop::Execute(CSession *pSession) -{ - DWORD dwError; - SC_HANDLE hSCM; - - // Open Service Control Manager. - hSCM = ::OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT); - if (hSCM) { - SC_HANDLE hService; - - // Open the specified service. - hService = ::OpenServiceW(hSCM, m_sValue, SERVICE_STOP | (m_bWait ? SERVICE_QUERY_STATUS : 0)); - if (hService) { - SERVICE_STATUS ss; - // Stop the service. - if (::ControlService(hService, SERVICE_CONTROL_STOP, &ss)) { - dwError = m_bWait ? WaitForState(pSession, hService, SERVICE_STOP_PENDING, SERVICE_STOPPED) : NO_ERROR; - if (dwError == NO_ERROR && pSession->m_bRollbackEnabled) { - // Order rollback action to start the service. - pSession->m_olRollback.AddHead(new COpSvcStart(m_sValue)); - } - } else { - dwError = ::GetLastError(); - if (dwError == ERROR_SERVICE_NOT_ACTIVE) { - // Service is already stopped. Not an error. - dwError = NO_ERROR; - } - } - } else - dwError = ::GetLastError(); - } else - dwError = ::GetLastError(); - - if (dwError == NO_ERROR) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_SVC_STOP); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(dwError); - } -} - -} // namespace MSICA diff --git a/MSICALib/OpTS.cpp b/MSICALib/OpTS.cpp deleted file mode 100644 index d10b3c8..0000000 --- a/MSICALib/OpTS.cpp +++ /dev/null @@ -1,1054 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#include "stdafx.h" - -#pragma comment(lib, "mstask.lib") -#pragma comment(lib, "taskschd.lib") - - -namespace MSICA { - -//////////////////////////////////////////////////////////////////////////// -// COpTaskCreate -//////////////////////////////////////////////////////////////////////////// - -COpTaskCreate::COpTaskCreate(LPCWSTR pszTaskName, int iTicks) : - m_dwFlags(0), - m_dwPriority(NORMAL_PRIORITY_CLASS), - m_wIdleMinutes(0), - m_wDeadlineMinutes(0), - m_dwMaxRuntimeMS(INFINITE), - COpTypeSingleString(pszTaskName, iTicks) -{ -} - - -COpTaskCreate::~COpTaskCreate() -{ - // Clear the password in memory. - int iLength = m_sPassword.GetLength(); - ::SecureZeroMemory(m_sPassword.GetBuffer(iLength), sizeof(WCHAR) * iLength); - m_sPassword.ReleaseBuffer(0); -} - - -HRESULT COpTaskCreate::Execute(CSession *pSession) -{ - HRESULT hr; - PMSIHANDLE hRecordMsg = ::MsiCreateRecord(1); - CComPtr pService; - POSITION pos; - - // Display our custom message in the progress bar. - ::MsiRecordSetStringW(hRecordMsg, 1, m_sValue); - if (MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ACTIONDATA, hRecordMsg) == IDCANCEL) - return AtlHresultFromWin32(ERROR_INSTALL_USEREXIT); - - { - // Delete existing task first. - // Since task deleting is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it. - // Don't worry, COpTaskDelete::Execute() returns S_OK if task doesn't exist. - COpTaskDelete opDelete(m_sValue); - hr = opDelete.Execute(pSession); - if (FAILED(hr)) goto finish; - } - - hr = pService.CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER); - if (SUCCEEDED(hr)) { - // Windows Vista or newer. - CComVariant vEmpty; - CComPtr pTaskDefinition; - CComPtr pTaskSettings; - CComPtr pPrincipal; - CComPtr pActionCollection; - CComPtr pAction; - CComPtr pIdleSettings; - CComPtr pExecAction; - CComPtr pRegististrationInfo; - CComPtr pTriggerCollection; - CComPtr pTaskFolder; - CComPtr pTask; - ATL::CAtlStringW str; - UINT iTrigger; - TASK_LOGON_TYPE logonType; - CComBSTR bstrContext(L"Author"); - - // Connect to local task service. - hr = pService->Connect(vEmpty, vEmpty, vEmpty, vEmpty); - if (FAILED(hr)) goto finish; - - // Prepare the definition for a new task. - hr = pService->NewTask(0, &pTaskDefinition); - if (FAILED(hr)) goto finish; - - // Get the task's settings. - hr = pTaskDefinition->get_Settings(&pTaskSettings); - if (FAILED(hr)) goto finish; - - // Enable/disable task. - if (pSession->m_bRollbackEnabled && (m_dwFlags & TASK_FLAG_DISABLED) == 0) { - // The task is supposed to be enabled. - // However, we shall enable it at commit to prevent it from accidentally starting in the very installation phase. - pSession->m_olCommit.AddTail(new COpTaskEnable(m_sValue, TRUE)); - m_dwFlags |= TASK_FLAG_DISABLED; - } - hr = pTaskSettings->put_Enabled(m_dwFlags & TASK_FLAG_DISABLED ? VARIANT_FALSE : VARIANT_TRUE); if (FAILED(hr)) goto finish; - - // Get task actions. - hr = pTaskDefinition->get_Actions(&pActionCollection); - if (FAILED(hr)) goto finish; - - // Add execute action. - hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction); - if (FAILED(hr)) goto finish; - hr = pAction.QueryInterface(&pExecAction); - if (FAILED(hr)) goto finish; - - // Configure the action. - hr = pExecAction->put_Path (CComBSTR(m_sApplicationName )); if (FAILED(hr)) goto finish; - hr = pExecAction->put_Arguments (CComBSTR(m_sParameters )); if (FAILED(hr)) goto finish; - hr = pExecAction->put_WorkingDirectory(CComBSTR(m_sWorkingDirectory)); if (FAILED(hr)) goto finish; - - // Set task description. - hr = pTaskDefinition->get_RegistrationInfo(&pRegististrationInfo); - if (FAILED(hr)) goto finish; - hr = pRegististrationInfo->put_Author(CComBSTR(m_sAuthor)); - if (FAILED(hr)) goto finish; - hr = pRegististrationInfo->put_Description(CComBSTR(m_sComment)); - if (FAILED(hr)) goto finish; - - // Configure task "flags". - if (m_dwFlags & TASK_FLAG_DELETE_WHEN_DONE) { - hr = pTaskSettings->put_DeleteExpiredTaskAfter(CComBSTR(L"PT24H")); - if (FAILED(hr)) goto finish; - } - hr = pTaskSettings->put_Hidden(m_dwFlags & TASK_FLAG_HIDDEN ? VARIANT_TRUE : VARIANT_FALSE); - if (FAILED(hr)) goto finish; - hr = pTaskSettings->put_WakeToRun(m_dwFlags & TASK_FLAG_SYSTEM_REQUIRED ? VARIANT_TRUE : VARIANT_FALSE); - if (FAILED(hr)) goto finish; - hr = pTaskSettings->put_DisallowStartIfOnBatteries(m_dwFlags & TASK_FLAG_DONT_START_IF_ON_BATTERIES ? VARIANT_TRUE : VARIANT_FALSE); - if (FAILED(hr)) goto finish; - hr = pTaskSettings->put_StopIfGoingOnBatteries(m_dwFlags & TASK_FLAG_KILL_IF_GOING_ON_BATTERIES ? VARIANT_TRUE : VARIANT_FALSE); - if (FAILED(hr)) goto finish; - - // Configure task priority. - hr = pTaskSettings->put_Priority( - m_dwPriority == REALTIME_PRIORITY_CLASS ? 0 : - m_dwPriority == HIGH_PRIORITY_CLASS ? 1 : - m_dwPriority == ABOVE_NORMAL_PRIORITY_CLASS ? 2 : - m_dwPriority == NORMAL_PRIORITY_CLASS ? 4 : - m_dwPriority == BELOW_NORMAL_PRIORITY_CLASS ? 7 : - m_dwPriority == IDLE_PRIORITY_CLASS ? 9 : 7); - if (FAILED(hr)) goto finish; - - // Get task principal. - hr = pTaskDefinition->get_Principal(&pPrincipal); - if (FAILED(hr)) goto finish; - - if (m_sAccountName.IsEmpty()) { - logonType = TASK_LOGON_SERVICE_ACCOUNT; - hr = pPrincipal->put_LogonType(logonType); if (FAILED(hr)) goto finish; - hr = pPrincipal->put_UserId(CComBSTR(L"S-1-5-18")); if (FAILED(hr)) goto finish; - hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST); if (FAILED(hr)) goto finish; - } else if (m_dwFlags & TASK_FLAG_RUN_ONLY_IF_LOGGED_ON) { - logonType = TASK_LOGON_INTERACTIVE_TOKEN; - hr = pPrincipal->put_LogonType(logonType); if (FAILED(hr)) goto finish; - hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_LUA); if (FAILED(hr)) goto finish; - } else { - logonType = TASK_LOGON_PASSWORD; - hr = pPrincipal->put_LogonType(logonType); if (FAILED(hr)) goto finish; - hr = pPrincipal->put_UserId(CComBSTR(m_sAccountName)); if (FAILED(hr)) goto finish; - hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST); if (FAILED(hr)) goto finish; - } - - // Connect principal and action collection. - hr = pPrincipal->put_Id(bstrContext); - if (FAILED(hr)) goto finish; - hr = pActionCollection->put_Context(bstrContext); - if (FAILED(hr)) goto finish; - - // Configure idle settings. - hr = pTaskSettings->put_RunOnlyIfIdle(m_dwFlags & TASK_FLAG_START_ONLY_IF_IDLE ? VARIANT_TRUE : VARIANT_FALSE); - if (FAILED(hr)) goto finish; - hr = pTaskSettings->get_IdleSettings(&pIdleSettings); - if (FAILED(hr)) goto finish; - str.Format(L"PT%uS", m_wIdleMinutes*60); - hr = pIdleSettings->put_IdleDuration(CComBSTR(str)); - if (FAILED(hr)) goto finish; - str.Format(L"PT%uS", m_wDeadlineMinutes*60); - hr = pIdleSettings->put_WaitTimeout(CComBSTR(str)); - if (FAILED(hr)) goto finish; - hr = pIdleSettings->put_RestartOnIdle(m_dwFlags & TASK_FLAG_RESTART_ON_IDLE_RESUME ? VARIANT_TRUE : VARIANT_FALSE); - if (FAILED(hr)) goto finish; - hr = pIdleSettings->put_StopOnIdleEnd(m_dwFlags & TASK_FLAG_KILL_ON_IDLE_END ? VARIANT_TRUE : VARIANT_FALSE); - if (FAILED(hr)) goto finish; - - // Configure task runtime limit. - str.Format(L"PT%uS", m_dwMaxRuntimeMS != INFINITE ? (m_dwMaxRuntimeMS + 500) / 1000 : 0); - hr = pTaskSettings->put_ExecutionTimeLimit(CComBSTR(str)); - if (FAILED(hr)) goto finish; - - // Get task trigger colection. - hr = pTaskDefinition->get_Triggers(&pTriggerCollection); - if (FAILED(hr)) goto finish; - - // Add triggers. - for (pos = m_lTriggers.GetHeadPosition(), iTrigger = 0; pos; iTrigger++) { - CComPtr pTrigger; - TASK_TRIGGER &ttData = m_lTriggers.GetNext(pos); - - switch (ttData.TriggerType) { - case TASK_TIME_TRIGGER_ONCE: { - CComPtr pTriggerTime; - hr = pTriggerCollection->Create(TASK_TRIGGER_TIME, &pTrigger); if (FAILED(hr)) goto finish; - hr = pTrigger.QueryInterface(&pTriggerTime); if (FAILED(hr)) goto finish; - str.Format(L"PT%uM", ttData.wRandomMinutesInterval); - hr = pTriggerTime->put_RandomDelay(CComBSTR(str)); if (FAILED(hr)) goto finish; - break; - } - - case TASK_TIME_TRIGGER_DAILY: { - CComPtr pTriggerDaily; - hr = pTriggerCollection->Create(TASK_TRIGGER_DAILY, &pTrigger); if (FAILED(hr)) goto finish; - hr = pTrigger.QueryInterface(&pTriggerDaily); if (FAILED(hr)) goto finish; - hr = pTriggerDaily->put_DaysInterval(ttData.Type.Daily.DaysInterval); if (FAILED(hr)) goto finish; - str.Format(L"PT%uM", ttData.wRandomMinutesInterval); - hr = pTriggerDaily->put_RandomDelay(CComBSTR(str)); if (FAILED(hr)) goto finish; - break; - } - - case TASK_TIME_TRIGGER_WEEKLY: { - CComPtr pTriggerWeekly; - hr = pTriggerCollection->Create(TASK_TRIGGER_WEEKLY, &pTrigger); if (FAILED(hr)) goto finish; - hr = pTrigger.QueryInterface(&pTriggerWeekly); if (FAILED(hr)) goto finish; - hr = pTriggerWeekly->put_WeeksInterval(ttData.Type.Weekly.WeeksInterval); if (FAILED(hr)) goto finish; - hr = pTriggerWeekly->put_DaysOfWeek(ttData.Type.Weekly.rgfDaysOfTheWeek); if (FAILED(hr)) goto finish; - str.Format(L"PT%uM", ttData.wRandomMinutesInterval); - hr = pTriggerWeekly->put_RandomDelay(CComBSTR(str)); if (FAILED(hr)) goto finish; - break; - } - - case TASK_TIME_TRIGGER_MONTHLYDATE: { - CComPtr pTriggerMonthly; - hr = pTriggerCollection->Create(TASK_TRIGGER_MONTHLY, &pTrigger); if (FAILED(hr)) goto finish; - hr = pTrigger.QueryInterface(&pTriggerMonthly); if (FAILED(hr)) goto finish; - hr = pTriggerMonthly->put_DaysOfMonth(ttData.Type.MonthlyDate.rgfDays); if (FAILED(hr)) goto finish; - hr = pTriggerMonthly->put_MonthsOfYear(ttData.Type.MonthlyDate.rgfMonths); if (FAILED(hr)) goto finish; - str.Format(L"PT%uM", ttData.wRandomMinutesInterval); - hr = pTriggerMonthly->put_RandomDelay(CComBSTR(str)); if (FAILED(hr)) goto finish; - break; - } - - case TASK_TIME_TRIGGER_MONTHLYDOW: { - CComPtr pTriggerMonthlyDOW; - hr = pTriggerCollection->Create(TASK_TRIGGER_MONTHLYDOW, &pTrigger); if (FAILED(hr)) goto finish; - hr = pTrigger.QueryInterface(&pTriggerMonthlyDOW); if (FAILED(hr)) goto finish; - hr = pTriggerMonthlyDOW->put_WeeksOfMonth( - ttData.Type.MonthlyDOW.wWhichWeek == TASK_FIRST_WEEK ? 0x01 : - ttData.Type.MonthlyDOW.wWhichWeek == TASK_SECOND_WEEK ? 0x02 : - ttData.Type.MonthlyDOW.wWhichWeek == TASK_THIRD_WEEK ? 0x04 : - ttData.Type.MonthlyDOW.wWhichWeek == TASK_FOURTH_WEEK ? 0x08 : - ttData.Type.MonthlyDOW.wWhichWeek == TASK_LAST_WEEK ? 0x10 : 0x00); if (FAILED(hr)) goto finish; - hr = pTriggerMonthlyDOW->put_DaysOfWeek(ttData.Type.MonthlyDOW.rgfDaysOfTheWeek); if (FAILED(hr)) goto finish; - hr = pTriggerMonthlyDOW->put_MonthsOfYear(ttData.Type.MonthlyDOW.rgfMonths); if (FAILED(hr)) goto finish; - str.Format(L"PT%uM", ttData.wRandomMinutesInterval); - hr = pTriggerMonthlyDOW->put_RandomDelay(CComBSTR(str)); if (FAILED(hr)) goto finish; - break; - } - - case TASK_EVENT_TRIGGER_ON_IDLE: { - hr = pTriggerCollection->Create(TASK_TRIGGER_IDLE, &pTrigger); if (FAILED(hr)) goto finish; - break; - } - - case TASK_EVENT_TRIGGER_AT_SYSTEMSTART: { - CComPtr pTriggerBoot; - hr = pTriggerCollection->Create(TASK_TRIGGER_BOOT, &pTrigger); if (FAILED(hr)) goto finish; - hr = pTrigger.QueryInterface(&pTriggerBoot); if (FAILED(hr)) goto finish; - str.Format(L"PT%uM", ttData.wRandomMinutesInterval); - hr = pTriggerBoot->put_Delay(CComBSTR(str)); if (FAILED(hr)) goto finish; - break; - } - - case TASK_EVENT_TRIGGER_AT_LOGON: { - CComPtr pTriggerLogon; - hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger); if (FAILED(hr)) goto finish; - hr = pTrigger.QueryInterface(&pTriggerLogon); if (FAILED(hr)) goto finish; - str.Format(L"PT%uM", ttData.wRandomMinutesInterval); - hr = pTriggerLogon->put_Delay(CComBSTR(str)); if (FAILED(hr)) goto finish; - break; - } - } - - // Set trigger ID. - str.Format(L"%u", iTrigger); - hr = pTrigger->put_Id(CComBSTR(str)); - if (FAILED(hr)) goto finish; - - // Set trigger start date. - str.Format(L"%04u-%02u-%02uT%02u:%02u:00", ttData.wBeginYear, ttData.wBeginMonth, ttData.wBeginDay, ttData.wStartHour, ttData.wStartMinute); - hr = pTrigger->put_StartBoundary(CComBSTR(str)); - if (FAILED(hr)) goto finish; - - if (ttData.rgFlags & TASK_TRIGGER_FLAG_HAS_END_DATE) { - // Set trigger end date. - str.Format(L"%04u-%02u-%02u", ttData.wEndYear, ttData.wEndMonth, ttData.wEndDay); - hr = pTrigger->put_EndBoundary(CComBSTR(str)); - if (FAILED(hr)) goto finish; - } - - // Set trigger repetition duration and interval. - if (ttData.MinutesDuration || ttData.MinutesInterval) { - CComPtr pRepetitionPattern; - - hr = pTrigger->get_Repetition(&pRepetitionPattern); - if (FAILED(hr)) goto finish; - str.Format(L"PT%uM", ttData.MinutesDuration); - hr = pRepetitionPattern->put_Duration(CComBSTR(str)); - if (FAILED(hr)) goto finish; - str.Format(L"PT%uM", ttData.MinutesInterval); - hr = pRepetitionPattern->put_Interval(CComBSTR(str)); - if (FAILED(hr)) goto finish; - hr = pRepetitionPattern->put_StopAtDurationEnd(ttData.rgFlags & TASK_TRIGGER_FLAG_KILL_AT_DURATION_END ? VARIANT_TRUE : VARIANT_FALSE); - if (FAILED(hr)) goto finish; - } - - // Enable/disable trigger. - hr = pTrigger->put_Enabled(ttData.rgFlags & TASK_TRIGGER_FLAG_DISABLED ? VARIANT_FALSE : VARIANT_TRUE); - if (FAILED(hr)) goto finish; - } - - // Get the task folder. - hr = pService->GetFolder(CComBSTR(L"\\"), &pTaskFolder); - if (FAILED(hr)) goto finish; - -#ifdef _DEBUG - CComBSTR xml; - hr = pTaskDefinition->get_XmlText(&xml); -#endif - - // Register the task. - hr = pTaskFolder->RegisterTaskDefinition( - CComBSTR(m_sValue), // path - pTaskDefinition, // pDefinition - TASK_CREATE, // flags - vEmpty, // userId - logonType != TASK_LOGON_SERVICE_ACCOUNT && !m_sPassword.IsEmpty() ? CComVariant(m_sPassword) : vEmpty, // password - logonType, // logonType - vEmpty, // sddl - &pTask); // ppTask - } else { - // Windows XP or older. - CComPtr pTaskScheduler; - CComPtr pTask; - - // Get task scheduler object. - hr = pTaskScheduler.CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_ALL); - if (FAILED(hr)) goto finish; - - // Create the new task. - hr = pTaskScheduler->NewWorkItem(m_sValue, CLSID_CTask, IID_ITask, (IUnknown**)&pTask); - if (pSession->m_bRollbackEnabled) { - // Order rollback action to delete the task. ITask::NewWorkItem() might made a blank task already. - pSession->m_olRollback.AddHead(new COpTaskDelete(m_sValue)); - } - if (FAILED(hr)) goto finish; - - // Set its properties. - hr = pTask->SetApplicationName (m_sApplicationName ); if (FAILED(hr)) goto finish; - hr = pTask->SetParameters (m_sParameters ); if (FAILED(hr)) goto finish; - hr = pTask->SetWorkingDirectory(m_sWorkingDirectory); if (FAILED(hr)) goto finish; - hr = pTask->SetComment (m_sComment ); if (FAILED(hr)) goto finish; - if (pSession->m_bRollbackEnabled && (m_dwFlags & TASK_FLAG_DISABLED) == 0) { - // The task is supposed to be enabled. - // However, we shall enable it at commit to prevent it from accidentally starting in the very installation phase. - pSession->m_olCommit.AddTail(new COpTaskEnable(m_sValue, TRUE)); - m_dwFlags |= TASK_FLAG_DISABLED; - } - hr = pTask->SetFlags (m_dwFlags ); if (FAILED(hr)) goto finish; - hr = pTask->SetPriority (m_dwPriority ); if (FAILED(hr)) goto finish; - - // Set task credentials. - hr = m_sAccountName.IsEmpty() ? - pTask->SetAccountInformation(L"", NULL ) : - pTask->SetAccountInformation(m_sAccountName, m_sPassword); - if (FAILED(hr)) goto finish; - - hr = pTask->SetIdleWait (m_wIdleMinutes, m_wDeadlineMinutes); if (FAILED(hr)) goto finish; - hr = pTask->SetMaxRunTime(m_dwMaxRuntimeMS ); if (FAILED(hr)) goto finish; - - // Add triggers. - for (pos = m_lTriggers.GetHeadPosition(); pos;) { - WORD wTriggerIdx; - CComPtr pTrigger; - TASK_TRIGGER ttData = m_lTriggers.GetNext(pos); // Don't use reference! We don't want to modify original trigger data by adding random startup delay. - - hr = pTask->CreateTrigger(&wTriggerIdx, &pTrigger); - if (FAILED(hr)) goto finish; - - if (ttData.wRandomMinutesInterval) { - // Windows XP doesn't support random startup delay. However, we can add fixed "random" delay when creating the trigger. - WORD wStartTime = ttData.wStartHour * 60 + ttData.wStartMinute + (WORD)::MulDiv(rand(), ttData.wRandomMinutesInterval, RAND_MAX); - FILETIME ftValue; - SYSTEMTIME stValue; - ULONGLONG ullValue; - - // Convert MDY date to numerical date (SYSTEMTIME -> FILETIME -> ULONGLONG). - ZeroMemory(&stValue, sizeof(stValue)); - stValue.wYear = ttData.wBeginYear; - stValue.wMonth = ttData.wBeginMonth; - stValue.wDay = ttData.wBeginDay; - ::SystemTimeToFileTime(&stValue, &ftValue); - ullValue = ((ULONGLONG)(ftValue.dwHighDateTime) << 32) | ftValue.dwLowDateTime; - - // Wrap days. - while (wStartTime >= 1440) { - ullValue += (ULONGLONG)864000000000; - wStartTime -= 1440; - } - - // Convert numerical date to DMY (ULONGLONG -> FILETIME -> SYSTEMTIME). - ftValue.dwHighDateTime = (DWORD)((ullValue >> 32) & 0xffffffff); - ftValue.dwLowDateTime = (DWORD)( ullValue & 0xffffffff); - ::FileTimeToSystemTime(&ftValue, &stValue); - - // Set new trigger date and time. - ttData.wBeginYear = stValue.wYear; - ttData.wBeginMonth = stValue.wMonth; - ttData.wBeginDay = stValue.wDay; - ttData.wStartHour = wStartTime / 60; - ttData.wStartMinute = wStartTime % 60; - } - - hr = pTrigger->SetTrigger(&ttData); - if (FAILED(hr)) goto finish; - } - - // Save the task. - CComQIPtr pTaskFile(pTask); - if (!pTaskFile) { hr = E_NOINTERFACE; goto finish; } - hr = pTaskFile->Save(NULL, TRUE); - } - -finish: - if (FAILED(hr)) { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_CREATE); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, hr ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - return hr; -} - - -UINT COpTaskCreate::SetFromRecord(MSIHANDLE hInstall, MSIHANDLE hRecord) -{ - UINT uiResult; - int iValue; - ATL::CAtlStringW sFolder; - - uiResult = ::MsiRecordFormatStringW(hInstall, hRecord, 3, m_sApplicationName); - if (uiResult != NO_ERROR) return uiResult; - - uiResult = ::MsiRecordFormatStringW(hInstall, hRecord, 4, m_sParameters); - if (uiResult != NO_ERROR) return uiResult; - - uiResult = ::MsiRecordGetStringW(hRecord, 5, sFolder); - if (uiResult != NO_ERROR) return uiResult; - uiResult = ::MsiGetTargetPathW(hInstall, sFolder, m_sWorkingDirectory); - if (uiResult != NO_ERROR) return uiResult; - if (!m_sWorkingDirectory.IsEmpty() && m_sWorkingDirectory.GetAt(m_sWorkingDirectory.GetLength() - 1) == L'\\') { - // Trim trailing backslash. - m_sWorkingDirectory.Truncate(m_sWorkingDirectory.GetLength() - 1); - } - - uiResult = ::MsiRecordFormatStringW(hInstall, hRecord, 10, m_sAuthor); - if (uiResult != NO_ERROR) return uiResult; - - uiResult = ::MsiRecordFormatStringW(hInstall, hRecord, 11, m_sComment); - if (uiResult != NO_ERROR) return uiResult; - - m_dwFlags = ::MsiRecordGetInteger(hRecord, 6); - if (m_dwFlags == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - - m_dwPriority = ::MsiRecordGetInteger(hRecord, 7); - if (m_dwPriority == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - - uiResult = ::MsiRecordFormatStringW(hInstall, hRecord, 8, m_sAccountName); - if (uiResult != NO_ERROR) return uiResult; - - uiResult = ::MsiRecordFormatStringW(hInstall, hRecord, 9, m_sPassword); - if (uiResult != NO_ERROR) return uiResult; - - iValue = ::MsiRecordGetInteger(hRecord, 12); - m_wIdleMinutes = iValue != MSI_NULL_INTEGER ? (WORD)iValue : 0; - - iValue = ::MsiRecordGetInteger(hRecord, 13); - m_wDeadlineMinutes = iValue != MSI_NULL_INTEGER ? (WORD)iValue : 0; - - m_dwMaxRuntimeMS = ::MsiRecordGetInteger(hRecord, 14); - if (m_dwMaxRuntimeMS == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - - return NO_ERROR; -} - - -UINT COpTaskCreate::SetTriggersFromView(MSIHANDLE hView) -{ - for (;;) { - UINT uiResult; - PMSIHANDLE hRecord; - TASK_TRIGGER ttData = { sizeof(TASK_TRIGGER) }; - ULONGLONG ullValue; - FILETIME ftValue; - SYSTEMTIME stValue; - int iValue; - - // Fetch one record from the view. - uiResult = ::MsiViewFetch(hView, &hRecord); - if (uiResult == ERROR_NO_MORE_ITEMS) return NO_ERROR; - else if (uiResult != NO_ERROR) return uiResult; - - // Get StartDate. - iValue = ::MsiRecordGetInteger(hRecord, 2); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ullValue = ((ULONGLONG)iValue + 138426) * 864000000000; - ftValue.dwHighDateTime = ullValue >> 32; - ftValue.dwLowDateTime = ullValue & 0xffffffff; - if (!::FileTimeToSystemTime(&ftValue, &stValue)) - return ::GetLastError(); - ttData.wBeginYear = stValue.wYear; - ttData.wBeginMonth = stValue.wMonth; - ttData.wBeginDay = stValue.wDay; - - // Get EndDate. - iValue = ::MsiRecordGetInteger(hRecord, 3); - if (iValue != MSI_NULL_INTEGER) { - ullValue = ((ULONGLONG)iValue + 138426) * 864000000000; - ftValue.dwHighDateTime = ullValue >> 32; - ftValue.dwLowDateTime = ullValue & 0xffffffff; - if (!::FileTimeToSystemTime(&ftValue, &stValue)) - return ::GetLastError(); - ttData.wEndYear = stValue.wYear; - ttData.wEndMonth = stValue.wMonth; - ttData.wEndDay = stValue.wDay; - ttData.rgFlags |= TASK_TRIGGER_FLAG_HAS_END_DATE; - } - - // Get StartTime. - iValue = ::MsiRecordGetInteger(hRecord, 4); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.wStartHour = (WORD)(iValue / 60); - ttData.wStartMinute = (WORD)(iValue % 60); - - // Get StartTimeRand. - iValue = ::MsiRecordGetInteger(hRecord, 5); - ttData.wRandomMinutesInterval = iValue != MSI_NULL_INTEGER ? (WORD)iValue : 0; - - // Get MinutesDuration. - iValue = ::MsiRecordGetInteger(hRecord, 6); - ttData.MinutesDuration = iValue != MSI_NULL_INTEGER ? iValue : 0; - - // Get MinutesInterval. - iValue = ::MsiRecordGetInteger(hRecord, 7); - ttData.MinutesInterval = iValue != MSI_NULL_INTEGER ? iValue : 0; - - // Get Flags. - iValue = ::MsiRecordGetInteger(hRecord, 8); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.rgFlags |= iValue & ~TASK_TRIGGER_FLAG_HAS_END_DATE; - - // Get Type. - iValue = ::MsiRecordGetInteger(hRecord, 9); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.TriggerType = (TASK_TRIGGER_TYPE)iValue; - - switch (ttData.TriggerType) { - case TASK_TIME_TRIGGER_DAILY: - // Get DaysInterval. - iValue = ::MsiRecordGetInteger(hRecord, 10); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.Type.Daily.DaysInterval = (WORD)iValue; - break; - - case TASK_TIME_TRIGGER_WEEKLY: - // Get WeeksInterval. - iValue = ::MsiRecordGetInteger(hRecord, 11); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.Type.Weekly.WeeksInterval = (WORD)iValue; - - // Get DaysOfTheWeek. - iValue = ::MsiRecordGetInteger(hRecord, 12); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.Type.Weekly.rgfDaysOfTheWeek = (WORD)iValue; - break; - - case TASK_TIME_TRIGGER_MONTHLYDATE: - // Get DaysOfMonth. - iValue = ::MsiRecordGetInteger(hRecord, 13); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.Type.MonthlyDate.rgfDays = (WORD)iValue; - - // Get MonthsOfYear. - iValue = ::MsiRecordGetInteger(hRecord, 15); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.Type.MonthlyDate.rgfMonths = (WORD)iValue; - break; - - case TASK_TIME_TRIGGER_MONTHLYDOW: - // Get WeekOfMonth. - iValue = ::MsiRecordGetInteger(hRecord, 14); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.Type.MonthlyDOW.wWhichWeek = (WORD)iValue; - - // Get DaysOfTheWeek. - iValue = ::MsiRecordGetInteger(hRecord, 12); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.Type.MonthlyDOW.rgfDaysOfTheWeek = (WORD)iValue; - - // Get MonthsOfYear. - iValue = ::MsiRecordGetInteger(hRecord, 15); - if (iValue == MSI_NULL_INTEGER) return ERROR_INVALID_FIELD; - ttData.Type.MonthlyDOW.rgfMonths = (WORD)iValue; - break; - } - - m_lTriggers.AddTail(ttData); - } - - return NO_ERROR; -} - - -//////////////////////////////////////////////////////////////////////////// -// COpTaskDelete -//////////////////////////////////////////////////////////////////////////// - -COpTaskDelete::COpTaskDelete(LPCWSTR pszTaskName, int iTicks) : - COpTypeSingleString(pszTaskName, iTicks) -{ -} - - -HRESULT COpTaskDelete::Execute(CSession *pSession) -{ - HRESULT hr; - CComPtr pService; - - hr = pService.CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER); - if (SUCCEEDED(hr)) { - // Windows Vista or newer. - CComVariant vEmpty; - CComPtr pTaskFolder; - - // Connect to local task service. - hr = pService->Connect(vEmpty, vEmpty, vEmpty, vEmpty); - if (FAILED(hr)) goto finish; - - // Get task folder. - hr = pService->GetFolder(CComBSTR(L"\\"), &pTaskFolder); - if (FAILED(hr)) goto finish; - - if (pSession->m_bRollbackEnabled) { - CComPtr pTask, pTaskOrig; - CComPtr pTaskDefinition; - CComPtr pPrincipal; - VARIANT_BOOL bEnabled; - TASK_LOGON_TYPE logonType; - CComBSTR sSSDL; - CComVariant vSSDL; - ATL::CAtlStringW sDisplayNameOrig; - UINT uiCount = 0; - - // Get the source task. - hr = pTaskFolder->GetTask(CComBSTR(m_sValue), &pTask); - if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { hr = S_OK; goto finish; } - else if (FAILED(hr)) goto finish; - - // Disable the task. - hr = pTask->get_Enabled(&bEnabled); - if (FAILED(hr)) goto finish; - if (bEnabled) { - // The task is enabled. - - // In case the task disabling fails halfway, try to re-enable it anyway on rollback. - pSession->m_olRollback.AddHead(new COpTaskEnable(m_sValue, TRUE)); - - // Disable it. - hr = pTask->put_Enabled(VARIANT_FALSE); - if (FAILED(hr)) goto finish; - } - - // Get task's definition. - hr = pTask->get_Definition(&pTaskDefinition); - if (FAILED(hr)) goto finish; - - // Get task principal. - hr = pTaskDefinition->get_Principal(&pPrincipal); - if (FAILED(hr)) goto finish; - - // Get task logon type. - hr = pPrincipal->get_LogonType(&logonType); - if (FAILED(hr)) goto finish; - - // Get task security descriptor. - hr = pTask->GetSecurityDescriptor(DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, &sSSDL); - if (hr == HRESULT_FROM_WIN32(ERROR_PRIVILEGE_NOT_HELD)) vSSDL.Clear(); - else if (FAILED(hr)) goto finish; - else { - V_VT (&vSSDL) = VT_BSTR; - V_BSTR(&vSSDL) = sSSDL.Detach(); - } - - // Register a backup copy of task. - do { - sDisplayNameOrig.Format(L"%ls (orig %u)", (LPCWSTR)m_sValue, ++uiCount); - hr = pTaskFolder->RegisterTaskDefinition( - CComBSTR(sDisplayNameOrig), // path - pTaskDefinition, // pDefinition - TASK_CREATE, // flags - vEmpty, // userId - vEmpty, // password - logonType, // logonType - vSSDL, // sddl - &pTaskOrig); // ppTask - } while (hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS)); - // In case the backup copy creation failed halfway, try to delete its remains anyway on rollback. - pSession->m_olRollback.AddHead(new COpTaskDelete(sDisplayNameOrig)); - if (FAILED(hr)) goto finish; - - // Order rollback action to restore from backup copy. - pSession->m_olRollback.AddHead(new COpTaskCopy(sDisplayNameOrig, m_sValue)); - - // Delete it. - hr = pTaskFolder->DeleteTask(CComBSTR(m_sValue), 0); - if (FAILED(hr)) goto finish; - - // Order commit action to delete backup copy. - pSession->m_olCommit.AddTail(new COpTaskDelete(sDisplayNameOrig)); - } else { - // Delete the task. - hr = pTaskFolder->DeleteTask(CComBSTR(m_sValue), 0); - if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) hr = S_OK; - } - } else { - // Windows XP or older. - CComPtr pTaskScheduler; - - // Get task scheduler object. - hr = pTaskScheduler.CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_ALL); - if (FAILED(hr)) goto finish; - - if (pSession->m_bRollbackEnabled) { - CComPtr pTask; - DWORD dwFlags; - ATL::CAtlStringW sDisplayNameOrig; - UINT uiCount = 0; - - // Load the task. - hr = pTaskScheduler->Activate(m_sValue, IID_ITask, (IUnknown**)&pTask); - if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { hr = S_OK; goto finish; } - else if (FAILED(hr)) goto finish; - - // Disable the task. - hr = pTask->GetFlags(&dwFlags); - if (FAILED(hr)) goto finish; - if ((dwFlags & TASK_FLAG_DISABLED) == 0) { - // The task is enabled. - - // In case the task disabling fails halfway, try to re-enable it anyway on rollback. - pSession->m_olRollback.AddHead(new COpTaskEnable(m_sValue, TRUE)); - - // Disable it. - dwFlags |= TASK_FLAG_DISABLED; - hr = pTask->SetFlags(dwFlags); - if (FAILED(hr)) goto finish; - } - - // Prepare a backup copy of task. - do { - sDisplayNameOrig.Format(L"%ls (orig %u)", (LPCWSTR)m_sValue, ++uiCount); - hr = pTaskScheduler->AddWorkItem(sDisplayNameOrig, pTask); - } while (hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS)); - // In case the backup copy creation failed halfway, try to delete its remains anyway on rollback. - pSession->m_olRollback.AddHead(new COpTaskDelete(sDisplayNameOrig)); - if (FAILED(hr)) goto finish; - - // Save the backup copy. - CComQIPtr pTaskFile(pTask); - if (!pTaskFile) { hr = E_NOINTERFACE; goto finish; } - hr = pTaskFile->Save(NULL, TRUE); - if (FAILED(hr)) goto finish; - - // Order rollback action to restore from backup copy. - pSession->m_olRollback.AddHead(new COpTaskCopy(sDisplayNameOrig, m_sValue)); - - // Delete it. - hr = pTaskScheduler->Delete(m_sValue); - if (FAILED(hr)) goto finish; - - // Order commit action to delete backup copy. - pSession->m_olCommit.AddTail(new COpTaskDelete(sDisplayNameOrig)); - } else { - // Delete the task. - hr = pTaskScheduler->Delete(m_sValue); - if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) hr = S_OK; - } - } - -finish: - if (FAILED(hr)) { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_DELETE); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, hr ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - return hr; -} - - -//////////////////////////////////////////////////////////////////////////// -// COpTaskEnable -//////////////////////////////////////////////////////////////////////////// - -COpTaskEnable::COpTaskEnable(LPCWSTR pszTaskName, BOOL bEnable, int iTicks) : - m_bEnable(bEnable), - COpTypeSingleString(pszTaskName, iTicks) -{ -} - - -HRESULT COpTaskEnable::Execute(CSession *pSession) -{ - HRESULT hr; - CComPtr pService; - - hr = pService.CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER); - if (SUCCEEDED(hr)) { - // Windows Vista or newer. - CComVariant vEmpty; - CComPtr pTaskFolder; - CComPtr pTask; - VARIANT_BOOL bEnabled; - - // Connect to local task service. - hr = pService->Connect(vEmpty, vEmpty, vEmpty, vEmpty); - if (FAILED(hr)) goto finish; - - // Get task folder. - hr = pService->GetFolder(CComBSTR(L"\\"), &pTaskFolder); - if (FAILED(hr)) goto finish; - - // Get task. - hr = pTaskFolder->GetTask(CComBSTR(m_sValue), &pTask); - if (FAILED(hr)) goto finish; - - // Get currently enabled state. - hr = pTask->get_Enabled(&bEnabled); - if (FAILED(hr)) goto finish; - - // Modify enable state. - if (m_bEnable) { - if (pSession->m_bRollbackEnabled && !bEnabled) { - // The task is disabled and supposed to be enabled. - // However, we shall enable it at commit to prevent it from accidentally starting in the very installation phase. - pSession->m_olCommit.AddTail(new COpTaskEnable(m_sValue, TRUE)); - hr = S_OK; goto finish; - } else - bEnabled = VARIANT_TRUE; - } else { - if (pSession->m_bRollbackEnabled && bEnabled) { - // The task is enabled and we will disable it now. - // Order rollback to re-enable it. - pSession->m_olRollback.AddHead(new COpTaskEnable(m_sValue, TRUE)); - } - bEnabled = VARIANT_FALSE; - } - - // Set enable/disable. - hr = pTask->put_Enabled(bEnabled); - if (FAILED(hr)) goto finish; - } else { - // Windows XP or older. - CComPtr pTaskScheduler; - CComPtr pTask; - DWORD dwFlags; - - // Get task scheduler object. - hr = pTaskScheduler.CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_ALL); - if (FAILED(hr)) goto finish; - - // Load the task. - hr = pTaskScheduler->Activate(m_sValue, IID_ITask, (IUnknown**)&pTask); - if (FAILED(hr)) goto finish; - - // Get task's current flags. - hr = pTask->GetFlags(&dwFlags); - if (FAILED(hr)) goto finish; - - // Modify flags. - if (m_bEnable) { - if (pSession->m_bRollbackEnabled && (dwFlags & TASK_FLAG_DISABLED)) { - // The task is disabled and supposed to be enabled. - // However, we shall enable it at commit to prevent it from accidentally starting in the very installation phase. - pSession->m_olCommit.AddTail(new COpTaskEnable(m_sValue, TRUE)); - hr = S_OK; goto finish; - } else - dwFlags &= ~TASK_FLAG_DISABLED; - } else { - if (pSession->m_bRollbackEnabled && !(dwFlags & TASK_FLAG_DISABLED)) { - // The task is enabled and we will disable it now. - // Order rollback to re-enable it. - pSession->m_olRollback.AddHead(new COpTaskEnable(m_sValue, TRUE)); - } - dwFlags |= TASK_FLAG_DISABLED; - } - - // Set flags. - hr = pTask->SetFlags(dwFlags); - if (FAILED(hr)) goto finish; - - // Save the task. - CComQIPtr pTaskFile(pTask); - if (!pTaskFile) { hr = E_NOINTERFACE; goto finish; } - hr = pTaskFile->Save(NULL, TRUE); - if (FAILED(hr)) goto finish; - } - -finish: - if (FAILED(hr)) { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_ENABLE); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, hr ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - return hr; -} - - -//////////////////////////////////////////////////////////////////////////// -// COpTaskCopy -//////////////////////////////////////////////////////////////////////////// - -COpTaskCopy::COpTaskCopy(LPCWSTR pszTaskSrc, LPCWSTR pszTaskDst, int iTicks) : - COpTypeSrcDstString(pszTaskSrc, pszTaskDst, iTicks) -{ -} - - -HRESULT COpTaskCopy::Execute(CSession *pSession) -{ - HRESULT hr; - CComPtr pService; - - hr = pService.CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER); - if (SUCCEEDED(hr)) { - // Windows Vista or newer. - CComVariant vEmpty; - CComPtr pTaskFolder; - CComPtr pTask, pTaskOrig; - CComPtr pTaskDefinition; - CComPtr pPrincipal; - TASK_LOGON_TYPE logonType; - CComBSTR sSSDL; - - // Connect to local task service. - hr = pService->Connect(vEmpty, vEmpty, vEmpty, vEmpty); - if (FAILED(hr)) goto finish; - - // Get task folder. - hr = pService->GetFolder(CComBSTR(L"\\"), &pTaskFolder); - if (FAILED(hr)) goto finish; - - // Get the source task. - hr = pTaskFolder->GetTask(CComBSTR(m_sValue1), &pTask); - if (FAILED(hr)) goto finish; - - // Get task's definition. - hr = pTask->get_Definition(&pTaskDefinition); - if (FAILED(hr)) goto finish; - - // Get task principal. - hr = pTaskDefinition->get_Principal(&pPrincipal); - if (FAILED(hr)) goto finish; - - // Get task logon type. - hr = pPrincipal->get_LogonType(&logonType); - if (FAILED(hr)) goto finish; - - // Get task security descriptor. - hr = pTask->GetSecurityDescriptor(DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION, &sSSDL); - if (FAILED(hr)) goto finish; - - // Register a new task. - hr = pTaskFolder->RegisterTaskDefinition( - CComBSTR(m_sValue2), // path - pTaskDefinition, // pDefinition - TASK_CREATE, // flags - vEmpty, // userId - vEmpty, // password - logonType, // logonType - CComVariant(sSSDL), // sddl - &pTaskOrig); // ppTask - if (FAILED(hr)) goto finish; - } else { - // Windows XP or older. - CComPtr pTaskScheduler; - CComPtr pTask; - - // Get task scheduler object. - hr = pTaskScheduler.CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_ALL); - if (FAILED(hr)) goto finish; - - // Load the source task. - hr = pTaskScheduler->Activate(m_sValue1, IID_ITask, (IUnknown**)&pTask); - if (FAILED(hr)) goto finish; - - // Add with different name. - hr = pTaskScheduler->AddWorkItem(m_sValue2, pTask); - if (pSession->m_bRollbackEnabled) { - // Order rollback action to delete the new copy. ITask::AddWorkItem() might made a blank task already. - pSession->m_olRollback.AddHead(new COpTaskDelete(m_sValue2)); - } - if (FAILED(hr)) goto finish; - - // Save the task. - CComQIPtr pTaskFile(pTask); - if (!pTaskFile) { hr = E_NOINTERFACE; goto finish; } - hr = pTaskFile->Save(NULL, TRUE); - if (FAILED(hr)) goto finish; - } - -finish: - if (FAILED(hr)) { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_COPY); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue1 ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue2 ); - ::MsiRecordSetInteger(hRecordProg, 4, hr ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - } - return hr; -} - -} // namespace MSICA diff --git a/MSICALib/OpWLAN.cpp b/MSICALib/OpWLAN.cpp deleted file mode 100644 index 27c3639..0000000 --- a/MSICALib/OpWLAN.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#include "stdafx.h" - -#pragma comment(lib, "wlanapi.lib") - - -namespace MSICA { - -//////////////////////////////////////////////////////////////////////////// -// COpWLANProfile -//////////////////////////////////////////////////////////////////////////// - -COpWLANProfile::COpWLANProfile(const GUID &guidInterface, LPCWSTR pszProfileName, int iTicks) : - COpTypeSingleString(pszProfileName, iTicks), - m_guidInterface(guidInterface) -{ -} - - -//////////////////////////////////////////////////////////////////////////// -// COpWLANProfileDelete -//////////////////////////////////////////////////////////////////////////// - -COpWLANProfileDelete::COpWLANProfileDelete(const GUID &guidInterface, LPCWSTR pszProfileName, int iTicks) : COpWLANProfile(guidInterface, pszProfileName, iTicks) -{ -} - - -HRESULT COpWLANProfileDelete::Execute(CSession *pSession) -{ - DWORD dwError, dwNegotiatedVersion; - HANDLE hClientHandle; - - dwError = ::WlanOpenHandle(2, NULL, &dwNegotiatedVersion, &hClientHandle); - if (dwError == NO_ERROR) { - if (pSession->m_bRollbackEnabled) { - LPWSTR pszProfileXML = NULL; - DWORD dwFlags = 0, dwGrantedAccess = 0; - - // Get profile settings as XML first. - dwError = ::WlanGetProfile(hClientHandle, &m_guidInterface, m_sValue, NULL, &pszProfileXML, &dwFlags, &dwGrantedAccess); - if (dwError == NO_ERROR) { - // Delete the profile. - dwError = ::WlanDeleteProfile(hClientHandle, &m_guidInterface, m_sValue, NULL); - if (dwError == NO_ERROR) { - // Order rollback action to recreate it. - pSession->m_olRollback.AddHead(new COpWLANProfileSet(m_guidInterface, dwFlags, m_sValue, pszProfileXML)); - } - ::WlanFreeMemory(pszProfileXML); - } - } else { - // Delete the profile. - dwError = ::WlanDeleteProfile(hClientHandle, &m_guidInterface, m_sValue, NULL); - } - ::WlanCloseHandle(hClientHandle, NULL); - } - - if (dwError == NO_ERROR || dwError == ERROR_NOT_FOUND) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ATL::CAtlStringW sGUID; - GuidToString(&m_guidInterface, sGUID); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_PROFILE_DELETE); - ::MsiRecordSetStringW(hRecordProg, 2, sGUID ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 4, dwError ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(dwError); - } -} - - -//////////////////////////////////////////////////////////////////////////// -// COpWLANProfileSet -//////////////////////////////////////////////////////////////////////////// - -COpWLANProfileSet::COpWLANProfileSet(const GUID &guidInterface, DWORD dwFlags, LPCWSTR pszProfileName, LPCWSTR pszProfileXML, int iTicks) : - COpWLANProfile(guidInterface, pszProfileName, iTicks), - m_dwFlags(dwFlags), - m_sProfileXML(pszProfileXML) -{ -} - - -HRESULT COpWLANProfileSet::Execute(CSession *pSession) -{ - DWORD dwError, dwNegotiatedVersion; - HANDLE hClientHandle; - WLAN_REASON_CODE wlrc = 0; - - { - // Delete existing profile first. - // Since deleting a profile is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it. - // Don't worry, COpWLANProfileDelete::Execute() returns S_OK if profile doesn't exist. - COpWLANProfileDelete opDelete(m_guidInterface, m_sValue); - HRESULT hr = opDelete.Execute(pSession); - if (FAILED(hr)) return hr; - } - - dwError = ::WlanOpenHandle(2, NULL, &dwNegotiatedVersion, &hClientHandle); - if (dwError == NO_ERROR) { - // Set the profile. - dwError = ::WlanSetProfile(hClientHandle, &m_guidInterface, m_dwFlags, m_sProfileXML, NULL, TRUE, NULL, &wlrc); - if (dwError == NO_ERROR && pSession->m_bRollbackEnabled) { - // Order rollback action to delete it. - pSession->m_olRollback.AddHead(new COpWLANProfileDelete(m_guidInterface, m_sValue)); - } - ::WlanCloseHandle(hClientHandle, NULL); - } - - if (dwError == NO_ERROR) - return S_OK; - else { - PMSIHANDLE hRecordProg = ::MsiCreateRecord(5); - ATL::CAtlStringW sGUID, sReason; - DWORD dwSize = 1024, dwResult; - LPWSTR szBuffer = sReason.GetBuffer(dwSize); - - GuidToString(&m_guidInterface, sGUID); - dwResult = ::WlanReasonCodeToString(wlrc, dwSize, szBuffer, NULL); - sReason.ReleaseBuffer(dwSize); - if (dwResult != NO_ERROR) sReason.Format(L"0x%x", wlrc); - - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_PROFILE_SET); - ::MsiRecordSetStringW(hRecordProg, 2, sGUID ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetStringW(hRecordProg, 4, sReason ); - ::MsiRecordSetInteger(hRecordProg, 5, dwError ); - ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); - return AtlHresultFromWin32(dwError); - } -} - -} // namespace MSICA diff --git a/MSICALib/stdafx.cpp b/MSICALib/stdafx.cpp deleted file mode 100644 index 96a124f..0000000 --- a/MSICALib/stdafx.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#include "stdafx.h" diff --git a/MSICALib/stdafx.h b/MSICALib/stdafx.h deleted file mode 100644 index 7d2eaa9..0000000 --- a/MSICALib/stdafx.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#pragma once - -#include "MSICALib.h" - -#include "../../../lib/atlex/include/atlex/atlcrypt.h" -#include "../../../lib/atlex/include/atlex/atlwin.h" - -#include -#include -#include - -#include -#include -#include -#include -#include diff --git a/include/version.h b/include/version.h deleted file mode 100644 index 3ea4af2..0000000 --- a/include/version.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright 1991-2015 Amebis - - This file is part of MSICA. - - MSICA 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 3 of the License, or - (at your option) any later version. - - MSICA 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 MSICA. If not, see . -*/ - -#define MSICA_VERSION 0x00ff0400 - -#define MSICA_VERSION_MAJ 0 -#define MSICA_VERSION_MIN 255 -#define MSICA_VERSION_REV 4 -#define MSICA_VERSION_BUILD 0 - -#define MSICA_VERSION_STR "1.0-pre4" -#define MSICA_BUILD_YEAR_STR "2015"