Project reorganized

- xgettext.exe dependency for DLL building removed
- MSICALib removed
- Version moved to MSICA.h
- Output folder changed
This commit is contained in:
Simon Rozman 2016-03-11 11:40:19 +01:00
parent f96ea62b70
commit 11a532296a
27 changed files with 61 additions and 5086 deletions

12
.gitignore vendored
View File

@ -13,17 +13,5 @@ MSICA/MSIBuild/*.Icon-2
MSICA/MSIBuild/*.lst MSICA/MSIBuild/*.lst
MSICA/MSIBuild/*.msm MSICA/MSIBuild/*.msm
MSICA/temp 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 /ipch
/output /output

View File

@ -1,14 +1,13 @@
 
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010 # 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 EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MSICA", "MSICA\MSICA.vcxproj", "{A7D9EBC1-1E64-4399-9C88-6692F8742153}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MSICA", "MSICA\MSICA.vcxproj", "{A7D9EBC1-1E64-4399-9C88-6692F8742153}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F3D5C008-7728-49CA-84F1-12C186FC87F8}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{26350A68-2F55-4732-972C-4A5E9077699E}"
ProjectSection(SolutionItems) = preProject
include\version.h = include\version.h
EndProjectSection
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -18,6 +17,14 @@ Global
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution 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.ActiveCfg = Debug|Win32
{8552EE55-177E-4F51-B51B-BAF7D6462CDE}.Debug|Win32.Build.0 = Debug|Win32 {8552EE55-177E-4F51-B51B-BAF7D6462CDE}.Debug|Win32.Build.0 = Debug|Win32
{8552EE55-177E-4F51-B51B-BAF7D6462CDE}.Debug|x64.ActiveCfg = Debug|x64 {8552EE55-177E-4F51-B51B-BAF7D6462CDE}.Debug|x64.ActiveCfg = Debug|x64
@ -38,4 +45,8 @@ Global
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection 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 EndGlobal

View File

@ -15,7 +15,6 @@ msgstr ""
"X-Poedit-Basepath: ..\n" "X-Poedit-Basepath: ..\n"
"X-Generator: Poedit 1.7.4\n" "X-Generator: Poedit 1.7.4\n"
"X-Poedit-SearchPath-0: MSIBuild\n" "X-Poedit-SearchPath-0: MSIBuild\n"
"X-Poedit-SearchPath-1: res\n"
# Language Code and Windows Charset (hexadecimal) # 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. # 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.

View File

@ -20,8 +20,23 @@
#ifndef __MSICA_H__ #ifndef __MSICA_H__
#define __MSICA_H__ #define __MSICA_H__
#include <msi.h> ////////////////////////////////////////////////////////////////////
// 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 <msi.h>
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Calling declaration // Calling declaration
@ -50,4 +65,5 @@ extern "C" {
} }
#endif #endif
#endif // !RC_INVOKED && !MIDL_PASS
#endif // __MSICA_H__ #endif // __MSICA_H__

View File

@ -3,7 +3,7 @@
<ImportGroup Label="PropertySheets" /> <ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup> <PropertyGroup>
<OutDir>..\output\$(Platform).$(Configuration)\</OutDir> <OutDir>..\..\output\$(Platform).$(Configuration)\</OutDir>
<IgnoreImportLibrary>true</IgnoreImportLibrary> <IgnoreImportLibrary>true</IgnoreImportLibrary>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup> <ItemDefinitionGroup>
@ -13,6 +13,9 @@
<ResourceLocalizator> <ResourceLocalizator>
<LanguageCatalogs>L10N\sl_SI.po</LanguageCatalogs> <LanguageCatalogs>L10N\sl_SI.po</LanguageCatalogs>
</ResourceLocalizator> </ResourceLocalizator>
<ClCompile>
<AdditionalIncludeDirectories>..\include;..\..\lib\MSICALib\include;..\..\lib\atlex\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup /> <ItemGroup />
</Project> </Project>

View File

@ -46,35 +46,33 @@
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings" />
<Import Project="$(VCTargetsPath)\BuildCustomizations\rcxgettext.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\common.props" /> <Import Project="..\..\include\common.props" />
<Import Project="..\include\Win32.props" /> <Import Project="..\..\include\Win32.props" />
<Import Project="..\include\Release.props" /> <Import Project="..\..\include\Release.props" />
<Import Project="MSICA.props" /> <Import Project="MSICA.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\common.props" /> <Import Project="..\..\include\common.props" />
<Import Project="..\include\Win32.props" /> <Import Project="..\..\include\Win32.props" />
<Import Project="..\include\Debug.props" /> <Import Project="..\..\include\Debug.props" />
<Import Project="MSICA.props" /> <Import Project="MSICA.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\common.props" /> <Import Project="..\..\include\common.props" />
<Import Project="..\include\x64.props" /> <Import Project="..\..\include\x64.props" />
<Import Project="..\include\Release.props" /> <Import Project="..\..\include\Release.props" />
<Import Project="MSICA.props" /> <Import Project="MSICA.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\common.props" /> <Import Project="..\..\include\common.props" />
<Import Project="..\include\x64.props" /> <Import Project="..\..\include\x64.props" />
<Import Project="..\include\Debug.props" /> <Import Project="..\..\include\Debug.props" />
<Import Project="MSICA.props" /> <Import Project="MSICA.props" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
@ -98,22 +96,17 @@
<ClInclude Include="MSICA.h" /> <ClInclude Include="MSICA.h" />
<ClInclude Include="stdafx.h" /> <ClInclude Include="stdafx.h" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="res\MSICA.rc" />
</ItemGroup>
<ItemGroup>
<ResourceLocalizator Include="res\MSICA.rcx" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="L10N\sl_SI.po" /> <None Include="L10N\sl_SI.po" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\MSICALib\MSICALib.vcxproj"> <ProjectReference Include="..\..\lib\MSICALib\build\MSICALib.vcxproj">
<Project>{8552ee55-177e-4f51-b51b-baf7d6462cde}</Project> <Project>{8552ee55-177e-4f51-b51b-baf7d6462cde}</Project>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="MSICA.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets" />
<Import Project="..\..\..\include\rcxgettext.targets" />
</ImportGroup>
</Project> </Project>

View File

@ -30,19 +30,14 @@
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="res\MSICA.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ResourceLocalizator Include="res\MSICA.rcx">
<Filter>Resource Files</Filter>
</ResourceLocalizator>
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="L10N\sl_SI.po"> <None Include="L10N\sl_SI.po">
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ResourceCompile Include="MSICA.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project> </Project>

Binary file not shown.

View File

@ -32,6 +32,6 @@
#include <time.h> #include <time.h>
#include <wlanapi.h> #include <wlanapi.h>
#include "..\MSICALib\MSICALib.h" #include <MSICALib.h>
#include "MSICA.h" #include "MSICA.h"

View File

@ -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 <simon.rozman@amebis.si>\n"
"Language-Team: Amebis, d. o. o., Kamnik <simon.rozman@amebis.si>\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."

View File

@ -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 <http://www.gnu.org/licenses/>.
#
!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
<<NOKEEP
"En.$(PLAT).$(CFG).Error-2.idtx" : "Makefile" "..\..\..\include\MSIBuildCfg.mak"
-if exist $@ del /f /q $@
move /y << $@ > 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.
<<NOKEEP
"De.$(PLAT).$(CFG).Error-2.idt" : "En.$(PLAT).$(CFG).Error-2.idtx" "..\L10N\de_DE.po"
rcxgettext.exe idtp $@ $**
"En.$(PLAT).$(CFG).Error-2.idt" : "En.$(PLAT).$(CFG).Error-2.idtx"
copy /y $** $@ > 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"

View File

@ -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

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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<COperation*>(sizeof(COperation*))
{
}
void COpList::Free()
{
POSITION pos;
for (pos = GetHeadPosition(); pos;) {
COperation *pOp = GetNext(pos);
COpList *pOpList = dynamic_cast<COpList*>(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

File diff suppressed because it is too large Load Diff

View File

@ -1,102 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="OpCert.cpp" />
<ClCompile Include="MSICALib.cpp" />
<ClCompile Include="OpFile.cpp" />
<ClCompile Include="OpSvc.cpp" />
<ClCompile Include="OpTS.cpp" />
<ClCompile Include="OpReg.cpp" />
<ClCompile Include="OpWLAN.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="MSICALib.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<None Include="L10N\sl_SI.po" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8552EE55-177E-4F51-B51B-BAF7D6462CDE}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>MSICALib</RootNamespace>
<ProjectName>MSICALib</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<UseOfAtl>Static</UseOfAtl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<UseOfAtl>Static</UseOfAtl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<UseOfAtl>Static</UseOfAtl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>Unicode</CharacterSet>
<UseOfAtl>Static</UseOfAtl>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\rcxgettext.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\common.props" />
<Import Project="..\include\Win32.props" />
<Import Project="..\include\Release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\common.props" />
<Import Project="..\include\Win32.props" />
<Import Project="..\include\Debug.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\common.props" />
<Import Project="..\include\x64.props" />
<Import Project="..\include\Release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\include\common.props" />
<Import Project="..\include\x64.props" />
<Import Project="..\include\Debug.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="MSICALib.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OpFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OpTS.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OpReg.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OpCert.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OpSvc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="OpWLAN.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="MSICALib.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="L10N\sl_SI.po">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

File diff suppressed because it is too large Load Diff

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "MSICALib.h"
#include "../../../lib/atlex/include/atlex/atlcrypt.h"
#include "../../../lib/atlex/include/atlex/atlwin.h"
#include <atlbase.h>
#include <atlfile.h>
#include <atlstr.h>
#include <msi.h>
#include <msiquery.h>
#include <mstask.h>
#include <taskschd.h>
#include <wlanapi.h>

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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"