Project reorganized
- xgettext.exe dependency for DLL building removed - MSICALib removed - Version moved to MSICA.h - Output folder changed
This commit is contained in:
parent
f96ea62b70
commit
11a532296a
12
.gitignore
vendored
12
.gitignore
vendored
@ -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
|
||||||
|
21
MSICA.sln
21
MSICA.sln
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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__
|
||||||
|
@ -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>
|
Binary file not shown.
@ -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>
|
@ -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.
@ -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"
|
||||||
|
@ -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."
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
1550
MSICALib/MSICALib.h
1550
MSICALib/MSICALib.h
File diff suppressed because it is too large
Load Diff
@ -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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
1054
MSICALib/OpTS.cpp
1054
MSICALib/OpTS.cpp
File diff suppressed because it is too large
Load Diff
@ -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
|
|
@ -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"
|
|
@ -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>
|
|
@ -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"
|
|
Loading…
x
Reference in New Issue
Block a user