From e713e6695bd531d1021482d454401b86c84f3f2d Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 4 May 2021 22:50:16 -0700 Subject: Move Sql.wixext into ext --- src/.editorconfig | 37 + src/Directory.Build.props | 27 - src/Directory.Build.targets | 51 -- src/Directory.csproj.props | 13 - src/Directory.csproj.targets | 26 - src/Directory.vcxproj.props | 111 --- src/ca/CustomMsiErrors.h | 10 - src/ca/caDecor.h | 13 - src/ca/dllmain.cpp | 26 - src/ca/precomp.h | 28 - src/ca/sca.h | 33 - src/ca/scacost.h | 7 - src/ca/scadb.cpp | 588 --------------- src/ca/scadb.h | 55 -- src/ca/scaexec.cpp | 393 ---------- src/ca/scasql.cpp | 113 --- src/ca/scasqlstr.cpp | 728 ------------------- src/ca/scasqlstr.h | 51 -- src/ca/scauser.cpp | 82 --- src/ca/scauser.h | 40 - src/ca/sqlca.cpp | 3 - src/ca/sqlca.def | 13 - src/ca/sqlca.vcxproj | 83 --- src/ext/Sql/Directory.Build.props | 27 + src/ext/Sql/Directory.Build.targets | 51 ++ src/ext/Sql/Directory.csproj.props | 13 + src/ext/Sql/Directory.csproj.targets | 26 + src/ext/Sql/Directory.vcxproj.props | 111 +++ src/ext/Sql/README.md | 2 + src/ext/Sql/Sql.wixext.sln | 59 ++ src/ext/Sql/appveyor.cmd | 19 + src/ext/Sql/appveyor.yml | 40 + src/ext/Sql/ca/CustomMsiErrors.h | 10 + src/ext/Sql/ca/caDecor.h | 13 + src/ext/Sql/ca/dllmain.cpp | 26 + src/ext/Sql/ca/precomp.h | 28 + src/ext/Sql/ca/sca.h | 33 + src/ext/Sql/ca/scacost.h | 7 + src/ext/Sql/ca/scadb.cpp | 588 +++++++++++++++ src/ext/Sql/ca/scadb.h | 55 ++ src/ext/Sql/ca/scaexec.cpp | 393 ++++++++++ src/ext/Sql/ca/scasql.cpp | 113 +++ src/ext/Sql/ca/scasqlstr.cpp | 728 +++++++++++++++++++ src/ext/Sql/ca/scasqlstr.h | 51 ++ src/ext/Sql/ca/scauser.cpp | 82 +++ src/ext/Sql/ca/scauser.h | 40 + src/ext/Sql/ca/sqlca.cpp | 3 + src/ext/Sql/ca/sqlca.def | 13 + src/ext/Sql/ca/sqlca.vcxproj | 83 +++ src/ext/Sql/nuget.config | 17 + .../test/WixToolsetTest.Sql/SqlExtensionFixture.cs | 36 + .../TestData/UsingSql/Package.en-us.wxl | 11 + .../TestData/UsingSql/Package.wxs | 19 + .../TestData/UsingSql/PackageComponents.wxs | 22 + .../TestData/UsingSql/example.txt | 1 + .../WixToolsetTest.Sql/WixToolsetTest.Sql.csproj | 38 + .../WixToolsetTest.Sql.v3.ncrunchproject | 5 + src/ext/Sql/wix.snk | Bin 0 -> 596 bytes src/ext/Sql/wixext/SqlCompiler.cs | 804 +++++++++++++++++++++ src/ext/Sql/wixext/SqlDecompiler.cs | 514 +++++++++++++ src/ext/Sql/wixext/SqlErrors.cs | 48 ++ src/ext/Sql/wixext/SqlExtensionData.cs | 30 + src/ext/Sql/wixext/SqlExtensionFactory.cs | 18 + src/ext/Sql/wixext/SqlTableDefinitions.cs | 82 +++ .../wixext/SqlWindowsInstallerBackendExtension.cs | 13 + src/ext/Sql/wixext/Symbols/SqlDatabaseSymbol.cs | 103 +++ src/ext/Sql/wixext/Symbols/SqlFileSpecSymbol.cs | 79 ++ src/ext/Sql/wixext/Symbols/SqlScriptSymbol.cs | 87 +++ src/ext/Sql/wixext/Symbols/SqlStringSymbol.cs | 87 +++ src/ext/Sql/wixext/Symbols/SqlSymbolDefinitions.cs | 51 ++ src/ext/Sql/wixext/WixToolset.Sql.wixext.csproj | 30 + src/ext/Sql/wixext/WixToolset.Sql.wixext.nuspec | 25 + src/ext/Sql/wixext/WixToolset.Sql.wixext.targets | 11 + src/ext/Sql/wixlib/SqlExtension.wxi | 35 + src/ext/Sql/wixlib/SqlExtension.wxs | 15 + src/ext/Sql/wixlib/SqlExtension_arm64.wxs | 7 + src/ext/Sql/wixlib/SqlExtension_x64.wxs | 7 + src/ext/Sql/wixlib/SqlExtension_x86.wxs | 7 + src/ext/Sql/wixlib/caDecor.wxi | 39 + src/ext/Sql/wixlib/caerr.wxi | 96 +++ src/ext/Sql/wixlib/de-de.wxl | 16 + src/ext/Sql/wixlib/en-us.wxl | 16 + src/ext/Sql/wixlib/es-es.wxl | 17 + src/ext/Sql/wixlib/ja-jp.wxl | 16 + src/ext/Sql/wixlib/pl-pl.wxl | 16 + src/ext/Sql/wixlib/pt-br.wxl | 16 + src/ext/Sql/wixlib/pt-pt.wxl | 16 + src/ext/Sql/wixlib/sql.v3.ncrunchproject | 5 + src/ext/Sql/wixlib/sql.wixproj | 24 + src/ext/global.json | 5 + src/test/WixToolsetTest.Sql/SqlExtensionFixture.cs | 36 - .../TestData/UsingSql/Package.en-us.wxl | 11 - .../TestData/UsingSql/Package.wxs | 19 - .../TestData/UsingSql/PackageComponents.wxs | 22 - .../TestData/UsingSql/example.txt | 1 - .../WixToolsetTest.Sql/WixToolsetTest.Sql.csproj | 38 - .../WixToolsetTest.Sql.v3.ncrunchproject | 5 - src/version.json | 11 + src/wix.snk | Bin 596 -> 0 bytes src/wixext/SqlCompiler.cs | 804 --------------------- src/wixext/SqlDecompiler.cs | 514 ------------- src/wixext/SqlErrors.cs | 48 -- src/wixext/SqlExtensionData.cs | 30 - src/wixext/SqlExtensionFactory.cs | 18 - src/wixext/SqlTableDefinitions.cs | 82 --- src/wixext/SqlWindowsInstallerBackendExtension.cs | 13 - src/wixext/Symbols/SqlDatabaseSymbol.cs | 103 --- src/wixext/Symbols/SqlFileSpecSymbol.cs | 79 -- src/wixext/Symbols/SqlScriptSymbol.cs | 87 --- src/wixext/Symbols/SqlStringSymbol.cs | 87 --- src/wixext/Symbols/SqlSymbolDefinitions.cs | 51 -- src/wixext/WixToolset.Sql.wixext.csproj | 30 - src/wixext/WixToolset.Sql.wixext.nuspec | 25 - src/wixext/WixToolset.Sql.wixext.targets | 11 - src/wixlib/SqlExtension.wxi | 35 - src/wixlib/SqlExtension.wxs | 15 - src/wixlib/SqlExtension_arm64.wxs | 7 - src/wixlib/SqlExtension_x64.wxs | 7 - src/wixlib/SqlExtension_x86.wxs | 7 - src/wixlib/caDecor.wxi | 39 - src/wixlib/caerr.wxi | 96 --- src/wixlib/de-de.wxl | 16 - src/wixlib/en-us.wxl | 16 - src/wixlib/es-es.wxl | 17 - src/wixlib/ja-jp.wxl | 16 - src/wixlib/pl-pl.wxl | 16 - src/wixlib/pt-br.wxl | 16 - src/wixlib/pt-pt.wxl | 16 - src/wixlib/sql.v3.ncrunchproject | 5 - src/wixlib/sql.wixproj | 24 - 130 files changed, 5146 insertions(+), 4956 deletions(-) create mode 100644 src/.editorconfig delete mode 100644 src/Directory.Build.props delete mode 100644 src/Directory.Build.targets delete mode 100644 src/Directory.csproj.props delete mode 100644 src/Directory.csproj.targets delete mode 100644 src/Directory.vcxproj.props delete mode 100644 src/ca/CustomMsiErrors.h delete mode 100644 src/ca/caDecor.h delete mode 100644 src/ca/dllmain.cpp delete mode 100644 src/ca/precomp.h delete mode 100644 src/ca/sca.h delete mode 100644 src/ca/scacost.h delete mode 100644 src/ca/scadb.cpp delete mode 100644 src/ca/scadb.h delete mode 100644 src/ca/scaexec.cpp delete mode 100644 src/ca/scasql.cpp delete mode 100644 src/ca/scasqlstr.cpp delete mode 100644 src/ca/scasqlstr.h delete mode 100644 src/ca/scauser.cpp delete mode 100644 src/ca/scauser.h delete mode 100644 src/ca/sqlca.cpp delete mode 100644 src/ca/sqlca.def delete mode 100644 src/ca/sqlca.vcxproj create mode 100644 src/ext/Sql/Directory.Build.props create mode 100644 src/ext/Sql/Directory.Build.targets create mode 100644 src/ext/Sql/Directory.csproj.props create mode 100644 src/ext/Sql/Directory.csproj.targets create mode 100644 src/ext/Sql/Directory.vcxproj.props create mode 100644 src/ext/Sql/README.md create mode 100644 src/ext/Sql/Sql.wixext.sln create mode 100644 src/ext/Sql/appveyor.cmd create mode 100644 src/ext/Sql/appveyor.yml create mode 100644 src/ext/Sql/ca/CustomMsiErrors.h create mode 100644 src/ext/Sql/ca/caDecor.h create mode 100644 src/ext/Sql/ca/dllmain.cpp create mode 100644 src/ext/Sql/ca/precomp.h create mode 100644 src/ext/Sql/ca/sca.h create mode 100644 src/ext/Sql/ca/scacost.h create mode 100644 src/ext/Sql/ca/scadb.cpp create mode 100644 src/ext/Sql/ca/scadb.h create mode 100644 src/ext/Sql/ca/scaexec.cpp create mode 100644 src/ext/Sql/ca/scasql.cpp create mode 100644 src/ext/Sql/ca/scasqlstr.cpp create mode 100644 src/ext/Sql/ca/scasqlstr.h create mode 100644 src/ext/Sql/ca/scauser.cpp create mode 100644 src/ext/Sql/ca/scauser.h create mode 100644 src/ext/Sql/ca/sqlca.cpp create mode 100644 src/ext/Sql/ca/sqlca.def create mode 100644 src/ext/Sql/ca/sqlca.vcxproj create mode 100644 src/ext/Sql/nuget.config create mode 100644 src/ext/Sql/test/WixToolsetTest.Sql/SqlExtensionFixture.cs create mode 100644 src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/Package.en-us.wxl create mode 100644 src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/Package.wxs create mode 100644 src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/PackageComponents.wxs create mode 100644 src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/example.txt create mode 100644 src/ext/Sql/test/WixToolsetTest.Sql/WixToolsetTest.Sql.csproj create mode 100644 src/ext/Sql/test/WixToolsetTest.Sql/WixToolsetTest.Sql.v3.ncrunchproject create mode 100644 src/ext/Sql/wix.snk create mode 100644 src/ext/Sql/wixext/SqlCompiler.cs create mode 100644 src/ext/Sql/wixext/SqlDecompiler.cs create mode 100644 src/ext/Sql/wixext/SqlErrors.cs create mode 100644 src/ext/Sql/wixext/SqlExtensionData.cs create mode 100644 src/ext/Sql/wixext/SqlExtensionFactory.cs create mode 100644 src/ext/Sql/wixext/SqlTableDefinitions.cs create mode 100644 src/ext/Sql/wixext/SqlWindowsInstallerBackendExtension.cs create mode 100644 src/ext/Sql/wixext/Symbols/SqlDatabaseSymbol.cs create mode 100644 src/ext/Sql/wixext/Symbols/SqlFileSpecSymbol.cs create mode 100644 src/ext/Sql/wixext/Symbols/SqlScriptSymbol.cs create mode 100644 src/ext/Sql/wixext/Symbols/SqlStringSymbol.cs create mode 100644 src/ext/Sql/wixext/Symbols/SqlSymbolDefinitions.cs create mode 100644 src/ext/Sql/wixext/WixToolset.Sql.wixext.csproj create mode 100644 src/ext/Sql/wixext/WixToolset.Sql.wixext.nuspec create mode 100644 src/ext/Sql/wixext/WixToolset.Sql.wixext.targets create mode 100644 src/ext/Sql/wixlib/SqlExtension.wxi create mode 100644 src/ext/Sql/wixlib/SqlExtension.wxs create mode 100644 src/ext/Sql/wixlib/SqlExtension_arm64.wxs create mode 100644 src/ext/Sql/wixlib/SqlExtension_x64.wxs create mode 100644 src/ext/Sql/wixlib/SqlExtension_x86.wxs create mode 100644 src/ext/Sql/wixlib/caDecor.wxi create mode 100644 src/ext/Sql/wixlib/caerr.wxi create mode 100644 src/ext/Sql/wixlib/de-de.wxl create mode 100644 src/ext/Sql/wixlib/en-us.wxl create mode 100644 src/ext/Sql/wixlib/es-es.wxl create mode 100644 src/ext/Sql/wixlib/ja-jp.wxl create mode 100644 src/ext/Sql/wixlib/pl-pl.wxl create mode 100644 src/ext/Sql/wixlib/pt-br.wxl create mode 100644 src/ext/Sql/wixlib/pt-pt.wxl create mode 100644 src/ext/Sql/wixlib/sql.v3.ncrunchproject create mode 100644 src/ext/Sql/wixlib/sql.wixproj create mode 100644 src/ext/global.json delete mode 100644 src/test/WixToolsetTest.Sql/SqlExtensionFixture.cs delete mode 100644 src/test/WixToolsetTest.Sql/TestData/UsingSql/Package.en-us.wxl delete mode 100644 src/test/WixToolsetTest.Sql/TestData/UsingSql/Package.wxs delete mode 100644 src/test/WixToolsetTest.Sql/TestData/UsingSql/PackageComponents.wxs delete mode 100644 src/test/WixToolsetTest.Sql/TestData/UsingSql/example.txt delete mode 100644 src/test/WixToolsetTest.Sql/WixToolsetTest.Sql.csproj delete mode 100644 src/test/WixToolsetTest.Sql/WixToolsetTest.Sql.v3.ncrunchproject create mode 100644 src/version.json delete mode 100644 src/wix.snk delete mode 100644 src/wixext/SqlCompiler.cs delete mode 100644 src/wixext/SqlDecompiler.cs delete mode 100644 src/wixext/SqlErrors.cs delete mode 100644 src/wixext/SqlExtensionData.cs delete mode 100644 src/wixext/SqlExtensionFactory.cs delete mode 100644 src/wixext/SqlTableDefinitions.cs delete mode 100644 src/wixext/SqlWindowsInstallerBackendExtension.cs delete mode 100644 src/wixext/Symbols/SqlDatabaseSymbol.cs delete mode 100644 src/wixext/Symbols/SqlFileSpecSymbol.cs delete mode 100644 src/wixext/Symbols/SqlScriptSymbol.cs delete mode 100644 src/wixext/Symbols/SqlStringSymbol.cs delete mode 100644 src/wixext/Symbols/SqlSymbolDefinitions.cs delete mode 100644 src/wixext/WixToolset.Sql.wixext.csproj delete mode 100644 src/wixext/WixToolset.Sql.wixext.nuspec delete mode 100644 src/wixext/WixToolset.Sql.wixext.targets delete mode 100644 src/wixlib/SqlExtension.wxi delete mode 100644 src/wixlib/SqlExtension.wxs delete mode 100644 src/wixlib/SqlExtension_arm64.wxs delete mode 100644 src/wixlib/SqlExtension_x64.wxs delete mode 100644 src/wixlib/SqlExtension_x86.wxs delete mode 100644 src/wixlib/caDecor.wxi delete mode 100644 src/wixlib/caerr.wxi delete mode 100644 src/wixlib/de-de.wxl delete mode 100644 src/wixlib/en-us.wxl delete mode 100644 src/wixlib/es-es.wxl delete mode 100644 src/wixlib/ja-jp.wxl delete mode 100644 src/wixlib/pl-pl.wxl delete mode 100644 src/wixlib/pt-br.wxl delete mode 100644 src/wixlib/pt-pt.wxl delete mode 100644 src/wixlib/sql.v3.ncrunchproject delete mode 100644 src/wixlib/sql.wixproj (limited to 'src') diff --git a/src/.editorconfig b/src/.editorconfig new file mode 100644 index 00000000..1d72e683 --- /dev/null +++ b/src/.editorconfig @@ -0,0 +1,37 @@ +# Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. +# +# Do NOT modify this file. Update the canonical version in Home\repo-template\src\.editorconfig +# then update all of the repos. + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.{cs,vb}] +dotnet_sort_system_directives_first = true + +[*.cs] +csharp_indent_case_contents = true : error +csharp_indent_switch_labels = true : error +csharp_new_line_before_open_brace = all +csharp_prefer_braces = true : error +csharp_style_expression_bodied_methods = when_on_single_line : suggestion +csharp_style_expression_bodied_constructors = when_on_single_line : suggestion +csharp_style_expression_bodied_operators = when_on_single_line : suggestion +csharp_style_expression_bodied_properties = when_on_single_line : suggestion +csharp_style_expression_bodied_indexers = when_on_single_line : suggestion +csharp_style_expression_bodied_accessors = when_on_single_line : suggestion +csharp_style_var_elsewhere = true : suggestion +csharp_style_var_for_built_in_types = true : suggestion +csharp_style_var_when_type_is_apparent = true : suggestion +dotnet_style_qualification_for_event = true : error +dotnet_style_qualification_for_field = true : error +dotnet_style_qualification_for_method = true : error +dotnet_style_qualification_for_property = true : error + +[*.targets] +indent_size = 2 diff --git a/src/Directory.Build.props b/src/Directory.Build.props deleted file mode 100644 index b3c6287c..00000000 --- a/src/Directory.Build.props +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - Debug - false - MSB3246 - - $(MSBuildProjectName) - $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\build\)) - $(BaseOutputPath)obj\$(ProjectName)\ - $(BaseOutputPath)$(Configuration)\ - - WiX Toolset Team - WiX Toolset - Copyright (c) .NET Foundation and contributors. All rights reserved. - MS-RL - WiX Toolset - - - - - diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets deleted file mode 100644 index 2fcc765a..00000000 --- a/src/Directory.Build.targets +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - true - $(SolutionPath) - $(NCrunchOriginalSolutionPath) - - - - - - - $([System.IO.File]::ReadAllText($(TheSolutionPath))) - $([System.IO.Path]::GetDirectoryName( $(TheSolutionPath) )) - (?<="[PackageName]", ")(.*)(?=", ") - - - - - - %(Identity) - $(SolutionFileContent.Contains('\%(Identity).csproj')) - - - - - $(RegexPattern.Replace('[PackageName]','%(PackageName)') ) - $([System.Text.RegularExpressions.Regex]::Match('$(SolutionFileContent)', '%(Pattern)')) - - - - - - - - - - - - - - diff --git a/src/Directory.csproj.props b/src/Directory.csproj.props deleted file mode 100644 index 81d24ad1..00000000 --- a/src/Directory.csproj.props +++ /dev/null @@ -1,13 +0,0 @@ - - - - - true - true - $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)wix.snk)) - false - - diff --git a/src/Directory.csproj.targets b/src/Directory.csproj.targets deleted file mode 100644 index c3270426..00000000 --- a/src/Directory.csproj.targets +++ /dev/null @@ -1,26 +0,0 @@ - - - - - false - $(OutputPath)\$(AssemblyName).xml - - - - - $(PrivateRepositoryUrl.Replace('.git','')) - - $(MSBuildProjectName).nuspec - $(OutputPath)..\ - $(NuspecProperties);Id=$(PackageId);Authors=$(Authors);Copyright=$(Copyright);Description=$(Description);Title=$(Title) - $(NuspecProperties);Version=$(PackageVersion);RepositoryCommit=$(SourceRevisionId);RepositoryType=$(RepositoryType);RepositoryUrl=$(PrivateRepositoryUrl);ProjectFolder=$(MSBuildProjectDirectory)\;ProjectUrl=$(ProjectUrl) - true - snupkg - - - - diff --git a/src/Directory.vcxproj.props b/src/Directory.vcxproj.props deleted file mode 100644 index bcf26c57..00000000 --- a/src/Directory.vcxproj.props +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - Win32 - $(BaseIntermediateOutputPath)$(Configuration)\$(Platform)\ - $(OutputPath)$(Platform)\ - - - $(Company) - $(Copyright) - - win-x86;win-x64;win-arm64 - native,Version=v0.0 - - - - $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) - - - - - $(DisableSpecificCompilerWarnings) - Level4 - $(ProjectDir)inc;$(MSBuildProjectDirectory);$(IntDir);$(SqlCESdkIncludePath);$(ProjectAdditionalIncludeDirectories);%(AdditionalIncludeDirectories) - WIN32;_WINDOWS;_WIN32_MSI=500;_WIN32_WINNT=0x0501;$(ArmPreprocessorDefinitions);$(UnicodePreprocessorDefinitions);_CRT_STDIO_LEGACY_WIDE_SPECIFIERS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) - Use - precomp.h - StdCall - true - false - -YlprecompDefine - /Zc:threadSafeInit- %(AdditionalOptions) - true - - - $(ArmPreprocessorDefinitions);%(PreprocessorDefinitions) - $(ProjectAdditionalResourceIncludeDirectories);%(AdditionalIncludeDirectories) - - - $(OutDir);$(AdditionalMultiTargetLibraryPath);$(ProjectAdditionalLibraryDirectories);%(AdditionalLibraryDirectories) - - - $(ProjectSubSystem) - $(ProjectModuleDefinitionFile) - $(ResourceOnlyDll) - true - $(ProjectAdditionalLinkLibraries);advapi32.lib;comdlg32.lib;user32.lib;oleaut32.lib;gdi32.lib;shell32.lib;ole32.lib;version.lib;%(AdditionalDependencies) - $(OutDir);$(AdditionalMultiTargetLibraryPath);$(ArmLibraryDirectories);$(ProjectAdditionalLinkLibraryDirectories);%(AdditionalLibraryDirectories) - /IGNORE:4099 %(AdditionalOptions) - - - - - - NoExtensions - - - - - CDecl - - - - - OldStyle - true - true - - - - - Disabled - EnableFastChecks - _DEBUG;DEBUG;%(PreprocessorDefinitions) - MultiThreadedDebug - - - - - - MultiThreadedDebugDll - - - - - MinSpace - NDEBUG;%(PreprocessorDefinitions) - true - true - MultiThreaded - - - true - true - - - - - - MultiThreadedDll - - - - - $(LinkKeyFile) - $(LinkDelaySign) - - - diff --git a/src/ca/CustomMsiErrors.h b/src/ca/CustomMsiErrors.h deleted file mode 100644 index b568d01c..00000000 --- a/src/ca/CustomMsiErrors.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -#define msierrSQLFailedCreateDatabase 26201 -#define msierrSQLFailedDropDatabase 26202 -#define msierrSQLFailedConnectDatabase 26203 -#define msierrSQLFailedExecString 26204 -#define msierrSQLDatabaseAlreadyExists 26205 - -//Last available is 26250 \ No newline at end of file diff --git a/src/ca/caDecor.h b/src/ca/caDecor.h deleted file mode 100644 index da274650..00000000 --- a/src/ca/caDecor.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - - -#if defined(_M_ARM64) -#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_A64" -#elif defined(_M_AMD64) -#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X64" -#elif defined(_M_ARM) -#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_ARM" -#else -#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X86" -#endif diff --git a/src/ca/dllmain.cpp b/src/ca/dllmain.cpp deleted file mode 100644 index 35ae6d1c..00000000 --- a/src/ca/dllmain.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -#include "precomp.h" - -/******************************************************************** -DllMain - standard entry point for all WiX custom actions - -********************************************************************/ -extern "C" BOOL WINAPI DllMain( - IN HINSTANCE hInst, - IN ULONG ulReason, - IN LPVOID) -{ - switch(ulReason) - { - case DLL_PROCESS_ATTACH: - WcaGlobalInitialize(hInst); - break; - - case DLL_PROCESS_DETACH: - WcaGlobalFinalize(); - break; - } - - return TRUE; -} diff --git a/src/ca/precomp.h b/src/ca/precomp.h deleted file mode 100644 index 266d543c..00000000 --- a/src/ca/precomp.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - - -#if _WIN32_MSI < 150 -#define _WIN32_MSI 150 -#endif - -#include -#include - -#include - -#define MAXUINT USHRT_MAX - -#include "wcautil.h" -#include "fileutil.h" -#include "memutil.h" -#include "strutil.h" -#include "wiutil.h" - -#include "CustomMsiErrors.h" - -#include "sca.h" -#include "scacost.h" -#include "scasqlstr.h" - -#include "caDecor.h" diff --git a/src/ca/sca.h b/src/ca/sca.h deleted file mode 100644 index bc36344e..00000000 --- a/src/ca/sca.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -// Generic action enum. -enum SCA_ACTION -{ - SCA_ACTION_NONE, - SCA_ACTION_INSTALL, - SCA_ACTION_UNINSTALL -}; - -// sql database attributes definitions -enum SCADB_ATTRIBUTES -{ - SCADB_CREATE_ON_INSTALL = 0x00000001, - SCADB_DROP_ON_UNINSTALL = 0x00000002, - SCADB_CONTINUE_ON_ERROR = 0x00000004, - SCADB_DROP_ON_INSTALL = 0x00000008, - SCADB_CREATE_ON_UNINSTALL = 0x00000010, - SCADB_CONFIRM_OVERWRITE = 0x00000020, - SCADB_CREATE_ON_REINSTALL = 0x00000040, - SCADB_DROP_ON_REINSTALL = 0x00000080, -}; - -// sql string/script attributes definitions -enum SCASQL_ATTRIBUTES -{ - SCASQL_EXECUTE_ON_INSTALL = 0x00000001, - SCASQL_EXECUTE_ON_UNINSTALL = 0x00000002, - SCASQL_CONTINUE_ON_ERROR = 0x00000004, - SCASQL_ROLLBACK = 0x00000008, - SCASQL_EXECUTE_ON_REINSTALL = 0x00000010, -}; diff --git a/src/ca/scacost.h b/src/ca/scacost.h deleted file mode 100644 index 6ea7e465..00000000 --- a/src/ca/scacost.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -const UINT COST_SQL_CREATEDB = 10000; -const UINT COST_SQL_DROPDB = 5000; -const UINT COST_SQL_CONNECTDB = 5000; -const UINT COST_SQL_STRING = 5000; diff --git a/src/ca/scadb.cpp b/src/ca/scadb.cpp deleted file mode 100644 index 288b9efe..00000000 --- a/src/ca/scadb.cpp +++ /dev/null @@ -1,588 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -#include "precomp.h" - -// sql queries -LPCWSTR vcsSqlDatabaseQuery = L"SELECT `SqlDb`, `Server`, `Instance`, `Database`, " - L"`Component_`, `User_`, `FileSpec_`, `FileSpec_Log`, `Attributes` " - L"FROM `Wix4SqlDatabase`"; -enum eSqlDatabaseQuery { sdqSqlDb = 1, sdqServer, sdqInstance, sdqDatabase, - sdqComponent, sdqUser, sdqDbFileSpec, sdqLogFileSpec, sdqAttributes }; - -LPCWSTR vcsSqlFileSpecQuery = L"SELECT `FileSpec`, `Name`, `Filename`, `Size`, " - L"`MaxSize`, `GrowthSize` FROM `Wix4SqlFileSpec` WHERE `FileSpec`=?"; -enum eSqlFileSpecQuery { sfsqFileSpec = 1, sfsqName, sfsqFilename, sfsqSize, - sfsqMaxSize, sfsqGrowth }; - - -// prototypes for private helper functions -static HRESULT NewDb( - __out SCA_DB** ppsd - ); - -static SCA_DB* AddDbToList( - __in SCA_DB* psdList, - __in SCA_DB* psd - ); - -static HRESULT SchedCreateDatabase( - __in SCA_DB* psd - ); - -static HRESULT SchedDropDatabase( - __in LPCWSTR wzKey, LPCWSTR wzServer, - __in LPCWSTR wzInstance, - __in LPCWSTR wzDatabase, - __in int iAttributes, - __in BOOL fIntegratedAuth, - __in LPCWSTR wzUser, - __in LPCWSTR wzPassword - ); - -static HRESULT GetFileSpec( - __in MSIHANDLE hViewFileSpec, - __in LPCWSTR wzKey, - __in SQL_FILESPEC* psf - ); - - -HRESULT ScaDbsRead( - __inout SCA_DB** ppsdList, - __in SCA_ACTION saAction - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - PMSIHANDLE hView; - PMSIHANDLE hRec; - PMSIHANDLE hViewFileSpec = NULL; - - LPWSTR pwzData = NULL; - LPWSTR pwzId = NULL; - LPWSTR pwzComponent = NULL; - - SCA_DB* psd = NULL; - - if (S_OK != WcaTableExists(L"Wix4SqlDatabase")) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaCreateDatabase() - Wix4SqlDatabase table not present"); - ExitFunction1(hr = S_FALSE); - } - - if (S_OK == WcaTableExists(L"Wix4SqlFileSpec")) - { - hr = WcaOpenView(vcsSqlFileSpecQuery, &hViewFileSpec); - ExitOnFailure(hr, "failed to open view on Wix4SqlFileSpec table"); - } - - // loop through all the sql databases - hr = WcaOpenExecuteView(vcsSqlDatabaseQuery, &hView); - ExitOnFailure(hr, "Failed to open view on Wix4SqlDatabase table"); - while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) - { - BOOL fHasComponent = FALSE; - INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; - INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; - - hr = WcaGetRecordString(hRec, sdqSqlDb, &pwzId); - ExitOnFailure(hr, "Failed to get Wix4SqlDatabase.SqlDb"); - - hr = WcaGetRecordString(hRec, sdqComponent, &pwzComponent); - ExitOnFailure(hr, "Failed to get Component for database: '%ls'", psd->wzKey); - if (pwzComponent && *pwzComponent) - { - fHasComponent = TRUE; - - er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); - hr = HRESULT_FROM_WIN32(er); - ExitOnFailure(hr, "Failed to get state for component: %ls", pwzComponent); - - // If we're doing install but the Component is not being installed or we're doing - // uninstall but the Component is not being uninstalled, skip it. - if ((WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL != saAction) || - (WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL != saAction)) - { - continue; - } - } - - hr = NewDb(&psd); - ExitOnFailure(hr, "Failed to allocate memory for new database: %D", pwzId); - - hr = ::StringCchCopyW(psd->wzKey, countof(psd->wzKey), pwzId); - ExitOnFailure(hr, "Failed to copy Wix4SqlDatabase.SqlDbL: %ls", pwzId); - - hr = ::StringCchCopyW(psd->wzComponent, countof(psd->wzComponent), pwzComponent); - ExitOnFailure(hr, "Failed to copy Wix4SqlDatabase.Component_: %ls", pwzComponent); - - psd->fHasComponent = fHasComponent; - psd->isInstalled = isInstalled; - psd->isAction = isAction; - - hr = WcaGetRecordFormattedString(hRec, sdqServer, &pwzData); - ExitOnFailure(hr, "Failed to get Server for database: '%ls'", psd->wzKey); - hr = ::StringCchCopyW(psd->wzServer, countof(psd->wzServer), pwzData); - ExitOnFailure(hr, "Failed to copy server string to database object:%ls", pwzData); - - hr = WcaGetRecordFormattedString(hRec, sdqInstance, &pwzData); - ExitOnFailure(hr, "Failed to get Instance for database: '%ls'", psd->wzKey); - hr = ::StringCchCopyW(psd->wzInstance, countof(psd->wzInstance), pwzData); - ExitOnFailure(hr, "Failed to copy instance string to database object:%ls", pwzData); - - hr = WcaGetRecordFormattedString(hRec, sdqDatabase, &pwzData); - ExitOnFailure(hr, "Failed to get Database for database: '%ls'", psd->wzKey); - hr = ::StringCchCopyW(psd->wzDatabase, countof(psd->wzDatabase), pwzData); - ExitOnFailure(hr, "Failed to copy database string to database object:%ls", pwzData); - - hr = WcaGetRecordInteger(hRec, sdqAttributes, &psd->iAttributes); - ExitOnFailure(hr, "Failed to get Wix4SqlDatabase.Attributes"); - - hr = WcaGetRecordFormattedString(hRec, sdqUser, &pwzData); - ExitOnFailure(hr, "Failed to get User record for database: '%ls'", psd->wzKey); - - // if a user was specified - if (*pwzData) - { - psd->fUseIntegratedAuth = FALSE; - hr = ScaGetUser(pwzData, &psd->scau); - ExitOnFailure(hr, "Failed to get user information for database: '%ls'", psd->wzKey); - } - else - { - psd->fUseIntegratedAuth = TRUE; - // integrated authorization doesn't have a User record - } - - hr = WcaGetRecordString(hRec, sdqDbFileSpec, &pwzData); - ExitOnFailure(hr, "Failed to get Database FileSpec for database: '%ls'", psd->wzKey); - - // if a database filespec was specified - if (*pwzData) - { - hr = GetFileSpec(hViewFileSpec, pwzData, &psd->sfDb); - ExitOnFailure(hr, "failed to get FileSpec for: %ls", pwzData); - if (S_OK == hr) - { - psd->fHasDbSpec = TRUE; - } - } - - hr = WcaGetRecordString(hRec, sdqLogFileSpec, &pwzData); - ExitOnFailure(hr, "Failed to get Log FileSpec for database: '%ls'", psd->wzKey); - - // if a log filespec was specified - if (*pwzData) - { - hr = GetFileSpec(hViewFileSpec, pwzData, &psd->sfLog); - ExitOnFailure(hr, "failed to get FileSpec for: %ls", pwzData); - if (S_OK == hr) - { - psd->fHasLogSpec = TRUE; - } - } - - *ppsdList = AddDbToList(*ppsdList, psd); - psd = NULL; // set the db NULL so it doesn't accidentally get freed below - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure occured while processing Wix4SqlDatabase table"); - -LExit: - if (psd) - { - ScaDbsFreeList(psd); - } - - ReleaseStr(pwzComponent); - ReleaseStr(pwzId); - ReleaseStr(pwzData); - return hr; -} - - -SCA_DB* ScaDbsFindDatabase( - __in LPCWSTR wzSqlDb, - __in SCA_DB* psdList - ) -{ - SCA_DB* psd = NULL; - - for (psd = psdList; psd; psd = psd->psdNext) - { - if (0 == lstrcmpW(wzSqlDb, psd->wzKey)) - { - break; - } - } - - return psd; -} - - -HRESULT ScaDbsInstall( - __in SCA_DB* psdList - ) -{ - HRESULT hr = S_FALSE; // assume nothing will be done - SCA_DB* psd = NULL; - - for (psd = psdList; psd; psd = psd->psdNext) - { - if (psd->fHasComponent) - { - // if we need to drop, do that first - if (((psd->iAttributes & SCADB_DROP_ON_INSTALL) && WcaIsInstalling(psd->isInstalled, psd->isAction) && !WcaIsReInstalling(psd->isInstalled, psd->isAction)) || - ((psd->iAttributes & SCADB_DROP_ON_REINSTALL) && WcaIsReInstalling(psd->isInstalled, psd->isAction))) - { - hr = SchedDropDatabase(psd->wzKey, psd->wzServer, psd->wzInstance, psd->wzDatabase, psd->iAttributes, psd->fUseIntegratedAuth, psd->scau.wzName, psd->scau.wzPassword); - ExitOnFailure(hr, "Failed to drop database %ls", psd->wzKey); - } - - // if installing this component - if (((psd->iAttributes & SCADB_CREATE_ON_INSTALL) && WcaIsInstalling(psd->isInstalled, psd->isAction) && !WcaIsReInstalling(psd->isInstalled, psd->isAction)) || - ((psd->iAttributes & SCADB_CREATE_ON_REINSTALL) && WcaIsReInstalling(psd->isInstalled, psd->isAction))) - { - hr = SchedCreateDatabase(psd); - ExitOnFailure(hr, "Failed to ensure database %ls exists", psd->wzKey); - } - } - } - -LExit: - return hr; -} - - -HRESULT ScaDbsUninstall( - __in SCA_DB* psdList - ) -{ - HRESULT hr = S_FALSE; // assume nothing will be done - SCA_DB* psd = NULL; - - for (psd = psdList; psd; psd = psd->psdNext) - { - if (psd->fHasComponent) - { - // if we need to drop do that first - if ((psd->iAttributes & SCADB_DROP_ON_UNINSTALL) && WcaIsUninstalling(psd->isInstalled, psd->isAction)) - { - hr = SchedDropDatabase(psd->wzKey, psd->wzServer, psd->wzInstance, psd->wzDatabase, psd->iAttributes, psd->fUseIntegratedAuth, psd->scau.wzName, psd->scau.wzPassword); - ExitOnFailure(hr, "Failed to drop database %ls", psd->wzKey); - } - - // install the db - if ((psd->iAttributes & SCADB_CREATE_ON_UNINSTALL) && WcaIsUninstalling(psd->isInstalled, psd->isAction)) - { - hr = SchedCreateDatabase(psd); - ExitOnFailure(hr, "Failed to ensure database %ls exists", psd->wzKey); - } - } - } - -LExit: - return hr; -} - - -void ScaDbsFreeList( - __in SCA_DB* psdList - ) -{ - SCA_DB* psdDelete = psdList; - while (psdList) - { - psdDelete = psdList; - psdList = psdList->psdNext; - - MemFree(psdDelete); - } -} - - -// private helper functions - -static HRESULT NewDb( - __out SCA_DB** ppsd - ) -{ - HRESULT hr = S_OK; - SCA_DB* psd = static_cast(MemAlloc(sizeof(SCA_DB), TRUE)); - ExitOnNull(psd, hr, E_OUTOFMEMORY, "failed to allocate memory for new database element"); - - *ppsd = psd; - -LExit: - return hr; -} - - -static SCA_DB* AddDbToList( - __in SCA_DB* psdList, - __in SCA_DB* psd - ) -{ - if (psdList) - { - SCA_DB* psdT = psdList; - while (psdT->psdNext) - { - psdT = psdT->psdNext; - } - - psdT->psdNext = psd; - } - else - { - psdList = psd; - } - - return psdList; -} - - -static HRESULT SchedCreateDatabase( - __in SCA_DB* psd - ) -{ - HRESULT hr = S_OK; - WCHAR* pwzCustomActionData = NULL; - - hr = WcaWriteStringToCaData(psd->wzKey, &pwzCustomActionData); - ExitOnFailure(hr, "failed to add DBKey to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->wzServer, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add server name to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->wzInstance, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add server instance to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->wzDatabase, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add database name to CustomActionData"); - - hr = WcaWriteIntegerToCaData(psd->iAttributes, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add Sql attributes to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->fUseIntegratedAuth ? L"1" : L"0", &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add if integrated connection to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->scau.wzName, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add server user to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->scau.wzPassword, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add user password to CustomActionData"); - - // Check to see if the database exists, if it does not then schedule a rollback - // so we clean up after ourselves if the creation of the database fails or is - // aborted. It is interesting to note that we can do this check here because the - // deferred CustomActions are Impersonated. That means this scheduling action and - // the execution actions all run with the same user context, so it is safe to - // to do the check. - hr = SqlDatabaseExists(psd->wzServer, psd->wzInstance, psd->wzDatabase, psd->fUseIntegratedAuth, psd->scau.wzName, psd->scau.wzPassword, NULL); - if (S_FALSE == hr) - { - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackCreateDatabase"), pwzCustomActionData, COST_SQL_CREATEDB); - ExitOnFailure(hr, "Failed to schedule RollbackCreateDatabase action"); - } - - // database filespec - if (psd->fHasDbSpec) - { - hr = WcaWriteStringToCaData(L"1", &pwzCustomActionData); - ExitOnFailure(hr, "failed to specify that do have db.filespec to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->sfDb.wzName, &pwzCustomActionData); - ExitOnFailure(hr, "failed to add FileSpec.Name to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->sfDb.wzFilename, &pwzCustomActionData); - ExitOnFailure(hr, "failed to add FileSpec.Filename to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->sfDb.wzSize, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add FileSpec.Size to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->sfDb.wzMaxSize, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add FileSpec.MaxSize to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->sfDb.wzGrow, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add FileSpec.GrowthSize to CustomActionData"); - } - else - { - hr = WcaWriteStringToCaData(L"0", &pwzCustomActionData); - ExitOnFailure(hr, "failed to specify that do not have db.filespec to CustomActionData"); - } - - // log filespec - if (psd->fHasLogSpec) - { - hr = WcaWriteStringToCaData(L"1", &pwzCustomActionData); - ExitOnFailure(hr, "failed to specify that do have log.filespec to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->sfLog.wzName, &pwzCustomActionData); - ExitOnFailure(hr, "failed to add FileSpec.Name to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->sfLog.wzFilename, &pwzCustomActionData); - ExitOnFailure(hr, "failed to add FileSpec.Filename to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->sfLog.wzSize, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add FileSpec.Size to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->sfLog.wzMaxSize, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add FileSpec.MaxSize to CustomActionData"); - - hr = WcaWriteStringToCaData(psd->sfLog.wzGrow, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add FileSpec.GrowthSize to CustomActionData"); - } - else - { - hr = WcaWriteStringToCaData(L"0", &pwzCustomActionData); - ExitOnFailure(hr, "failed to specify that do not have log.filespec to CustomActionData"); - } - - // schedule the CreateDatabase action - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CreateDatabase"), pwzCustomActionData, COST_SQL_CREATEDB); - ExitOnFailure(hr, "Failed to schedule CreateDatabase action"); - -LExit: - ReleaseStr(pwzCustomActionData); - return hr; -} - - -HRESULT SchedDropDatabase( - __in LPCWSTR wzKey, - __in LPCWSTR wzServer, - __in LPCWSTR wzInstance, - __in LPCWSTR wzDatabase, - __in int iAttributes, - __in BOOL fIntegratedAuth, - __in LPCWSTR wzUser, - __in LPCWSTR wzPassword - ) -{ - HRESULT hr = S_OK; - WCHAR* pwzCustomActionData = NULL; - - hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); - ExitOnFailure(hr, "failed to add DBKey to CustomActionData"); - - hr = WcaWriteStringToCaData(wzServer, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add server name to CustomActionData"); - - hr = WcaWriteStringToCaData(wzInstance, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add server instance to CustomActionData"); - - hr = WcaWriteStringToCaData(wzDatabase, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add database name to CustomActionData"); - - hr = WcaWriteIntegerToCaData(iAttributes, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add server name to CustomActionData"); - - hr = WcaWriteStringToCaData(fIntegratedAuth ? L"1" : L"0", &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add server name to CustomActionData"); - - hr = WcaWriteStringToCaData(wzUser, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add server user to CustomActionData"); - - hr = WcaWriteStringToCaData(wzPassword, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add user password to CustomActionData"); - - hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"DropDatabase"), pwzCustomActionData, COST_SQL_DROPDB); - ExitOnFailure(hr, "Failed to schedule DropDatabase action"); - -LExit: - ReleaseStr(pwzCustomActionData); - return hr; -} - - -HRESULT GetFileSpec( - __in MSIHANDLE hViewFileSpec, - __in LPCWSTR wzKey, - __in SQL_FILESPEC* psf - ) -{ - HRESULT hr = S_OK; - PMSIHANDLE hRecFileSpec, hRec; - LPWSTR pwzData = NULL; - - // create a record to do the fetch - hRecFileSpec = ::MsiCreateRecord(1); - if (!hRecFileSpec) - { - ExitOnFailure(hr = E_UNEXPECTED, "failed to create record for filespec: %ls", wzKey); - } - hr = WcaSetRecordString(hRecFileSpec, 1, wzKey); - ExitOnFailure(hr, "failed to set record string for filespec: %ls", wzKey); - - // get the FileSpec record - hr = WcaExecuteView(hViewFileSpec, hRecFileSpec); - ExitOnFailure(hr, "failed to execute view on Wix4SqlFileSpec table for filespec: %ls", wzKey); - hr = WcaFetchSingleRecord(hViewFileSpec, &hRec); - ExitOnFailure(hr, "failed to get record for filespec: %ls", wzKey); - - // read the data out of the filespec record - hr = WcaGetRecordFormattedString(hRec, sfsqName, &pwzData); - ExitOnFailure(hr, "Failed to get Wix4SqlFileSpec.Name for filespec: %ls", wzKey); - hr = ::StringCchCopyW(psf->wzName, countof(psf->wzName), pwzData); - ExitOnFailure(hr, "Failed to copy Wix4SqlFileSpec.Name string: %ls", pwzData); - - hr = WcaGetRecordFormattedString(hRec, sfsqFilename, &pwzData); - ExitOnFailure(hr, "Failed to get Wix4SqlFileSpec.Filename for filespec: %ls", wzKey); - if (*pwzData) - { - hr = ::StringCchCopyW(psf->wzFilename, countof(psf->wzFilename), pwzData); - ExitOnFailure(hr, "Failed to copy filename to filespec object: %ls", pwzData); - } - else // if there is no file, skip this FILESPEC - { - WcaLog(LOGMSG_VERBOSE, "No filename specified, skipping FileSpec: %ls", psf->wzName); - ExitFunction1(hr = S_FALSE); - } - - hr = WcaGetRecordFormattedString(hRec, sfsqSize, &pwzData); - ExitOnFailure(hr, "Failed to get Wix4SqlFileSpec.Size for filespec: %ls", wzKey); - if (*pwzData) - { - hr = ::StringCchCopyW(psf->wzSize, countof(psf->wzSize), pwzData); - ExitOnFailure(hr, "Failed to copy size to filespec object: %ls", pwzData); - } - else - { - psf->wzSize[0] = 0; - } - - hr = WcaGetRecordFormattedString(hRec, sfsqMaxSize, &pwzData); - ExitOnFailure(hr, "Failed to get Wix4SqlFileSpec.MaxSize for filespec: %ls", wzKey); - if (*pwzData) - { - hr = ::StringCchCopyW(psf->wzMaxSize, countof(psf->wzMaxSize), pwzData); - ExitOnFailure(hr, "Failed to copy max size to filespec object: %ls", pwzData); - } - else - { - psf->wzMaxSize[0] = 0; - } - - hr = WcaGetRecordFormattedString(hRec, sfsqGrowth, &pwzData); - ExitOnFailure(hr, "Failed to get Wix4SqlFileSpec.GrowthSize for filespec: %ls", wzKey); - if (*pwzData) - { - hr = ::StringCchCopyW(psf->wzGrow, countof(psf->wzGrow), pwzData); - ExitOnFailure(hr, "Failed to copy growth size to filespec object: %ls", pwzData); - } - else - { - psf->wzGrow[0] = 0; - } - - hr = S_OK; - -LExit: - ReleaseStr(pwzData); - return hr; -} diff --git a/src/ca/scadb.h b/src/ca/scadb.h deleted file mode 100644 index 885e84c2..00000000 --- a/src/ca/scadb.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - - -#include "scauser.h" -#include "sqlutil.h" - -struct SCA_DB -{ - // darwin information - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - BOOL fHasComponent; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - INSTALLSTATE isInstalled, isAction; - - WCHAR wzServer[MAX_DARWIN_COLUMN + 1]; - WCHAR wzInstance[MAX_DARWIN_COLUMN + 1]; - WCHAR wzDatabase[MAX_DARWIN_COLUMN + 1]; - - int iAttributes; - - BOOL fUseIntegratedAuth; - SCA_USER scau; - - BOOL fHasDbSpec; - SQL_FILESPEC sfDb; - BOOL fHasLogSpec; - SQL_FILESPEC sfLog; - - SCA_DB* psdNext; -}; - - -// prototypes -HRESULT ScaDbsRead( - __inout SCA_DB** ppsdList, - __in SCA_ACTION saAction - ); - -SCA_DB* ScaDbsFindDatabase( - __in LPCWSTR wzSqlDb, - __in SCA_DB* psdList - ); - -HRESULT ScaDbsInstall( - __in SCA_DB* psdList - ); - -HRESULT ScaDbsUninstall( - __in SCA_DB* psdList - ); - -void ScaDbsFreeList( - __in SCA_DB* psdList - ); diff --git a/src/ca/scaexec.cpp b/src/ca/scaexec.cpp deleted file mode 100644 index b2648361..00000000 --- a/src/ca/scaexec.cpp +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -#include "precomp.h" - - -/******************************************************************** - * CreateDatabase - CUSTOM ACTION ENTRY POINT for creating databases - * - * Input: deferred CustomActionData - DbKey\tServer\tInstance\tDatabase\tAttributes\tIntegratedAuth\tUser\tPassword - * ****************************************************************/ -extern "C" UINT __stdcall CreateDatabase(MSIHANDLE hInstall) -{ -//AssertSz(FALSE, "debug CreateDatabase here"); - UINT er = ERROR_SUCCESS; - HRESULT hr = S_OK; - - LPWSTR pwzData = NULL; - IDBCreateSession* pidbSession = NULL; - BSTR bstrErrorDescription = NULL; - LPWSTR pwz = NULL; - LPWSTR pwzDatabaseKey = NULL; - LPWSTR pwzServer = NULL; - LPWSTR pwzInstance = NULL; - LPWSTR pwzDatabase = NULL; - LPWSTR pwzTemp = NULL; - int iAttributes; - BOOL fIntegratedAuth; - LPWSTR pwzUser = NULL; - LPWSTR pwzPassword = NULL; - BOOL fHaveDbFileSpec = FALSE; - SQL_FILESPEC sfDb; - BOOL fHaveLogFileSpec = FALSE; - SQL_FILESPEC sfLog; - BOOL fInitializedCom = FALSE; - - memset(&sfDb, 0, sizeof(sfDb)); - memset(&sfLog, 0, sizeof(sfLog)); - - hr = WcaInitialize(hInstall, "CreateDatabase"); - ExitOnFailure(hr, "failed to initialize"); - - hr = ::CoInitialize(NULL); - ExitOnFailure(hr, "failed to intialize COM"); - fInitializedCom = TRUE; - - hr = WcaGetProperty( L"CustomActionData", &pwzData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData); - - pwz = pwzData; - hr = WcaReadStringFromCaData(&pwz, &pwzDatabaseKey); // SQL Server - ExitOnFailure(hr, "failed to read database key from custom action data: %ls", pwz); - hr = WcaReadStringFromCaData(&pwz, &pwzServer); // SQL Server - ExitOnFailure(hr, "failed to read server from custom action data: %ls", pwz); - hr = WcaReadStringFromCaData(&pwz, &pwzInstance); // SQL Server Instance - ExitOnFailure(hr, "failed to read server instance from custom action data: %ls", pwz); - hr = WcaReadStringFromCaData(&pwz, &pwzDatabase); // SQL Database - ExitOnFailure(hr, "failed to read server instance from custom action data: %ls", pwz); - hr = WcaReadIntegerFromCaData(&pwz, &iAttributes); - ExitOnFailure(hr, "failed to read attributes from custom action data: %ls", pwz); - hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&fIntegratedAuth)); // Integrated Windows Authentication? - ExitOnFailure(hr, "failed to read integrated auth flag from custom action data: %ls", pwz); - hr = WcaReadStringFromCaData(&pwz, &pwzUser); // SQL User - ExitOnFailure(hr, "failed to read user from custom action data: %ls", pwz); - hr = WcaReadStringFromCaData(&pwz, &pwzPassword); // SQL User Password - ExitOnFailure(hr, "failed to read user from custom action data: %ls", pwz); - - // db file spec - hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&fHaveDbFileSpec)); - ExitOnFailure(hr, "failed to read db file spec from custom action data: %ls", pwz); - - if (fHaveDbFileSpec) - { - hr = WcaReadStringFromCaData(&pwz, &pwzTemp); - ExitOnFailure(hr, "failed to read db file spec name from custom action data: %ls", pwz); - hr = ::StringCchCopyW(sfDb.wzName, countof(sfDb.wzName), pwzTemp); - ExitOnFailure(hr, "failed to copy db file spec name: %ls", pwzTemp); - - hr = WcaReadStringFromCaData(&pwz, &pwzTemp); - ExitOnFailure(hr, "failed to read db file spec filename from custom action data: %ls", pwz); - hr = ::StringCchCopyW(sfDb.wzFilename, countof(sfDb.wzFilename), pwzTemp); - ExitOnFailure(hr, "failed to copy db file spec filename: %ls", pwzTemp); - - hr = WcaReadStringFromCaData(&pwz, &pwzTemp); - ExitOnFailure(hr, "failed to read db file spec size from custom action data: %ls", pwz); - hr = ::StringCchCopyW(sfDb.wzSize, countof(sfDb.wzSize), pwzTemp); - ExitOnFailure(hr, "failed to copy db file spec size value: %ls", pwzTemp); - - hr = WcaReadStringFromCaData(&pwz, &pwzTemp); - ExitOnFailure(hr, "failed to read db file spec max size from custom action data: %ls", pwz); - hr = ::StringCchCopyW(sfDb.wzMaxSize, countof(sfDb.wzMaxSize), pwzTemp); - ExitOnFailure(hr, "failed to copy db file spec max size: %ls", pwzTemp); - - hr = WcaReadStringFromCaData(&pwz, &pwzTemp); - ExitOnFailure(hr, "failed to read db file spec grow from custom action data: %ls", pwz); - hr = ::StringCchCopyW(sfDb.wzGrow, countof(sfDb.wzGrow), pwzTemp); - ExitOnFailure(hr, "failed to copy db file spec grow value: %ls", pwzTemp); - } - - // log file spec - hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&fHaveLogFileSpec)); - ExitOnFailure(hr, "failed to read log file spec from custom action data: %ls", pwz); - if (fHaveLogFileSpec) - { - hr = WcaReadStringFromCaData(&pwz, &pwzTemp); - ExitOnFailure(hr, "failed to read log file spec name from custom action data: %ls", pwz); - hr = ::StringCchCopyW(sfLog.wzName, countof(sfDb.wzName), pwzTemp); - ExitOnFailure(hr, "failed to copy log file spec name: %ls", pwzTemp); - - hr = WcaReadStringFromCaData(&pwz, &pwzTemp); - ExitOnFailure(hr, "failed to read log file spec filename from custom action data: %ls", pwz); - hr = ::StringCchCopyW(sfLog.wzFilename, countof(sfDb.wzFilename), pwzTemp); - ExitOnFailure(hr, "failed to copy log file spec filename: %ls", pwzTemp); - - hr = WcaReadStringFromCaData(&pwz, &pwzTemp); - ExitOnFailure(hr, "failed to read log file spec size from custom action data: %ls", pwz); - hr = ::StringCchCopyW(sfLog.wzSize, countof(sfDb.wzSize), pwzTemp); - ExitOnFailure(hr, "failed to copy log file spec size value: %ls", pwzTemp); - - hr = WcaReadStringFromCaData(&pwz, &pwzTemp); - ExitOnFailure(hr, "failed to read log file spec max size from custom action data: %ls", pwz); - hr = ::StringCchCopyW(sfLog.wzMaxSize, countof(sfDb.wzMaxSize), pwzTemp); - ExitOnFailure(hr, "failed to copy log file spec max size: %ls", pwzTemp); - - hr = WcaReadStringFromCaData(&pwz, &pwzTemp); - ExitOnFailure(hr, "failed to read log file spec grow from custom action data: %ls", pwz); - hr = ::StringCchCopyW(sfLog.wzGrow, countof(sfDb.wzGrow), pwzTemp); - ExitOnFailure(hr, "failed to copy log file spec grow value: %ls", pwzTemp); - } - - if (iAttributes & SCADB_CONFIRM_OVERWRITE) - { - // Check if the database already exists - hr = SqlDatabaseExists(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, &bstrErrorDescription); - MessageExitOnFailure(hr, msierrSQLFailedCreateDatabase, "failed to check if database exists: '%ls', error: %ls", pwzDatabase, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription); - - if (S_OK == hr) // found an existing database, confirm that they don't want to stop before it gets trampled, in no UI case just continue anyways - { - hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); - if (IDNO == WcaErrorMessage(msierrSQLDatabaseAlreadyExists, hr, MB_YESNO, 1, pwzDatabase)) - ExitOnFailure(hr, "failed to initialize"); - } - } - - hr = SqlDatabaseEnsureExists(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, fHaveDbFileSpec ? &sfDb : NULL, fHaveLogFileSpec ? &sfLog : NULL, &bstrErrorDescription); - if ((iAttributes & SCADB_CONTINUE_ON_ERROR) && FAILED(hr)) - { - WcaLog(LOGMSG_STANDARD, "Error 0x%x: failed to create SQL database but continuing, error: %ls, Database: %ls", hr, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzDatabase); - hr = S_OK; - } - MessageExitOnFailure(hr, msierrSQLFailedCreateDatabase, "failed to create to database: '%ls', error: %ls", pwzDatabase, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription); - - hr = WcaProgressMessage(COST_SQL_CONNECTDB, FALSE); -LExit: - ReleaseStr(pwzDatabaseKey); - ReleaseStr(pwzServer); - ReleaseStr(pwzInstance); - ReleaseStr(pwzDatabase); - ReleaseStr(pwzUser); - ReleaseStr(pwzPassword); - ReleaseObject(pidbSession); - ReleaseBSTR(bstrErrorDescription); - - if (fInitializedCom) - { - ::CoUninitialize(); - } - - if (FAILED(hr)) - { - er = ERROR_INSTALL_FAILURE; - } - return WcaFinalize(er); -} - - -/******************************************************************** - DropDatabase - CUSTOM ACTION ENTRY POINT for removing databases - - Input: deferred CustomActionData - DbKey\tServer\tInstance\tDatabase\tAttributes\tIntegratedAuth\tUser\tPassword - * ****************************************************************/ -extern "C" UINT __stdcall DropDatabase(MSIHANDLE hInstall) -{ -//Assert(FALSE); - UINT er = ERROR_SUCCESS; - HRESULT hr = S_OK; - - LPWSTR pwzData = NULL; - IDBCreateSession* pidbSession = NULL; - BSTR bstrErrorDescription = NULL; - LPWSTR pwz = NULL; - LPWSTR pwzDatabaseKey = NULL; - LPWSTR pwzServer = NULL; - LPWSTR pwzInstance = NULL; - LPWSTR pwzDatabase = NULL; - long lAttributes; - BOOL fIntegratedAuth; - LPWSTR pwzUser = NULL; - LPWSTR pwzPassword = NULL; - BOOL fInitializedCom = TRUE; - - hr = WcaInitialize(hInstall, "DropDatabase"); - ExitOnFailure(hr, "failed to initialize"); - - hr = ::CoInitialize(NULL); - ExitOnFailure(hr, "failed to intialize COM"); - fInitializedCom = TRUE; - - hr = WcaGetProperty( L"CustomActionData", &pwzData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData); - - pwz = pwzData; - hr = WcaReadStringFromCaData(&pwz, &pwzDatabaseKey); - ExitOnFailure(hr, "failed to read database key"); - hr = WcaReadStringFromCaData(&pwz, &pwzServer); - ExitOnFailure(hr, "failed to read server"); - hr = WcaReadStringFromCaData(&pwz, &pwzInstance); - ExitOnFailure(hr, "failed to read instance"); - hr = WcaReadStringFromCaData(&pwz, &pwzDatabase); - ExitOnFailure(hr, "failed to read database"); - hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&lAttributes)); - ExitOnFailure(hr, "failed to read attributes"); - hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&fIntegratedAuth)); // Integrated Windows Authentication? - ExitOnFailure(hr, "failed to read integrated auth flag"); - hr = WcaReadStringFromCaData(&pwz, &pwzUser); - ExitOnFailure(hr, "failed to read user"); - hr = WcaReadStringFromCaData(&pwz, &pwzPassword); - ExitOnFailure(hr, "failed to read password"); - - hr = SqlDropDatabase(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, &bstrErrorDescription); - if ((lAttributes & SCADB_CONTINUE_ON_ERROR) && FAILED(hr)) - { - WcaLog(LOGMSG_STANDARD, "Error 0x%x: failed to drop SQL database but continuing, error: %ls, Database: %ls", hr, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzDatabase); - hr = S_OK; - } - MessageExitOnFailure(hr, msierrSQLFailedDropDatabase, "failed to drop to database: '%ls', error: %ls", pwzDatabase, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription); - - hr = WcaProgressMessage(COST_SQL_CONNECTDB, FALSE); - -LExit: - ReleaseStr(pwzDatabaseKey); - ReleaseStr(pwzServer); - ReleaseStr(pwzInstance); - ReleaseStr(pwzDatabase); - ReleaseStr(pwzUser); - ReleaseStr(pwzPassword); - ReleaseStr(pwzData); - ReleaseObject(pidbSession); - ReleaseBSTR(bstrErrorDescription); - - if (fInitializedCom) - { - ::CoUninitialize(); - } - - if (FAILED(hr)) - { - er = ERROR_INSTALL_FAILURE; - } - return WcaFinalize(er); -} - - -/******************************************************************** - ExecuteSqlStrings - CUSTOM ACTION ENTRY POINT for running SQL strings - - Input: deferred CustomActionData - DbKey\tServer\tInstance\tDatabase\tAttributes\tIntegratedAuth\tUser\tPassword\tSQLKey1\tSQLString1\tSQLKey2\tSQLString2\tSQLKey3\tSQLString3\t... - rollback CustomActionData - same as above - * ****************************************************************/ -extern "C" UINT __stdcall ExecuteSqlStrings(MSIHANDLE hInstall) -{ -//Assert(FALSE); - UINT er = ERROR_SUCCESS; - HRESULT hr = S_OK; - HRESULT hrDB = S_OK; - - LPWSTR pwzData = NULL; - IDBCreateSession* pidbSession = NULL; - BSTR bstrErrorDescription = NULL; - - LPWSTR pwz = NULL; - LPWSTR pwzDatabaseKey = NULL; - LPWSTR pwzServer = NULL; - LPWSTR pwzInstance = NULL; - LPWSTR pwzDatabase = NULL; - int iAttributesDB; - int iAttributesSQL; - BOOL fIntegratedAuth; - LPWSTR pwzUser = NULL; - LPWSTR pwzPassword = NULL; - LPWSTR pwzSqlKey = NULL; - LPWSTR pwzSql = NULL; - BOOL fInitializedCom = FALSE; - - hr = WcaInitialize(hInstall, "ExecuteSqlStrings"); - ExitOnFailure(hr, "failed to initialize"); - - hr = ::CoInitialize(NULL); - ExitOnFailure(hr, "failed to intialize COM"); - fInitializedCom = TRUE; - - hr = WcaGetProperty( L"CustomActionData", &pwzData); - ExitOnFailure(hr, "failed to get CustomActionData"); - - WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData); - - pwz = pwzData; - hr = WcaReadStringFromCaData(&pwz, &pwzDatabaseKey); - ExitOnFailure(hr, "failed to read database key"); - hr = WcaReadStringFromCaData(&pwz, &pwzServer); - ExitOnFailure(hr, "failed to read server"); - hr = WcaReadStringFromCaData(&pwz, &pwzInstance); - ExitOnFailure(hr, "failed to read instance"); - hr = WcaReadStringFromCaData(&pwz, &pwzDatabase); - ExitOnFailure(hr, "failed to read database"); - hr = WcaReadIntegerFromCaData(&pwz, &iAttributesDB); - ExitOnFailure(hr, "failed to read attributes"); - hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&fIntegratedAuth)); // Integrated Windows Authentication? - ExitOnFailure(hr, "failed to read integrated auth flag"); - hr = WcaReadStringFromCaData(&pwz, &pwzUser); - ExitOnFailure(hr, "failed to read user"); - hr = WcaReadStringFromCaData(&pwz, &pwzPassword); - ExitOnFailure(hr, "failed to read password"); - - // Store off the result of the connect, only exit if we don't care if the database connection succeeds - // Wait to fail until later to see if we actually have work to do that is not set to continue on error - hrDB = SqlConnectDatabase(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, &pidbSession); - if ((iAttributesDB & SCADB_CONTINUE_ON_ERROR) && FAILED(hrDB)) - { - WcaLog(LOGMSG_STANDARD, "Error 0x%x: continuing after failure to connect to database: %ls", hrDB, pwzDatabase); - ExitFunction1(hr = S_OK); - } - - while (S_OK == hr && S_OK == (hr = WcaReadStringFromCaData(&pwz, &pwzSqlKey))) - { - hr = WcaReadIntegerFromCaData(&pwz, &iAttributesSQL); - ExitOnFailure(hr, "failed to read attributes for SQL string: %ls", pwzSqlKey); - - hr = WcaReadStringFromCaData(&pwz, &pwzSql); - ExitOnFailure(hr, "failed to read SQL string for key: %ls", pwzSqlKey); - - // If the Wix4SqlString row is set to continue on error and the DB connection failed, skip attempting to execute - if ((iAttributesSQL & SCASQL_CONTINUE_ON_ERROR) && FAILED(hrDB)) - { - WcaLog(LOGMSG_STANDARD, "Error 0x%x: continuing after failure to connect to database: %ls", hrDB, pwzDatabase); - continue; - } - - // Now check if the DB connection succeeded - MessageExitOnFailure(hr = hrDB, msierrSQLFailedConnectDatabase, "failed to connect to database: '%ls'", pwzDatabase); - - WcaLog(LOGMSG_VERBOSE, "Executing SQL string: %ls", pwzSql); - hr = SqlSessionExecuteQuery(pidbSession, pwzSql, NULL, NULL, &bstrErrorDescription); - if ((iAttributesSQL & SCASQL_CONTINUE_ON_ERROR) && FAILED(hr)) - { - WcaLog(LOGMSG_STANDARD, "Error 0x%x: failed to execute SQL string but continuing, error: %ls, SQL key: %ls SQL string: %ls", hr, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzSqlKey, pwzSql); - hr = S_OK; - } - MessageExitOnFailure(hr, msierrSQLFailedExecString, "failed to execute SQL string, error: %ls, SQL key: %ls SQL string: %ls", NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzSqlKey, pwzSql); - - WcaProgressMessage(COST_SQL_STRING, FALSE); - } - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - -LExit: - ReleaseStr(pwzDatabaseKey); - ReleaseStr(pwzServer); - ReleaseStr(pwzInstance); - ReleaseStr(pwzDatabase); - ReleaseStr(pwzUser); - ReleaseStr(pwzPassword); - ReleaseStr(pwzData); - - ReleaseBSTR(bstrErrorDescription); - ReleaseObject(pidbSession); - - if (fInitializedCom) - { - ::CoUninitialize(); - } - - if (FAILED(hr)) - { - er = ERROR_INSTALL_FAILURE; - } - return WcaFinalize(er); -} diff --git a/src/ca/scasql.cpp b/src/ca/scasql.cpp deleted file mode 100644 index b0216950..00000000 --- a/src/ca/scasql.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -#include "precomp.h" - -// prototypes -static HRESULT ConfigureSqlData( - __in SCA_ACTION saAction - ); - - -/******************************************************************** -InstallSqlData - CUSTOM ACTION ENTRY POINT for installing - SQL data - -********************************************************************/ -extern "C" UINT __stdcall InstallSqlData( - __in MSIHANDLE hInstall - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - // initialize - hr = WcaInitialize(hInstall, "InstallSqlData"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = ConfigureSqlData(SCA_ACTION_INSTALL); - -LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -/******************************************************************** -UninstallSqlData - CUSTOM ACTION ENTRY POINT for uninstalling - SQL data - -********************************************************************/ -extern "C" UINT __stdcall UninstallSqlData( - __in MSIHANDLE hInstall - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - // initialize - hr = WcaInitialize(hInstall, "UninstallCertificates"); - ExitOnFailure(hr, "Failed to initialize"); - - hr = ConfigureSqlData(SCA_ACTION_UNINSTALL); - -LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - - -static HRESULT ConfigureSqlData( - __in SCA_ACTION saAction - ) -{ - //AssertSz(FALSE, "debug ConfigureSqlData()"); - HRESULT hr = S_OK; - - SCA_DB* psdList = NULL; - SCA_SQLSTR* psssList = NULL; - - // check for the prerequsite tables - if (S_OK != WcaTableExists(L"Wix4SqlDatabase")) - { - WcaLog(LOGMSG_VERBOSE, "skipping SQL CustomAction, no Wix4SqlDatabase table"); - ExitFunction1(hr = S_FALSE); - } - - // read tables - hr = ScaDbsRead(&psdList, saAction); - ExitOnFailure(hr, "failed to read Wix4SqlDatabase table"); - - hr = ScaSqlStrsRead(&psssList, saAction); - ExitOnFailure(hr, "failed to read Wix4SqlString table"); - - hr = ScaSqlStrsReadScripts(&psssList, saAction); - ExitOnFailure(hr, "failed to read Wix4SqlScript table"); - - if (SCA_ACTION_UNINSTALL == saAction) - { - // do uninstall actions (order is important!) - hr = ScaSqlStrsUninstall(psdList, psssList); - ExitOnFailure(hr, "failed to execute uninstall SQL strings"); - - hr = ScaDbsUninstall(psdList); - ExitOnFailure(hr, "failed to uninstall databases"); - } - else - { - // do install actions (order is important!) - hr = ScaDbsInstall(psdList); - ExitOnFailure(hr, "failed to install databases"); - - hr = ScaSqlStrsInstall(psdList, psssList); - ExitOnFailure(hr, "failed to execute install SQL strings, length may be too long, try add GO to break up"); - } - -LExit: - if (psssList) - ScaSqlStrsFreeList(psssList); - - if (psdList) - ScaDbsFreeList(psdList); - - return hr; -} diff --git a/src/ca/scasqlstr.cpp b/src/ca/scasqlstr.cpp deleted file mode 100644 index c3ebd43d..00000000 --- a/src/ca/scasqlstr.cpp +++ /dev/null @@ -1,728 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -#include "precomp.h" - -// sql queries -LPCWSTR vcsSqlStringQuery = L"SELECT `String`, `SqlDb_`, `Component_`,`SQL`,`User_`,`Attributes`,`Sequence` " -L"FROM `Wix4SqlString` ORDER BY `SqlDb_`,`Sequence`"; -enum eSqlStringQuery { ssqSqlString = 1, ssqSqlDb, ssqComponent, ssqSQL, ssqUser, ssqAttributes, ssqSequence }; - -LPCWSTR vcsSqlScriptQuery = L"SELECT `ScriptBinary_`,`Script`, `SqlDb_`, `Component_`,`User_`,`Attributes`,`Sequence` " -L"FROM `Wix4SqlScript` ORDER BY `SqlDb_`,`Sequence`"; -enum eSqlScriptQuery { sscrqScriptBinary=1, sscrqSqlScript, sscrqSqlDb, sscrqComponent, sscrqUser, sscrqAttributes, sscrqSequence }; - -LPCWSTR vcsSqlBinaryScriptQuery = L"SELECT `Data` FROM `Binary` WHERE `Name`=?"; -enum eSqlBinaryScriptQuery { ssbsqData = 1 }; - - -// prototypes for private helper functions -static HRESULT NewSqlStr( - __out SCA_SQLSTR** ppsss - ); -static SCA_SQLSTR* AddSqlStrToList( - __in SCA_SQLSTR* psssList, - __in SCA_SQLSTR* psss - ); -static HRESULT ExecuteStrings( - __in SCA_DB* psdList, - __in SCA_SQLSTR* psssList, - __in BOOL fInstall - ); - -HRESULT ScaSqlStrsRead( - __inout SCA_SQLSTR** ppsssList, - __in SCA_ACTION saAction - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - PMSIHANDLE hView, hRec; - PMSIHANDLE hViewUser, hRecUser; - - LPWSTR pwzComponent = NULL; - LPWSTR pwzData = NULL; - - SCA_SQLSTR* psss = NULL; - - if (S_OK != WcaTableExists(L"Wix4SqlString") || S_OK != WcaTableExists(L"Wix4SqlDatabase")) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaSqlStrsRead() - Wix4SqlString and/or Wix4SqlDatabase table not present"); - ExitFunction1(hr = S_FALSE); - } - - // loop through all the sql strings - hr = WcaOpenExecuteView(vcsSqlStringQuery, &hView); - ExitOnFailure(hr, "Failed to open view on Wix4SqlString table"); - while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) - { - INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; - INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; - - hr = WcaGetRecordString(hRec, ssqComponent, &pwzComponent); - ExitOnFailure(hr, "Failed to get Component for SQL String."); - - er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); - hr = HRESULT_FROM_WIN32(er); - ExitOnFailure(hr, "Failed to get state for component: %ls", pwzComponent); - - // If we're doing install but the Component is not being installed or we're doing - // uninstall but the Component is not being uninstalled, skip it. - if ((WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL != saAction) || - (WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL != saAction)) - { - continue; - } - - hr = NewSqlStr(&psss); - ExitOnFailure(hr, "failed to allocation new sql string element"); - - psss->isInstalled = isInstalled; - psss->isAction = isAction; - - hr = WcaGetRecordString(hRec, ssqSqlString, &pwzData); - ExitOnFailure(hr, "Failed to get Wix4SqlString.String"); - hr = ::StringCchCopyW(psss->wzKey, countof(psss->wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy Wix4SqlString.String: %ls", pwzData); - - // find the database information for this string - hr = WcaGetRecordString(hRec, ssqSqlDb, &pwzData); - ExitOnFailure(hr, "Failed to get Wix4SqlString.SqlDb_ for SqlString '%ls'", psss->wzKey); - hr = ::StringCchCopyW(psss->wzSqlDb, countof(psss->wzSqlDb), pwzData); - ExitOnFailure(hr, "Failed to copy Wix4SqlString.SqlDb_: %ls", pwzData); - - hr = WcaGetRecordInteger(hRec, ssqAttributes, &psss->iAttributes); - ExitOnFailure(hr, "Failed to get Wix4SqlString.Attributes for SqlString '%ls'", psss->wzKey); - - //get the sequence number for the string (note that this will be sequenced with scripts too) - hr = WcaGetRecordInteger(hRec, ssqSequence, &psss->iSequence); - ExitOnFailure(hr, "Failed to get Wix4SqlString.Sequence for SqlString '%ls'", psss->wzKey); - - // execute SQL - hr = WcaGetRecordFormattedString(hRec, ssqSQL, &pwzData); - ExitOnFailure(hr, "Failed to get Wix4SqlString.SQL for SQL string '%ls'", psss->wzKey); - - Assert(!psss->pwzSql); - hr = StrAllocString(&psss->pwzSql, pwzData, 0); - ExitOnFailure(hr, "Failed to alloc string for SQL string '%ls'", psss->wzKey); - - *ppsssList = AddSqlStrToList(*ppsssList, psss); - psss = NULL; // set the sss to NULL so it doesn't get freed below - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure occured while reading Wix4SqlString table"); - -LExit: - // if anything was left over after an error clean it all up - if (psss) - { - ScaSqlStrsFreeList(psss); - } - - ReleaseStr(pwzData); - ReleaseStr(pwzComponent); - - return hr; -} - - -HRESULT ScaSqlStrsReadScripts( - __inout SCA_SQLSTR** ppsssList, - __in SCA_ACTION saAction - ) -{ - HRESULT hr = S_OK; - UINT er = ERROR_SUCCESS; - - PMSIHANDLE hView, hRec; - PMSIHANDLE hViewBinary, hRecBinary; - PMSIHANDLE hViewUser, hRecUser; - - LPWSTR pwzComponent = NULL; - LPWSTR pwzData = NULL; - - BYTE* pbScript = NULL; - DWORD cbRead = 0; - DWORD cbScript = 0; - DWORD cchScript = 0; - - LPWSTR pwzScriptBuffer = NULL; - WCHAR* pwzScript = NULL; - WCHAR* pwz; - DWORD cch = 0; - - SCA_SQLSTR sss; - SCA_SQLSTR* psss = NULL; - - if (S_OK != WcaTableExists(L"Wix4SqlScript") || S_OK != WcaTableExists(L"Wix4SqlDatabase") || S_OK != WcaTableExists(L"Binary")) - { - WcaLog(LOGMSG_VERBOSE, "Skipping ScaSqlStrsReadScripts() - Wix4SqlScript and/or Wix4SqlDatabase table not present"); - ExitFunction1(hr = S_FALSE); - } - - // open a view on the binary table - hr = WcaOpenView(vcsSqlBinaryScriptQuery, &hViewBinary); - ExitOnFailure(hr, "Failed to open view on Binary table for SQL scripts"); - - // loop through all the sql scripts - hr = WcaOpenExecuteView(vcsSqlScriptQuery, &hView); - ExitOnFailure(hr, "Failed to open view on Wix4SqlScript table"); - while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) - { - INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; - INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; - - hr = WcaGetRecordString(hRec, sscrqComponent, &pwzComponent); - ExitOnFailure(hr, "Failed to get Component for SQL Script."); - - er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); - hr = HRESULT_FROM_WIN32(er); - ExitOnFailure(hr, "Failed to get state for component: %ls", pwzComponent); - - // If we're doing install but the Component is not being installed or we're doing - // uninstall but the Component is not being uninstalled, skip it. - if ((WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL != saAction) || - (WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL != saAction)) - { - continue; - } - - ::ZeroMemory(&sss, sizeof(sss)); - - sss.isInstalled = isInstalled; - sss.isAction = isAction; - - hr = WcaGetRecordString(hRec, sscrqSqlScript, &pwzData); - ExitOnFailure(hr, "Failed to get Wix4SqlScript.Script"); - hr = ::StringCchCopyW(sss.wzKey, countof(sss.wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy Wix4SqlScript.Script: %ls", pwzData); - - // find the database information for this string - hr = WcaGetRecordString(hRec, sscrqSqlDb, &pwzData); - ExitOnFailure(hr, "Failed to get Wix4SqlScript.SqlDb_ for SqlScript '%ls'", sss.wzKey); - hr = ::StringCchCopyW(sss.wzSqlDb, countof(sss.wzSqlDb), pwzData); - ExitOnFailure(hr, "Failed to copy Wix4SqlScript.SqlDbb: %ls", pwzData); - - hr = WcaGetRecordInteger(hRec, sscrqAttributes, &sss.iAttributes); - ExitOnFailure(hr, "Failed to get Wix4SqlScript.Attributes for SqlScript '%ls'", sss.wzKey); - - hr = WcaGetRecordInteger(hRec, sscrqSequence, &sss.iSequence); - ExitOnFailure(hr, "Failed to get Wix4SqlScript.Sequence for SqlScript '%ls'", sss.wzKey); - - // get the sql script out of the binary stream - hr = WcaExecuteView(hViewBinary, hRec); - ExitOnFailure(hr, "Failed to open Wix4SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey); - hr = WcaFetchSingleRecord(hViewBinary, &hRecBinary); - ExitOnFailure(hr, "Failed to fetch Wix4SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey); - - // Note: We need to allocate an extra character on the stream to NULL terminate the SQL script. - // The WcaGetRecordStream() function won't let us add extra space on the end of the stream - // so we'll read the stream "the old fashioned way". - //hr = WcaGetRecordStream(hRecBinary, ssbsqData, (BYTE**)&pbScript, &cbScript); - //ExitOnFailure(hr, "Failed to read Wix4SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey); - er = ::MsiRecordReadStream(hRecBinary, ssbsqData, NULL, &cbRead); - hr = HRESULT_FROM_WIN32(er); - ExitOnFailure(hr, "failed to get size of stream"); - - cbScript = cbRead + sizeof(WCHAR); // we may have an ANSI SQL script but leave enough to even NULL terminate a WCHAR string - hr = WcaAllocStream(&pbScript, cbScript); // this will allocate a fully zeroed out buffer so our string will be NULL terminated - ExitOnFailure(hr, "failed to allocate data for stream"); - - er = ::MsiRecordReadStream(hRecBinary, ssbsqData, reinterpret_cast(pbScript), &cbRead); //read the buffer but leave the space for the NULL terminator - hr = HRESULT_FROM_WIN32(er); - ExitOnFailure(hr, "failed to read from stream"); - - Assert(cbRead + sizeof(WCHAR) == cbScript); - - // Check for the UNICODE BOM file marker. - if ((0xFF == *pbScript) && (0xFE == *(pbScript + 1))) - { - // Copy the UNICODE string after the BOM marker (subtract one because we'll skip the BOM marker). - cchScript = (cbScript / sizeof(WCHAR)) - 1; - - hr = StrAllocString(&pwzScriptBuffer, reinterpret_cast(pbScript) + 1, 0); - ExitOnFailure(hr, "Failed to allocate WCHAR string of size '%d'", cchScript); - } - else - { - // We have an ANSI string so convert it to UNICODE. - cchScript = cbScript; - - hr = StrAllocStringAnsi(&pwzScriptBuffer, reinterpret_cast(pbScript), 0, CP_ACP); - ExitOnFailure(hr, "Failed to allocate WCHAR string of size '%d'", cchScript); - } - - // Free the byte buffer since it has been converted to a new UNICODE string, one way or another. - if (pbScript) - { - WcaFreeStream(pbScript); - pbScript = NULL; - } - - // Process the SQL script stripping out unnecessary stuff (like comments) and looking for "GO" statements. - pwzScript = pwzScriptBuffer; - while (cchScript && pwzScript && *pwzScript) - { - // strip off leading whitespace - while (cchScript && *pwzScript && iswspace(*pwzScript)) - { - ++pwzScript; - --cchScript; - } - - Assert(0 <= cchScript); - - // if there is a SQL comment remove it - while (cchScript && L'/' == *pwzScript && L'*' == *(pwzScript + 1)) - { - // go until end of comment - while (cchScript && *pwzScript && *(pwzScript + 1) && !(L'*' == *pwzScript && L'/' == *(pwzScript + 1))) - { - ++pwzScript; - --cchScript; - } - - Assert(2 <= cchScript); - - if (2 <= cchScript) - { - // to account for */ at end - pwzScript+=2; - cchScript-=2; - } - - Assert(0 <= cchScript); - - // strip off any new leading whitespace - while (cchScript && *pwzScript && iswspace(*pwzScript)) - { - ++pwzScript; - --cchScript; - } - } - - while (cchScript && L'-' == *pwzScript && L'-' == *(pwzScript + 1)) - { - // go past the new line character - while (cchScript && *pwzScript && L'\n' != *pwzScript) - { - ++pwzScript; - --cchScript; - } - - Assert(0 <= cchScript); - - if (cchScript && L'\n' == *pwzScript) - { - ++pwzScript; - --cchScript; - } - - Assert(0 <= cchScript); - - // strip off any new leading whitespace - while (cchScript && *pwzScript && iswspace(*pwzScript)) - { - ++pwzScript; - --cchScript; - } - } - - Assert(0 <= cchScript); - - // try to isolate a "GO" keyword and count the characters in the SQL string - pwz = pwzScript; - cch = 0; - while (cchScript && *pwz) - { - //skip past comment lines that might have "go" in them - //note that these comments are "in the middle" of our function, - //or possibly at the end of a line - if (cchScript && L'-' == *pwz && L'-' == *(pwz + 1)) - { - // skip past chars until the new line character - while (cchScript && *pwz && (L'\n' != *pwz)) - { - ++pwz; - ++cch; - --cchScript; - } - } - - //skip past comment lines of form /* to */ that might have "go" in them - //note that these comments are "in the middle" of our function, - //or possibly at the end of a line - if (cchScript && L'/' == *pwz && L'*' == *(pwz + 1)) - { - // skip past chars until the new line character - while (cchScript && *pwz && *(pwz + 1) && !((L'*' == *pwz) && (L'/' == *(pwz + 1)))) - { - ++pwz; - ++cch; - --cchScript; - } - - if (2 <= cchScript) - { - // to account for */ at end - pwz+=2; - cch+=2; - cchScript-=2; - } - } - - // Skip past strings that may be part of the SQL statement that might have a "go" in them - if ( cchScript && L'\'' == *pwz ) - { - ++pwz; - ++cch; - --cchScript; - - // Skip past chars until the end of the string - while ( cchScript && *pwz && !(L'\'' == *pwz) ) - { - ++pwz; - ++cch; - --cchScript; - } - } - - // Skip past strings that may be part of the SQL statement that might have a "go" in them - if ( cchScript && L'\"' == *pwz ) - { - ++pwz; - ++cch; - --cchScript; - - // Skip past chars until the end of the string - while ( cchScript && *pwz && !(L'\"' == *pwz) ) - { - ++pwz; - ++cch; - --cchScript; - } - } - - // if "GO" is isolated - if ((pwzScript == pwz || iswspace(*(pwz - 1))) && - (L'G' == *pwz || L'g' == *pwz) && - (L'O' == *(pwz + 1) || L'o' == *(pwz + 1)) && - (0 == *(pwz + 2) || iswspace(*(pwz + 2)))) - { - *pwz = 0; // null terminate the SQL string on the "G" - pwz += 2; - cchScript -= 2; - break; // found "GO" now add SQL string to list - } - - ++pwz; - ++cch; - --cchScript; - } - - Assert(0 <= cchScript); - - if (0 < cch) //don't process if there's nothing to process - { - // replace tabs with spaces - for (LPWSTR pwzTab = wcsstr(pwzScript, L"\t"); pwzTab; pwzTab = wcsstr(pwzTab, L"\t")) - *pwzTab = ' '; - - // strip off whitespace at the end of the script string - for (LPWSTR pwzErase = pwzScript + cch - 1; pwzScript < pwzErase && iswspace(*pwzErase); pwzErase--) - { - *(pwzErase) = 0; - cch--; - } - } - - if (0 < cch) - { - hr = NewSqlStr(&psss); - ExitOnFailure(hr, "failed to allocate new sql string element"); - - // copy everything over - hr = ::StringCchCopyW(psss->wzKey, countof(psss->wzKey), sss.wzKey); - ExitOnFailure(hr, "Failed to copy key string to sqlstr object"); - hr = ::StringCchCopyW(psss->wzSqlDb, countof(psss->wzSqlDb), sss.wzSqlDb); - ExitOnFailure(hr, "Failed to copy DB string to sqlstr object"); - hr = ::StringCchCopyW(psss->wzComponent, countof(psss->wzComponent), sss.wzComponent); - ExitOnFailure(hr, "Failed to copy component string to sqlstr object"); - psss->isInstalled = sss.isInstalled; - psss->isAction = sss.isAction; - psss->iAttributes = sss.iAttributes; - psss->iSequence = sss.iSequence; - - // cchRequired includes the NULL terminating char - hr = StrAllocString(&psss->pwzSql, pwzScript, 0); - ExitOnFailure(hr, "Failed to allocate string for SQL script: '%ls'", psss->wzKey); - - *ppsssList = AddSqlStrToList(*ppsssList, psss); - psss = NULL; // set the db NULL so it doesn't accidentally get freed below - } - - pwzScript = pwz; - } - } - - if (E_NOMOREITEMS == hr) - { - hr = S_OK; - } - ExitOnFailure(hr, "Failure occured while reading Wix4SqlScript table"); - -LExit: - // if anything was left over after an error clean it all up - if (psss) - { - ScaSqlStrsFreeList(psss); - } - - if (pbScript) - { - WcaFreeStream(pbScript); - } - - ReleaseStr(pwzScriptBuffer); - ReleaseStr(pwzData); - ReleaseStr(pwzComponent); - - return hr; -} - - -HRESULT ScaSqlStrsInstall( - __in SCA_DB* psdList, - __in SCA_SQLSTR* psssList - ) -{ - HRESULT hr = ExecuteStrings(psdList, psssList, TRUE); - - return hr; -} - - -HRESULT ScaSqlStrsUninstall( - __in SCA_DB* psdList, - __in SCA_SQLSTR* psssList - ) -{ - HRESULT hr = ExecuteStrings(psdList, psssList, FALSE); - - return hr; -} - - -void ScaSqlStrsFreeList( - __in SCA_SQLSTR* psssList - ) -{ - SCA_SQLSTR* psssDelete = psssList; - while (psssList) - { - psssDelete = psssList; - psssList = psssList->psssNext; - - if (psssDelete->pwzSql) - { - ReleaseStr(psssDelete->pwzSql); - } - - MemFree(psssDelete); - } -} - - -// private helper functions - -static HRESULT NewSqlStr( - __out SCA_SQLSTR** ppsss - ) -{ - HRESULT hr = S_OK; - SCA_SQLSTR* psss = static_cast(MemAlloc(sizeof(SCA_SQLSTR), TRUE)); - ExitOnNull(psss, hr, E_OUTOFMEMORY, "failed to allocate memory for new sql string element"); - - *ppsss = psss; - -LExit: - return hr; -} - - -static SCA_SQLSTR* AddSqlStrToList( - __in SCA_SQLSTR* psssList, - __in SCA_SQLSTR* psss - ) -{ - Assert(psss); //just checking - - //make certain we have a valid sequence number; note that negatives are technically valid - if (MSI_NULL_INTEGER == psss->iSequence) - { - psss->iSequence = 0; - } - - if (psssList) - { - //list already exists, so insert psss into the list in Sequence order - - //see if we need to change the head, otherwise figure out where in the order it fits - if (psss->iSequence < psssList->iSequence) - { - psss->psssNext = psssList; - psssList = psss; - } - else - { - SCA_SQLSTR* psssT = psssList; - //note that if Sequence numbers are duplicated, as in the case of a sqlscript, - //we need to insert them "at the end" of the group so the sqlfile stays in order - while (psssT->psssNext && (psssT->psssNext->iSequence <= psss->iSequence)) - { - psssT = psssT->psssNext; - } - - //insert our new psss AFTER psssT - psss->psssNext = psssT->psssNext; - psssT->psssNext = psss; - } - } - else - { - psssList = psss; - } - - return psssList; -} - - -static HRESULT ExecuteStrings( - __in SCA_DB* psdList, - __in SCA_SQLSTR* psssList, - __in BOOL fInstall - ) -{ - HRESULT hr = S_FALSE; // assume nothing will be done - - int iRollback = -1; - int iOldRollback = iRollback; - - LPCWSTR wzOldDb = NULL; - UINT uiCost = 0; - WCHAR* pwzCustomActionData = NULL; - WCHAR wzNumber[64]; - - // loop through all sql strings - for (SCA_SQLSTR* psss = psssList; psss; psss = psss->psssNext) - { - // if installing this component - if ((fInstall && (psss->iAttributes & SCASQL_EXECUTE_ON_INSTALL) && WcaIsInstalling(psss->isInstalled, psss->isAction) && !WcaIsReInstalling(psss->isInstalled, psss->isAction)) || - (fInstall && (psss->iAttributes & SCASQL_EXECUTE_ON_REINSTALL) && WcaIsReInstalling(psss->isInstalled, psss->isAction)) || - (!fInstall && (psss->iAttributes & SCASQL_EXECUTE_ON_UNINSTALL) && WcaIsUninstalling(psss->isInstalled, psss->isAction))) - { - // determine if this is a rollback scheduling or normal deferred scheduling - if (psss->iAttributes & SCASQL_ROLLBACK) - { - iRollback = 1; - } - else - { - iRollback = 0; - } - - // if we need to create a connection to a new server\database - if (!wzOldDb || 0 != lstrcmpW(wzOldDb, psss->wzSqlDb) || iOldRollback != iRollback) - { - const SCA_DB* psd = ScaDbsFindDatabase(psss->wzSqlDb, psdList); - if (!psd) - { - ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "failed to find data for Database: %ls", psss->wzSqlDb); - } - - if (-1 == iOldRollback) - { - iOldRollback = iRollback; - } - Assert(0 == iOldRollback || 1 == iOldRollback); - - // if there was custom action data before, schedule the action to write it - if (pwzCustomActionData && *pwzCustomActionData) - { - Assert(pwzCustomActionData && *pwzCustomActionData && uiCost); - - hr = WcaDoDeferredAction(1 == iOldRollback ? CUSTOM_ACTION_DECORATION(L"RollbackExecuteSqlStrings") : CUSTOM_ACTION_DECORATION(L"ExecuteSqlStrings"), pwzCustomActionData, uiCost); - ExitOnFailure(hr, "failed to schedule ExecuteSqlStrings action, rollback: %d", iOldRollback); - iOldRollback = iRollback; - - *pwzCustomActionData = L'\0'; - uiCost = 0; - } - - Assert(!pwzCustomActionData || (pwzCustomActionData && 0 == *pwzCustomActionData) && 0 == uiCost); - - hr = WcaWriteStringToCaData(psd->wzKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add SQL Server Database String to CustomActionData for Database String: %ls", psd->wzKey); - - hr = WcaWriteStringToCaData(psd->wzServer, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add SQL Server to CustomActionData for Database String: %ls", psd->wzKey); - - hr = WcaWriteStringToCaData(psd->wzInstance, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add SQL Instance to CustomActionData for Database String: %ls", psd->wzKey); - - hr = WcaWriteStringToCaData(psd->wzDatabase, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add SQL Database to CustomActionData for Database String: %ls", psd->wzKey); - - hr = ::StringCchPrintfW(wzNumber, countof(wzNumber), L"%d", psd->iAttributes); - ExitOnFailure(hr, "Failed to format attributes integer value to string"); - hr = WcaWriteStringToCaData(wzNumber, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add SQL Attributes to CustomActionData for Database String: %ls", psd->wzKey); - - hr = ::StringCchPrintfW(wzNumber, countof(wzNumber), L"%d", psd->fUseIntegratedAuth); - ExitOnFailure(hr, "Failed to format UseIntegratedAuth integer value to string"); - hr = WcaWriteStringToCaData(wzNumber, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add SQL IntegratedAuth flag to CustomActionData for Database String: %ls", psd->wzKey); - - hr = WcaWriteStringToCaData(psd->scau.wzName, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add SQL UserName to CustomActionData for Database String: %ls", psd->wzKey); - - hr = WcaWriteStringToCaData(psd->scau.wzPassword, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add SQL Password to CustomActionData for Database String: %ls", psd->wzKey); - - uiCost += COST_SQL_CONNECTDB; - - wzOldDb = psss->wzSqlDb; - } - - WcaLog(LOGMSG_VERBOSE, "Scheduling SQL string: %ls", psss->pwzSql); - - hr = WcaWriteStringToCaData(psss->wzKey, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to add SQL Key to CustomActionData for SQL string: %ls", psss->wzKey); - - hr = WcaWriteIntegerToCaData(psss->iAttributes, &pwzCustomActionData); - ExitOnFailure(hr, "failed to add attributes to CustomActionData for SQL string: %ls", psss->wzKey); - - hr = WcaWriteStringToCaData(psss->pwzSql, &pwzCustomActionData); - ExitOnFailure(hr, "Failed to to add SQL Query to CustomActionData for SQL string: %ls", psss->wzKey); - uiCost += COST_SQL_STRING; - } - } - - if (pwzCustomActionData && *pwzCustomActionData) - { - Assert(pwzCustomActionData && *pwzCustomActionData && uiCost); - hr = WcaDoDeferredAction(1 == iRollback ? CUSTOM_ACTION_DECORATION(L"RollbackExecuteSqlStrings") : CUSTOM_ACTION_DECORATION(L"ExecuteSqlStrings"), pwzCustomActionData, uiCost); - ExitOnFailure(hr, "Failed to schedule ExecuteSqlStrings action"); - - *pwzCustomActionData = L'\0'; - uiCost = 0; - } - -LExit: - ReleaseStr(pwzCustomActionData); - - return hr; -} diff --git a/src/ca/scasqlstr.h b/src/ca/scasqlstr.h deleted file mode 100644 index 72c1d770..00000000 --- a/src/ca/scasqlstr.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - - -#include "scadb.h" - -struct SCA_SQLSTR -{ - // darwin information - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - INSTALLSTATE isInstalled, isAction; - - WCHAR wzSqlDb[MAX_DARWIN_COLUMN + 1]; - - BOOL fHasUser; - SCA_USER scau; - - LPWSTR pwzSql; - int iAttributes; - int iSequence; //used to sequence Wix4SqlString and Wix4SqlScript tables together - - SCA_SQLSTR* psssNext; -}; - - -// prototypes -HRESULT ScaSqlStrsRead( - __inout SCA_SQLSTR** ppsssList, - __in SCA_ACTION saAction - ); - -HRESULT ScaSqlStrsReadScripts( - __inout SCA_SQLSTR** ppsssList, - __in SCA_ACTION saAction - ); - -HRESULT ScaSqlStrsInstall( - __in SCA_DB* psdList, - __in SCA_SQLSTR* psssList - ); - -HRESULT ScaSqlStrsUninstall( - __in SCA_DB* psdList, - __in SCA_SQLSTR* psssList - ); - -void ScaSqlStrsFreeList( - __in SCA_SQLSTR* psssList - ); - diff --git a/src/ca/scauser.cpp b/src/ca/scauser.cpp deleted file mode 100644 index 4d74e4d4..00000000 --- a/src/ca/scauser.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -#include "precomp.h" - -LPCWSTR vcsUserQuery = L"SELECT `User`, `Component_`, `Name`, `Domain`, `Password` FROM `User` WHERE `User`=?"; -enum eUserQuery { vuqUser = 1, vuqComponent, vuqName, vuqDomain, vuqPassword }; - - -HRESULT __stdcall ScaGetUser( - __in LPCWSTR wzUser, - __out SCA_USER* pscau - ) -{ - if (!wzUser || !pscau) - { - return E_INVALIDARG; - } - - HRESULT hr = S_OK; - PMSIHANDLE hView, hRec; - - LPWSTR pwzData = NULL; - - // clear struct and bail right away if no user key was passed to search for - ::ZeroMemory(pscau, sizeof(*pscau)); - if (!*wzUser) - { - ExitFunction1(hr = S_OK); - } - - hRec = ::MsiCreateRecord(1); - hr = WcaSetRecordString(hRec, 1, wzUser); - ExitOnFailure(hr, "Failed to look up User"); - - hr = WcaOpenView(vcsUserQuery, &hView); - ExitOnFailure(hr, "Failed to open view on User table"); - hr = WcaExecuteView(hView, hRec); - ExitOnFailure(hr, "Failed to execute view on User table"); - - hr = WcaFetchSingleRecord(hView, &hRec); - if (S_OK == hr) - { - hr = WcaGetRecordString(hRec, vuqUser, &pwzData); - ExitOnFailure(hr, "Failed to get User.User"); - hr = ::StringCchCopyW(pscau->wzKey, countof(pscau->wzKey), pwzData); - ExitOnFailure(hr, "Failed to copy key string to user object"); - - hr = WcaGetRecordString(hRec, vuqComponent, &pwzData); - ExitOnFailure(hr, "Failed to get User.Component_"); - hr = ::StringCchCopyW(pscau->wzComponent, countof(pscau->wzComponent), pwzData); - ExitOnFailure(hr, "Failed to copy component string to user object"); - - hr = WcaGetRecordFormattedString(hRec, vuqName, &pwzData); - ExitOnFailure(hr, "Failed to get User.Name"); - hr = ::StringCchCopyW(pscau->wzName, countof(pscau->wzName), pwzData); - ExitOnFailure(hr, "Failed to copy name string to user object"); - - hr = WcaGetRecordFormattedString(hRec, vuqDomain, &pwzData); - ExitOnFailure(hr, "Failed to get User.Domain"); - hr = ::StringCchCopyW(pscau->wzDomain, countof(pscau->wzDomain), pwzData); - ExitOnFailure(hr, "Failed to copy domain string to user object"); - - hr = WcaGetRecordFormattedString(hRec, vuqPassword, &pwzData); - ExitOnFailure(hr, "Failed to get User.Password"); - hr = ::StringCchCopyW(pscau->wzPassword, countof(pscau->wzPassword), pwzData); - ExitOnFailure(hr, "Failed to copy password string to user object"); - } - else if (E_NOMOREITEMS == hr) - { - WcaLog(LOGMSG_STANDARD, "Error: Cannot locate User.User='%ls'", wzUser); - hr = E_FAIL; - } - else - { - ExitOnFailure(hr, "Error or found multiple matching User rows"); - } - -LExit: - ReleaseStr(pwzData); - - return hr; -} diff --git a/src/ca/scauser.h b/src/ca/scauser.h deleted file mode 100644 index 20e561f2..00000000 --- a/src/ca/scauser.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - - - -// structs -struct SCA_GROUP -{ - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - - WCHAR wzDomain[MAX_DARWIN_COLUMN + 1]; - WCHAR wzName[MAX_DARWIN_COLUMN + 1]; - - SCA_GROUP *psgNext; -}; - -struct SCA_USER -{ - WCHAR wzKey[MAX_DARWIN_KEY + 1]; - WCHAR wzComponent[MAX_DARWIN_KEY + 1]; - INSTALLSTATE isInstalled; - INSTALLSTATE isAction; - - WCHAR wzDomain[MAX_DARWIN_COLUMN + 1]; - WCHAR wzName[MAX_DARWIN_COLUMN + 1]; - WCHAR wzPassword[MAX_DARWIN_COLUMN + 1]; - INT iAttributes; - - SCA_GROUP *psgGroups; - - SCA_USER *psuNext; -}; - - -// prototypes -HRESULT __stdcall ScaGetUser( - __in LPCWSTR wzUser, - __out SCA_USER* pscau - ); diff --git a/src/ca/sqlca.cpp b/src/ca/sqlca.cpp deleted file mode 100644 index 37664a1c..00000000 --- a/src/ca/sqlca.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -#include "precomp.h" diff --git a/src/ca/sqlca.def b/src/ca/sqlca.def deleted file mode 100644 index e899d560..00000000 --- a/src/ca/sqlca.def +++ /dev/null @@ -1,13 +0,0 @@ -; Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - - -LIBRARY "sqlca" - -EXPORTS -;scaexec.cpp - CreateDatabase - DropDatabase - ExecuteSqlStrings -;scasql.cpp - InstallSqlData - UninstallSqlData diff --git a/src/ca/sqlca.vcxproj b/src/ca/sqlca.vcxproj deleted file mode 100644 index 18becc5f..00000000 --- a/src/ca/sqlca.vcxproj +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - Debug - ARM64 - - - Release - ARM64 - - - - - {4DCA6E4B-A1F1-4450-BC2D-94AC20F31935} - DynamicLibrary - sqlca - v142 - Unicode - sqlca.def - WiX Toolset Sql CustomAction - - - - - - - msi.lib - - - - - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/ext/Sql/Directory.Build.props b/src/ext/Sql/Directory.Build.props new file mode 100644 index 00000000..b3c6287c --- /dev/null +++ b/src/ext/Sql/Directory.Build.props @@ -0,0 +1,27 @@ + + + + + + Debug + false + MSB3246 + + $(MSBuildProjectName) + $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)..\build\)) + $(BaseOutputPath)obj\$(ProjectName)\ + $(BaseOutputPath)$(Configuration)\ + + WiX Toolset Team + WiX Toolset + Copyright (c) .NET Foundation and contributors. All rights reserved. + MS-RL + WiX Toolset + + + + + diff --git a/src/ext/Sql/Directory.Build.targets b/src/ext/Sql/Directory.Build.targets new file mode 100644 index 00000000..2fcc765a --- /dev/null +++ b/src/ext/Sql/Directory.Build.targets @@ -0,0 +1,51 @@ + + + + + + + true + $(SolutionPath) + $(NCrunchOriginalSolutionPath) + + + + + + + $([System.IO.File]::ReadAllText($(TheSolutionPath))) + $([System.IO.Path]::GetDirectoryName( $(TheSolutionPath) )) + (?<="[PackageName]", ")(.*)(?=", ") + + + + + + %(Identity) + $(SolutionFileContent.Contains('\%(Identity).csproj')) + + + + + $(RegexPattern.Replace('[PackageName]','%(PackageName)') ) + $([System.Text.RegularExpressions.Regex]::Match('$(SolutionFileContent)', '%(Pattern)')) + + + + + + + + + + + + + + diff --git a/src/ext/Sql/Directory.csproj.props b/src/ext/Sql/Directory.csproj.props new file mode 100644 index 00000000..81d24ad1 --- /dev/null +++ b/src/ext/Sql/Directory.csproj.props @@ -0,0 +1,13 @@ + + + + + true + true + $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)wix.snk)) + false + + diff --git a/src/ext/Sql/Directory.csproj.targets b/src/ext/Sql/Directory.csproj.targets new file mode 100644 index 00000000..c3270426 --- /dev/null +++ b/src/ext/Sql/Directory.csproj.targets @@ -0,0 +1,26 @@ + + + + + false + $(OutputPath)\$(AssemblyName).xml + + + + + $(PrivateRepositoryUrl.Replace('.git','')) + + $(MSBuildProjectName).nuspec + $(OutputPath)..\ + $(NuspecProperties);Id=$(PackageId);Authors=$(Authors);Copyright=$(Copyright);Description=$(Description);Title=$(Title) + $(NuspecProperties);Version=$(PackageVersion);RepositoryCommit=$(SourceRevisionId);RepositoryType=$(RepositoryType);RepositoryUrl=$(PrivateRepositoryUrl);ProjectFolder=$(MSBuildProjectDirectory)\;ProjectUrl=$(ProjectUrl) + true + snupkg + + + + diff --git a/src/ext/Sql/Directory.vcxproj.props b/src/ext/Sql/Directory.vcxproj.props new file mode 100644 index 00000000..bcf26c57 --- /dev/null +++ b/src/ext/Sql/Directory.vcxproj.props @@ -0,0 +1,111 @@ + + + + + + Win32 + $(BaseIntermediateOutputPath)$(Configuration)\$(Platform)\ + $(OutputPath)$(Platform)\ + + + $(Company) + $(Copyright) + + win-x86;win-x64;win-arm64 + native,Version=v0.0 + + + + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + + + + + $(DisableSpecificCompilerWarnings) + Level4 + $(ProjectDir)inc;$(MSBuildProjectDirectory);$(IntDir);$(SqlCESdkIncludePath);$(ProjectAdditionalIncludeDirectories);%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;_WIN32_MSI=500;_WIN32_WINNT=0x0501;$(ArmPreprocessorDefinitions);$(UnicodePreprocessorDefinitions);_CRT_STDIO_LEGACY_WIDE_SPECIFIERS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + Use + precomp.h + StdCall + true + false + -YlprecompDefine + /Zc:threadSafeInit- %(AdditionalOptions) + true + + + $(ArmPreprocessorDefinitions);%(PreprocessorDefinitions) + $(ProjectAdditionalResourceIncludeDirectories);%(AdditionalIncludeDirectories) + + + $(OutDir);$(AdditionalMultiTargetLibraryPath);$(ProjectAdditionalLibraryDirectories);%(AdditionalLibraryDirectories) + + + $(ProjectSubSystem) + $(ProjectModuleDefinitionFile) + $(ResourceOnlyDll) + true + $(ProjectAdditionalLinkLibraries);advapi32.lib;comdlg32.lib;user32.lib;oleaut32.lib;gdi32.lib;shell32.lib;ole32.lib;version.lib;%(AdditionalDependencies) + $(OutDir);$(AdditionalMultiTargetLibraryPath);$(ArmLibraryDirectories);$(ProjectAdditionalLinkLibraryDirectories);%(AdditionalLibraryDirectories) + /IGNORE:4099 %(AdditionalOptions) + + + + + + NoExtensions + + + + + CDecl + + + + + OldStyle + true + true + + + + + Disabled + EnableFastChecks + _DEBUG;DEBUG;%(PreprocessorDefinitions) + MultiThreadedDebug + + + + + + MultiThreadedDebugDll + + + + + MinSpace + NDEBUG;%(PreprocessorDefinitions) + true + true + MultiThreaded + + + true + true + + + + + + MultiThreadedDll + + + + + $(LinkKeyFile) + $(LinkDelaySign) + + + diff --git a/src/ext/Sql/README.md b/src/ext/Sql/README.md new file mode 100644 index 00000000..377c9032 --- /dev/null +++ b/src/ext/Sql/README.md @@ -0,0 +1,2 @@ +# Sql.wixext +WixToolset.Sql.wixext - Sql WiX Toolset Extension diff --git a/src/ext/Sql/Sql.wixext.sln b/src/ext/Sql/Sql.wixext.sln new file mode 100644 index 00000000..cfa9ad4f --- /dev/null +++ b/src/ext/Sql/Sql.wixext.sln @@ -0,0 +1,59 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30204.135 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlca", "src\ca\sqlca.vcxproj", "{4DCA6E4B-A1F1-4450-BC2D-94AC20F31935}" +EndProject +Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "sql", "src\wixlib\sql.wixproj", "{9ACF1A20-D801-45CC-A463-F9D13E506AA3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Sql.wixext", "src\wixext\WixToolset.Sql.wixext.csproj", "{0E05519A-0045-4AEC-BD0C-D9205FF1468F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolsetTest.Sql", "src\test\WixToolsetTest.Sql\WixToolsetTest.Sql.csproj", "{FE72A369-03CA-4EBC-BC7B-A8BBF5BBD3E0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4DCA6E4B-A1F1-4450-BC2D-94AC20F31935}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {4DCA6E4B-A1F1-4450-BC2D-94AC20F31935}.Debug|Any CPU.Build.0 = Debug|Win32 + {4DCA6E4B-A1F1-4450-BC2D-94AC20F31935}.Debug|x86.ActiveCfg = Debug|Win32 + {4DCA6E4B-A1F1-4450-BC2D-94AC20F31935}.Debug|x86.Build.0 = Debug|Win32 + {4DCA6E4B-A1F1-4450-BC2D-94AC20F31935}.Release|Any CPU.ActiveCfg = Release|Win32 + {4DCA6E4B-A1F1-4450-BC2D-94AC20F31935}.Release|x86.ActiveCfg = Release|Win32 + {4DCA6E4B-A1F1-4450-BC2D-94AC20F31935}.Release|x86.Build.0 = Release|Win32 + {9ACF1A20-D801-45CC-A463-F9D13E506AA3}.Debug|Any CPU.ActiveCfg = Debug|x86 + {9ACF1A20-D801-45CC-A463-F9D13E506AA3}.Debug|Any CPU.Build.0 = Debug|x86 + {9ACF1A20-D801-45CC-A463-F9D13E506AA3}.Debug|x86.ActiveCfg = Debug|x86 + {9ACF1A20-D801-45CC-A463-F9D13E506AA3}.Debug|x86.Build.0 = Debug|x86 + {9ACF1A20-D801-45CC-A463-F9D13E506AA3}.Release|Any CPU.ActiveCfg = Release|x86 + {9ACF1A20-D801-45CC-A463-F9D13E506AA3}.Release|x86.ActiveCfg = Release|x86 + {9ACF1A20-D801-45CC-A463-F9D13E506AA3}.Release|x86.Build.0 = Release|x86 + {0E05519A-0045-4AEC-BD0C-D9205FF1468F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E05519A-0045-4AEC-BD0C-D9205FF1468F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E05519A-0045-4AEC-BD0C-D9205FF1468F}.Debug|x86.ActiveCfg = Debug|Any CPU + {0E05519A-0045-4AEC-BD0C-D9205FF1468F}.Debug|x86.Build.0 = Debug|Any CPU + {0E05519A-0045-4AEC-BD0C-D9205FF1468F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E05519A-0045-4AEC-BD0C-D9205FF1468F}.Release|Any CPU.Build.0 = Release|Any CPU + {0E05519A-0045-4AEC-BD0C-D9205FF1468F}.Release|x86.ActiveCfg = Release|Any CPU + {0E05519A-0045-4AEC-BD0C-D9205FF1468F}.Release|x86.Build.0 = Release|Any CPU + {FE72A369-03CA-4EBC-BC7B-A8BBF5BBD3E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE72A369-03CA-4EBC-BC7B-A8BBF5BBD3E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE72A369-03CA-4EBC-BC7B-A8BBF5BBD3E0}.Debug|x86.ActiveCfg = Debug|Any CPU + {FE72A369-03CA-4EBC-BC7B-A8BBF5BBD3E0}.Debug|x86.Build.0 = Debug|Any CPU + {FE72A369-03CA-4EBC-BC7B-A8BBF5BBD3E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE72A369-03CA-4EBC-BC7B-A8BBF5BBD3E0}.Release|Any CPU.Build.0 = Release|Any CPU + {FE72A369-03CA-4EBC-BC7B-A8BBF5BBD3E0}.Release|x86.ActiveCfg = Release|Any CPU + {FE72A369-03CA-4EBC-BC7B-A8BBF5BBD3E0}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DEFEE3BB-E557-4B77-A85C-ECA19D6F5DF5} + EndGlobalSection +EndGlobal diff --git a/src/ext/Sql/appveyor.cmd b/src/ext/Sql/appveyor.cmd new file mode 100644 index 00000000..f21449d2 --- /dev/null +++ b/src/ext/Sql/appveyor.cmd @@ -0,0 +1,19 @@ +@setlocal +@pushd %~dp0 +@set _C=Release +@if /i "%1"=="debug" set _C=Debug + +:: Restore +msbuild -p:Configuration=%_C% -t:Restore || exit /b + +:: Build +msbuild -p:Configuration=%_C% src\test\WixToolsetTest.Sql\WixToolsetTest.Sql.csproj || exit /b + +:: Test +dotnet test -c %_C% --no-build src\test\WixToolsetTest.Sql || exit /b + +:: Pack +msbuild -p:Configuration=%_C% -p:NoBuild=true -t:Pack src\wixext\WixToolset.Sql.wixext.csproj || exit /b + +@popd +@endlocal diff --git a/src/ext/Sql/appveyor.yml b/src/ext/Sql/appveyor.yml new file mode 100644 index 00000000..7c686b04 --- /dev/null +++ b/src/ext/Sql/appveyor.yml @@ -0,0 +1,40 @@ +# Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. +# +# Do NOT modify this file. Update the canonical version in Home\repo-template\src\appveyor.yml +# then update all of the repos. + +branches: + only: + - master + - develop + +image: Visual Studio 2019 + +version: 0.0.0.{build} +configuration: Release + +environment: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + NUGET_XMLDOC_MODE: skip + +build_script: + - appveyor.cmd + +pull_requests: + do_not_increment_build_number: true + +nuget: + disable_publish_on_pr: true + +skip_branch_with_pr: true +skip_tags: true + +artifacts: +- path: build\Release\**\*.nupkg + name: nuget + +notifications: +- provider: Slack + incoming_webhook: + secure: p5xuu+4x2JHfwGDMDe5KcG1k7gZxqYc4jWVwvyNZv5cvkubPD2waJs5yXMAXZNN7Z63/3PWHb7q4KoY/99AjauYa1nZ4c5qYqRPFRBKTHfA= diff --git a/src/ext/Sql/ca/CustomMsiErrors.h b/src/ext/Sql/ca/CustomMsiErrors.h new file mode 100644 index 00000000..b568d01c --- /dev/null +++ b/src/ext/Sql/ca/CustomMsiErrors.h @@ -0,0 +1,10 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#define msierrSQLFailedCreateDatabase 26201 +#define msierrSQLFailedDropDatabase 26202 +#define msierrSQLFailedConnectDatabase 26203 +#define msierrSQLFailedExecString 26204 +#define msierrSQLDatabaseAlreadyExists 26205 + +//Last available is 26250 \ No newline at end of file diff --git a/src/ext/Sql/ca/caDecor.h b/src/ext/Sql/ca/caDecor.h new file mode 100644 index 00000000..da274650 --- /dev/null +++ b/src/ext/Sql/ca/caDecor.h @@ -0,0 +1,13 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#if defined(_M_ARM64) +#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_A64" +#elif defined(_M_AMD64) +#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X64" +#elif defined(_M_ARM) +#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_ARM" +#else +#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X86" +#endif diff --git a/src/ext/Sql/ca/dllmain.cpp b/src/ext/Sql/ca/dllmain.cpp new file mode 100644 index 00000000..35ae6d1c --- /dev/null +++ b/src/ext/Sql/ca/dllmain.cpp @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +/******************************************************************** +DllMain - standard entry point for all WiX custom actions + +********************************************************************/ +extern "C" BOOL WINAPI DllMain( + IN HINSTANCE hInst, + IN ULONG ulReason, + IN LPVOID) +{ + switch(ulReason) + { + case DLL_PROCESS_ATTACH: + WcaGlobalInitialize(hInst); + break; + + case DLL_PROCESS_DETACH: + WcaGlobalFinalize(); + break; + } + + return TRUE; +} diff --git a/src/ext/Sql/ca/precomp.h b/src/ext/Sql/ca/precomp.h new file mode 100644 index 00000000..266d543c --- /dev/null +++ b/src/ext/Sql/ca/precomp.h @@ -0,0 +1,28 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#if _WIN32_MSI < 150 +#define _WIN32_MSI 150 +#endif + +#include +#include + +#include + +#define MAXUINT USHRT_MAX + +#include "wcautil.h" +#include "fileutil.h" +#include "memutil.h" +#include "strutil.h" +#include "wiutil.h" + +#include "CustomMsiErrors.h" + +#include "sca.h" +#include "scacost.h" +#include "scasqlstr.h" + +#include "caDecor.h" diff --git a/src/ext/Sql/ca/sca.h b/src/ext/Sql/ca/sca.h new file mode 100644 index 00000000..bc36344e --- /dev/null +++ b/src/ext/Sql/ca/sca.h @@ -0,0 +1,33 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +// Generic action enum. +enum SCA_ACTION +{ + SCA_ACTION_NONE, + SCA_ACTION_INSTALL, + SCA_ACTION_UNINSTALL +}; + +// sql database attributes definitions +enum SCADB_ATTRIBUTES +{ + SCADB_CREATE_ON_INSTALL = 0x00000001, + SCADB_DROP_ON_UNINSTALL = 0x00000002, + SCADB_CONTINUE_ON_ERROR = 0x00000004, + SCADB_DROP_ON_INSTALL = 0x00000008, + SCADB_CREATE_ON_UNINSTALL = 0x00000010, + SCADB_CONFIRM_OVERWRITE = 0x00000020, + SCADB_CREATE_ON_REINSTALL = 0x00000040, + SCADB_DROP_ON_REINSTALL = 0x00000080, +}; + +// sql string/script attributes definitions +enum SCASQL_ATTRIBUTES +{ + SCASQL_EXECUTE_ON_INSTALL = 0x00000001, + SCASQL_EXECUTE_ON_UNINSTALL = 0x00000002, + SCASQL_CONTINUE_ON_ERROR = 0x00000004, + SCASQL_ROLLBACK = 0x00000008, + SCASQL_EXECUTE_ON_REINSTALL = 0x00000010, +}; diff --git a/src/ext/Sql/ca/scacost.h b/src/ext/Sql/ca/scacost.h new file mode 100644 index 00000000..6ea7e465 --- /dev/null +++ b/src/ext/Sql/ca/scacost.h @@ -0,0 +1,7 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +const UINT COST_SQL_CREATEDB = 10000; +const UINT COST_SQL_DROPDB = 5000; +const UINT COST_SQL_CONNECTDB = 5000; +const UINT COST_SQL_STRING = 5000; diff --git a/src/ext/Sql/ca/scadb.cpp b/src/ext/Sql/ca/scadb.cpp new file mode 100644 index 00000000..288b9efe --- /dev/null +++ b/src/ext/Sql/ca/scadb.cpp @@ -0,0 +1,588 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +// sql queries +LPCWSTR vcsSqlDatabaseQuery = L"SELECT `SqlDb`, `Server`, `Instance`, `Database`, " + L"`Component_`, `User_`, `FileSpec_`, `FileSpec_Log`, `Attributes` " + L"FROM `Wix4SqlDatabase`"; +enum eSqlDatabaseQuery { sdqSqlDb = 1, sdqServer, sdqInstance, sdqDatabase, + sdqComponent, sdqUser, sdqDbFileSpec, sdqLogFileSpec, sdqAttributes }; + +LPCWSTR vcsSqlFileSpecQuery = L"SELECT `FileSpec`, `Name`, `Filename`, `Size`, " + L"`MaxSize`, `GrowthSize` FROM `Wix4SqlFileSpec` WHERE `FileSpec`=?"; +enum eSqlFileSpecQuery { sfsqFileSpec = 1, sfsqName, sfsqFilename, sfsqSize, + sfsqMaxSize, sfsqGrowth }; + + +// prototypes for private helper functions +static HRESULT NewDb( + __out SCA_DB** ppsd + ); + +static SCA_DB* AddDbToList( + __in SCA_DB* psdList, + __in SCA_DB* psd + ); + +static HRESULT SchedCreateDatabase( + __in SCA_DB* psd + ); + +static HRESULT SchedDropDatabase( + __in LPCWSTR wzKey, LPCWSTR wzServer, + __in LPCWSTR wzInstance, + __in LPCWSTR wzDatabase, + __in int iAttributes, + __in BOOL fIntegratedAuth, + __in LPCWSTR wzUser, + __in LPCWSTR wzPassword + ); + +static HRESULT GetFileSpec( + __in MSIHANDLE hViewFileSpec, + __in LPCWSTR wzKey, + __in SQL_FILESPEC* psf + ); + + +HRESULT ScaDbsRead( + __inout SCA_DB** ppsdList, + __in SCA_ACTION saAction + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + PMSIHANDLE hView; + PMSIHANDLE hRec; + PMSIHANDLE hViewFileSpec = NULL; + + LPWSTR pwzData = NULL; + LPWSTR pwzId = NULL; + LPWSTR pwzComponent = NULL; + + SCA_DB* psd = NULL; + + if (S_OK != WcaTableExists(L"Wix4SqlDatabase")) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaCreateDatabase() - Wix4SqlDatabase table not present"); + ExitFunction1(hr = S_FALSE); + } + + if (S_OK == WcaTableExists(L"Wix4SqlFileSpec")) + { + hr = WcaOpenView(vcsSqlFileSpecQuery, &hViewFileSpec); + ExitOnFailure(hr, "failed to open view on Wix4SqlFileSpec table"); + } + + // loop through all the sql databases + hr = WcaOpenExecuteView(vcsSqlDatabaseQuery, &hView); + ExitOnFailure(hr, "Failed to open view on Wix4SqlDatabase table"); + while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) + { + BOOL fHasComponent = FALSE; + INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; + INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; + + hr = WcaGetRecordString(hRec, sdqSqlDb, &pwzId); + ExitOnFailure(hr, "Failed to get Wix4SqlDatabase.SqlDb"); + + hr = WcaGetRecordString(hRec, sdqComponent, &pwzComponent); + ExitOnFailure(hr, "Failed to get Component for database: '%ls'", psd->wzKey); + if (pwzComponent && *pwzComponent) + { + fHasComponent = TRUE; + + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "Failed to get state for component: %ls", pwzComponent); + + // If we're doing install but the Component is not being installed or we're doing + // uninstall but the Component is not being uninstalled, skip it. + if ((WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL != saAction) || + (WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL != saAction)) + { + continue; + } + } + + hr = NewDb(&psd); + ExitOnFailure(hr, "Failed to allocate memory for new database: %D", pwzId); + + hr = ::StringCchCopyW(psd->wzKey, countof(psd->wzKey), pwzId); + ExitOnFailure(hr, "Failed to copy Wix4SqlDatabase.SqlDbL: %ls", pwzId); + + hr = ::StringCchCopyW(psd->wzComponent, countof(psd->wzComponent), pwzComponent); + ExitOnFailure(hr, "Failed to copy Wix4SqlDatabase.Component_: %ls", pwzComponent); + + psd->fHasComponent = fHasComponent; + psd->isInstalled = isInstalled; + psd->isAction = isAction; + + hr = WcaGetRecordFormattedString(hRec, sdqServer, &pwzData); + ExitOnFailure(hr, "Failed to get Server for database: '%ls'", psd->wzKey); + hr = ::StringCchCopyW(psd->wzServer, countof(psd->wzServer), pwzData); + ExitOnFailure(hr, "Failed to copy server string to database object:%ls", pwzData); + + hr = WcaGetRecordFormattedString(hRec, sdqInstance, &pwzData); + ExitOnFailure(hr, "Failed to get Instance for database: '%ls'", psd->wzKey); + hr = ::StringCchCopyW(psd->wzInstance, countof(psd->wzInstance), pwzData); + ExitOnFailure(hr, "Failed to copy instance string to database object:%ls", pwzData); + + hr = WcaGetRecordFormattedString(hRec, sdqDatabase, &pwzData); + ExitOnFailure(hr, "Failed to get Database for database: '%ls'", psd->wzKey); + hr = ::StringCchCopyW(psd->wzDatabase, countof(psd->wzDatabase), pwzData); + ExitOnFailure(hr, "Failed to copy database string to database object:%ls", pwzData); + + hr = WcaGetRecordInteger(hRec, sdqAttributes, &psd->iAttributes); + ExitOnFailure(hr, "Failed to get Wix4SqlDatabase.Attributes"); + + hr = WcaGetRecordFormattedString(hRec, sdqUser, &pwzData); + ExitOnFailure(hr, "Failed to get User record for database: '%ls'", psd->wzKey); + + // if a user was specified + if (*pwzData) + { + psd->fUseIntegratedAuth = FALSE; + hr = ScaGetUser(pwzData, &psd->scau); + ExitOnFailure(hr, "Failed to get user information for database: '%ls'", psd->wzKey); + } + else + { + psd->fUseIntegratedAuth = TRUE; + // integrated authorization doesn't have a User record + } + + hr = WcaGetRecordString(hRec, sdqDbFileSpec, &pwzData); + ExitOnFailure(hr, "Failed to get Database FileSpec for database: '%ls'", psd->wzKey); + + // if a database filespec was specified + if (*pwzData) + { + hr = GetFileSpec(hViewFileSpec, pwzData, &psd->sfDb); + ExitOnFailure(hr, "failed to get FileSpec for: %ls", pwzData); + if (S_OK == hr) + { + psd->fHasDbSpec = TRUE; + } + } + + hr = WcaGetRecordString(hRec, sdqLogFileSpec, &pwzData); + ExitOnFailure(hr, "Failed to get Log FileSpec for database: '%ls'", psd->wzKey); + + // if a log filespec was specified + if (*pwzData) + { + hr = GetFileSpec(hViewFileSpec, pwzData, &psd->sfLog); + ExitOnFailure(hr, "failed to get FileSpec for: %ls", pwzData); + if (S_OK == hr) + { + psd->fHasLogSpec = TRUE; + } + } + + *ppsdList = AddDbToList(*ppsdList, psd); + psd = NULL; // set the db NULL so it doesn't accidentally get freed below + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure occured while processing Wix4SqlDatabase table"); + +LExit: + if (psd) + { + ScaDbsFreeList(psd); + } + + ReleaseStr(pwzComponent); + ReleaseStr(pwzId); + ReleaseStr(pwzData); + return hr; +} + + +SCA_DB* ScaDbsFindDatabase( + __in LPCWSTR wzSqlDb, + __in SCA_DB* psdList + ) +{ + SCA_DB* psd = NULL; + + for (psd = psdList; psd; psd = psd->psdNext) + { + if (0 == lstrcmpW(wzSqlDb, psd->wzKey)) + { + break; + } + } + + return psd; +} + + +HRESULT ScaDbsInstall( + __in SCA_DB* psdList + ) +{ + HRESULT hr = S_FALSE; // assume nothing will be done + SCA_DB* psd = NULL; + + for (psd = psdList; psd; psd = psd->psdNext) + { + if (psd->fHasComponent) + { + // if we need to drop, do that first + if (((psd->iAttributes & SCADB_DROP_ON_INSTALL) && WcaIsInstalling(psd->isInstalled, psd->isAction) && !WcaIsReInstalling(psd->isInstalled, psd->isAction)) || + ((psd->iAttributes & SCADB_DROP_ON_REINSTALL) && WcaIsReInstalling(psd->isInstalled, psd->isAction))) + { + hr = SchedDropDatabase(psd->wzKey, psd->wzServer, psd->wzInstance, psd->wzDatabase, psd->iAttributes, psd->fUseIntegratedAuth, psd->scau.wzName, psd->scau.wzPassword); + ExitOnFailure(hr, "Failed to drop database %ls", psd->wzKey); + } + + // if installing this component + if (((psd->iAttributes & SCADB_CREATE_ON_INSTALL) && WcaIsInstalling(psd->isInstalled, psd->isAction) && !WcaIsReInstalling(psd->isInstalled, psd->isAction)) || + ((psd->iAttributes & SCADB_CREATE_ON_REINSTALL) && WcaIsReInstalling(psd->isInstalled, psd->isAction))) + { + hr = SchedCreateDatabase(psd); + ExitOnFailure(hr, "Failed to ensure database %ls exists", psd->wzKey); + } + } + } + +LExit: + return hr; +} + + +HRESULT ScaDbsUninstall( + __in SCA_DB* psdList + ) +{ + HRESULT hr = S_FALSE; // assume nothing will be done + SCA_DB* psd = NULL; + + for (psd = psdList; psd; psd = psd->psdNext) + { + if (psd->fHasComponent) + { + // if we need to drop do that first + if ((psd->iAttributes & SCADB_DROP_ON_UNINSTALL) && WcaIsUninstalling(psd->isInstalled, psd->isAction)) + { + hr = SchedDropDatabase(psd->wzKey, psd->wzServer, psd->wzInstance, psd->wzDatabase, psd->iAttributes, psd->fUseIntegratedAuth, psd->scau.wzName, psd->scau.wzPassword); + ExitOnFailure(hr, "Failed to drop database %ls", psd->wzKey); + } + + // install the db + if ((psd->iAttributes & SCADB_CREATE_ON_UNINSTALL) && WcaIsUninstalling(psd->isInstalled, psd->isAction)) + { + hr = SchedCreateDatabase(psd); + ExitOnFailure(hr, "Failed to ensure database %ls exists", psd->wzKey); + } + } + } + +LExit: + return hr; +} + + +void ScaDbsFreeList( + __in SCA_DB* psdList + ) +{ + SCA_DB* psdDelete = psdList; + while (psdList) + { + psdDelete = psdList; + psdList = psdList->psdNext; + + MemFree(psdDelete); + } +} + + +// private helper functions + +static HRESULT NewDb( + __out SCA_DB** ppsd + ) +{ + HRESULT hr = S_OK; + SCA_DB* psd = static_cast(MemAlloc(sizeof(SCA_DB), TRUE)); + ExitOnNull(psd, hr, E_OUTOFMEMORY, "failed to allocate memory for new database element"); + + *ppsd = psd; + +LExit: + return hr; +} + + +static SCA_DB* AddDbToList( + __in SCA_DB* psdList, + __in SCA_DB* psd + ) +{ + if (psdList) + { + SCA_DB* psdT = psdList; + while (psdT->psdNext) + { + psdT = psdT->psdNext; + } + + psdT->psdNext = psd; + } + else + { + psdList = psd; + } + + return psdList; +} + + +static HRESULT SchedCreateDatabase( + __in SCA_DB* psd + ) +{ + HRESULT hr = S_OK; + WCHAR* pwzCustomActionData = NULL; + + hr = WcaWriteStringToCaData(psd->wzKey, &pwzCustomActionData); + ExitOnFailure(hr, "failed to add DBKey to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->wzServer, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add server name to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->wzInstance, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add server instance to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->wzDatabase, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add database name to CustomActionData"); + + hr = WcaWriteIntegerToCaData(psd->iAttributes, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add Sql attributes to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->fUseIntegratedAuth ? L"1" : L"0", &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add if integrated connection to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->scau.wzName, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add server user to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->scau.wzPassword, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add user password to CustomActionData"); + + // Check to see if the database exists, if it does not then schedule a rollback + // so we clean up after ourselves if the creation of the database fails or is + // aborted. It is interesting to note that we can do this check here because the + // deferred CustomActions are Impersonated. That means this scheduling action and + // the execution actions all run with the same user context, so it is safe to + // to do the check. + hr = SqlDatabaseExists(psd->wzServer, psd->wzInstance, psd->wzDatabase, psd->fUseIntegratedAuth, psd->scau.wzName, psd->scau.wzPassword, NULL); + if (S_FALSE == hr) + { + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackCreateDatabase"), pwzCustomActionData, COST_SQL_CREATEDB); + ExitOnFailure(hr, "Failed to schedule RollbackCreateDatabase action"); + } + + // database filespec + if (psd->fHasDbSpec) + { + hr = WcaWriteStringToCaData(L"1", &pwzCustomActionData); + ExitOnFailure(hr, "failed to specify that do have db.filespec to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->sfDb.wzName, &pwzCustomActionData); + ExitOnFailure(hr, "failed to add FileSpec.Name to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->sfDb.wzFilename, &pwzCustomActionData); + ExitOnFailure(hr, "failed to add FileSpec.Filename to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->sfDb.wzSize, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add FileSpec.Size to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->sfDb.wzMaxSize, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add FileSpec.MaxSize to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->sfDb.wzGrow, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add FileSpec.GrowthSize to CustomActionData"); + } + else + { + hr = WcaWriteStringToCaData(L"0", &pwzCustomActionData); + ExitOnFailure(hr, "failed to specify that do not have db.filespec to CustomActionData"); + } + + // log filespec + if (psd->fHasLogSpec) + { + hr = WcaWriteStringToCaData(L"1", &pwzCustomActionData); + ExitOnFailure(hr, "failed to specify that do have log.filespec to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->sfLog.wzName, &pwzCustomActionData); + ExitOnFailure(hr, "failed to add FileSpec.Name to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->sfLog.wzFilename, &pwzCustomActionData); + ExitOnFailure(hr, "failed to add FileSpec.Filename to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->sfLog.wzSize, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add FileSpec.Size to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->sfLog.wzMaxSize, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add FileSpec.MaxSize to CustomActionData"); + + hr = WcaWriteStringToCaData(psd->sfLog.wzGrow, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add FileSpec.GrowthSize to CustomActionData"); + } + else + { + hr = WcaWriteStringToCaData(L"0", &pwzCustomActionData); + ExitOnFailure(hr, "failed to specify that do not have log.filespec to CustomActionData"); + } + + // schedule the CreateDatabase action + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"CreateDatabase"), pwzCustomActionData, COST_SQL_CREATEDB); + ExitOnFailure(hr, "Failed to schedule CreateDatabase action"); + +LExit: + ReleaseStr(pwzCustomActionData); + return hr; +} + + +HRESULT SchedDropDatabase( + __in LPCWSTR wzKey, + __in LPCWSTR wzServer, + __in LPCWSTR wzInstance, + __in LPCWSTR wzDatabase, + __in int iAttributes, + __in BOOL fIntegratedAuth, + __in LPCWSTR wzUser, + __in LPCWSTR wzPassword + ) +{ + HRESULT hr = S_OK; + WCHAR* pwzCustomActionData = NULL; + + hr = WcaWriteStringToCaData(wzKey, &pwzCustomActionData); + ExitOnFailure(hr, "failed to add DBKey to CustomActionData"); + + hr = WcaWriteStringToCaData(wzServer, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add server name to CustomActionData"); + + hr = WcaWriteStringToCaData(wzInstance, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add server instance to CustomActionData"); + + hr = WcaWriteStringToCaData(wzDatabase, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add database name to CustomActionData"); + + hr = WcaWriteIntegerToCaData(iAttributes, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add server name to CustomActionData"); + + hr = WcaWriteStringToCaData(fIntegratedAuth ? L"1" : L"0", &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add server name to CustomActionData"); + + hr = WcaWriteStringToCaData(wzUser, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add server user to CustomActionData"); + + hr = WcaWriteStringToCaData(wzPassword, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add user password to CustomActionData"); + + hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"DropDatabase"), pwzCustomActionData, COST_SQL_DROPDB); + ExitOnFailure(hr, "Failed to schedule DropDatabase action"); + +LExit: + ReleaseStr(pwzCustomActionData); + return hr; +} + + +HRESULT GetFileSpec( + __in MSIHANDLE hViewFileSpec, + __in LPCWSTR wzKey, + __in SQL_FILESPEC* psf + ) +{ + HRESULT hr = S_OK; + PMSIHANDLE hRecFileSpec, hRec; + LPWSTR pwzData = NULL; + + // create a record to do the fetch + hRecFileSpec = ::MsiCreateRecord(1); + if (!hRecFileSpec) + { + ExitOnFailure(hr = E_UNEXPECTED, "failed to create record for filespec: %ls", wzKey); + } + hr = WcaSetRecordString(hRecFileSpec, 1, wzKey); + ExitOnFailure(hr, "failed to set record string for filespec: %ls", wzKey); + + // get the FileSpec record + hr = WcaExecuteView(hViewFileSpec, hRecFileSpec); + ExitOnFailure(hr, "failed to execute view on Wix4SqlFileSpec table for filespec: %ls", wzKey); + hr = WcaFetchSingleRecord(hViewFileSpec, &hRec); + ExitOnFailure(hr, "failed to get record for filespec: %ls", wzKey); + + // read the data out of the filespec record + hr = WcaGetRecordFormattedString(hRec, sfsqName, &pwzData); + ExitOnFailure(hr, "Failed to get Wix4SqlFileSpec.Name for filespec: %ls", wzKey); + hr = ::StringCchCopyW(psf->wzName, countof(psf->wzName), pwzData); + ExitOnFailure(hr, "Failed to copy Wix4SqlFileSpec.Name string: %ls", pwzData); + + hr = WcaGetRecordFormattedString(hRec, sfsqFilename, &pwzData); + ExitOnFailure(hr, "Failed to get Wix4SqlFileSpec.Filename for filespec: %ls", wzKey); + if (*pwzData) + { + hr = ::StringCchCopyW(psf->wzFilename, countof(psf->wzFilename), pwzData); + ExitOnFailure(hr, "Failed to copy filename to filespec object: %ls", pwzData); + } + else // if there is no file, skip this FILESPEC + { + WcaLog(LOGMSG_VERBOSE, "No filename specified, skipping FileSpec: %ls", psf->wzName); + ExitFunction1(hr = S_FALSE); + } + + hr = WcaGetRecordFormattedString(hRec, sfsqSize, &pwzData); + ExitOnFailure(hr, "Failed to get Wix4SqlFileSpec.Size for filespec: %ls", wzKey); + if (*pwzData) + { + hr = ::StringCchCopyW(psf->wzSize, countof(psf->wzSize), pwzData); + ExitOnFailure(hr, "Failed to copy size to filespec object: %ls", pwzData); + } + else + { + psf->wzSize[0] = 0; + } + + hr = WcaGetRecordFormattedString(hRec, sfsqMaxSize, &pwzData); + ExitOnFailure(hr, "Failed to get Wix4SqlFileSpec.MaxSize for filespec: %ls", wzKey); + if (*pwzData) + { + hr = ::StringCchCopyW(psf->wzMaxSize, countof(psf->wzMaxSize), pwzData); + ExitOnFailure(hr, "Failed to copy max size to filespec object: %ls", pwzData); + } + else + { + psf->wzMaxSize[0] = 0; + } + + hr = WcaGetRecordFormattedString(hRec, sfsqGrowth, &pwzData); + ExitOnFailure(hr, "Failed to get Wix4SqlFileSpec.GrowthSize for filespec: %ls", wzKey); + if (*pwzData) + { + hr = ::StringCchCopyW(psf->wzGrow, countof(psf->wzGrow), pwzData); + ExitOnFailure(hr, "Failed to copy growth size to filespec object: %ls", pwzData); + } + else + { + psf->wzGrow[0] = 0; + } + + hr = S_OK; + +LExit: + ReleaseStr(pwzData); + return hr; +} diff --git a/src/ext/Sql/ca/scadb.h b/src/ext/Sql/ca/scadb.h new file mode 100644 index 00000000..885e84c2 --- /dev/null +++ b/src/ext/Sql/ca/scadb.h @@ -0,0 +1,55 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#include "scauser.h" +#include "sqlutil.h" + +struct SCA_DB +{ + // darwin information + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + BOOL fHasComponent; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + INSTALLSTATE isInstalled, isAction; + + WCHAR wzServer[MAX_DARWIN_COLUMN + 1]; + WCHAR wzInstance[MAX_DARWIN_COLUMN + 1]; + WCHAR wzDatabase[MAX_DARWIN_COLUMN + 1]; + + int iAttributes; + + BOOL fUseIntegratedAuth; + SCA_USER scau; + + BOOL fHasDbSpec; + SQL_FILESPEC sfDb; + BOOL fHasLogSpec; + SQL_FILESPEC sfLog; + + SCA_DB* psdNext; +}; + + +// prototypes +HRESULT ScaDbsRead( + __inout SCA_DB** ppsdList, + __in SCA_ACTION saAction + ); + +SCA_DB* ScaDbsFindDatabase( + __in LPCWSTR wzSqlDb, + __in SCA_DB* psdList + ); + +HRESULT ScaDbsInstall( + __in SCA_DB* psdList + ); + +HRESULT ScaDbsUninstall( + __in SCA_DB* psdList + ); + +void ScaDbsFreeList( + __in SCA_DB* psdList + ); diff --git a/src/ext/Sql/ca/scaexec.cpp b/src/ext/Sql/ca/scaexec.cpp new file mode 100644 index 00000000..b2648361 --- /dev/null +++ b/src/ext/Sql/ca/scaexec.cpp @@ -0,0 +1,393 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + + +/******************************************************************** + * CreateDatabase - CUSTOM ACTION ENTRY POINT for creating databases + * + * Input: deferred CustomActionData - DbKey\tServer\tInstance\tDatabase\tAttributes\tIntegratedAuth\tUser\tPassword + * ****************************************************************/ +extern "C" UINT __stdcall CreateDatabase(MSIHANDLE hInstall) +{ +//AssertSz(FALSE, "debug CreateDatabase here"); + UINT er = ERROR_SUCCESS; + HRESULT hr = S_OK; + + LPWSTR pwzData = NULL; + IDBCreateSession* pidbSession = NULL; + BSTR bstrErrorDescription = NULL; + LPWSTR pwz = NULL; + LPWSTR pwzDatabaseKey = NULL; + LPWSTR pwzServer = NULL; + LPWSTR pwzInstance = NULL; + LPWSTR pwzDatabase = NULL; + LPWSTR pwzTemp = NULL; + int iAttributes; + BOOL fIntegratedAuth; + LPWSTR pwzUser = NULL; + LPWSTR pwzPassword = NULL; + BOOL fHaveDbFileSpec = FALSE; + SQL_FILESPEC sfDb; + BOOL fHaveLogFileSpec = FALSE; + SQL_FILESPEC sfLog; + BOOL fInitializedCom = FALSE; + + memset(&sfDb, 0, sizeof(sfDb)); + memset(&sfLog, 0, sizeof(sfLog)); + + hr = WcaInitialize(hInstall, "CreateDatabase"); + ExitOnFailure(hr, "failed to initialize"); + + hr = ::CoInitialize(NULL); + ExitOnFailure(hr, "failed to intialize COM"); + fInitializedCom = TRUE; + + hr = WcaGetProperty( L"CustomActionData", &pwzData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData); + + pwz = pwzData; + hr = WcaReadStringFromCaData(&pwz, &pwzDatabaseKey); // SQL Server + ExitOnFailure(hr, "failed to read database key from custom action data: %ls", pwz); + hr = WcaReadStringFromCaData(&pwz, &pwzServer); // SQL Server + ExitOnFailure(hr, "failed to read server from custom action data: %ls", pwz); + hr = WcaReadStringFromCaData(&pwz, &pwzInstance); // SQL Server Instance + ExitOnFailure(hr, "failed to read server instance from custom action data: %ls", pwz); + hr = WcaReadStringFromCaData(&pwz, &pwzDatabase); // SQL Database + ExitOnFailure(hr, "failed to read server instance from custom action data: %ls", pwz); + hr = WcaReadIntegerFromCaData(&pwz, &iAttributes); + ExitOnFailure(hr, "failed to read attributes from custom action data: %ls", pwz); + hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&fIntegratedAuth)); // Integrated Windows Authentication? + ExitOnFailure(hr, "failed to read integrated auth flag from custom action data: %ls", pwz); + hr = WcaReadStringFromCaData(&pwz, &pwzUser); // SQL User + ExitOnFailure(hr, "failed to read user from custom action data: %ls", pwz); + hr = WcaReadStringFromCaData(&pwz, &pwzPassword); // SQL User Password + ExitOnFailure(hr, "failed to read user from custom action data: %ls", pwz); + + // db file spec + hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&fHaveDbFileSpec)); + ExitOnFailure(hr, "failed to read db file spec from custom action data: %ls", pwz); + + if (fHaveDbFileSpec) + { + hr = WcaReadStringFromCaData(&pwz, &pwzTemp); + ExitOnFailure(hr, "failed to read db file spec name from custom action data: %ls", pwz); + hr = ::StringCchCopyW(sfDb.wzName, countof(sfDb.wzName), pwzTemp); + ExitOnFailure(hr, "failed to copy db file spec name: %ls", pwzTemp); + + hr = WcaReadStringFromCaData(&pwz, &pwzTemp); + ExitOnFailure(hr, "failed to read db file spec filename from custom action data: %ls", pwz); + hr = ::StringCchCopyW(sfDb.wzFilename, countof(sfDb.wzFilename), pwzTemp); + ExitOnFailure(hr, "failed to copy db file spec filename: %ls", pwzTemp); + + hr = WcaReadStringFromCaData(&pwz, &pwzTemp); + ExitOnFailure(hr, "failed to read db file spec size from custom action data: %ls", pwz); + hr = ::StringCchCopyW(sfDb.wzSize, countof(sfDb.wzSize), pwzTemp); + ExitOnFailure(hr, "failed to copy db file spec size value: %ls", pwzTemp); + + hr = WcaReadStringFromCaData(&pwz, &pwzTemp); + ExitOnFailure(hr, "failed to read db file spec max size from custom action data: %ls", pwz); + hr = ::StringCchCopyW(sfDb.wzMaxSize, countof(sfDb.wzMaxSize), pwzTemp); + ExitOnFailure(hr, "failed to copy db file spec max size: %ls", pwzTemp); + + hr = WcaReadStringFromCaData(&pwz, &pwzTemp); + ExitOnFailure(hr, "failed to read db file spec grow from custom action data: %ls", pwz); + hr = ::StringCchCopyW(sfDb.wzGrow, countof(sfDb.wzGrow), pwzTemp); + ExitOnFailure(hr, "failed to copy db file spec grow value: %ls", pwzTemp); + } + + // log file spec + hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&fHaveLogFileSpec)); + ExitOnFailure(hr, "failed to read log file spec from custom action data: %ls", pwz); + if (fHaveLogFileSpec) + { + hr = WcaReadStringFromCaData(&pwz, &pwzTemp); + ExitOnFailure(hr, "failed to read log file spec name from custom action data: %ls", pwz); + hr = ::StringCchCopyW(sfLog.wzName, countof(sfDb.wzName), pwzTemp); + ExitOnFailure(hr, "failed to copy log file spec name: %ls", pwzTemp); + + hr = WcaReadStringFromCaData(&pwz, &pwzTemp); + ExitOnFailure(hr, "failed to read log file spec filename from custom action data: %ls", pwz); + hr = ::StringCchCopyW(sfLog.wzFilename, countof(sfDb.wzFilename), pwzTemp); + ExitOnFailure(hr, "failed to copy log file spec filename: %ls", pwzTemp); + + hr = WcaReadStringFromCaData(&pwz, &pwzTemp); + ExitOnFailure(hr, "failed to read log file spec size from custom action data: %ls", pwz); + hr = ::StringCchCopyW(sfLog.wzSize, countof(sfDb.wzSize), pwzTemp); + ExitOnFailure(hr, "failed to copy log file spec size value: %ls", pwzTemp); + + hr = WcaReadStringFromCaData(&pwz, &pwzTemp); + ExitOnFailure(hr, "failed to read log file spec max size from custom action data: %ls", pwz); + hr = ::StringCchCopyW(sfLog.wzMaxSize, countof(sfDb.wzMaxSize), pwzTemp); + ExitOnFailure(hr, "failed to copy log file spec max size: %ls", pwzTemp); + + hr = WcaReadStringFromCaData(&pwz, &pwzTemp); + ExitOnFailure(hr, "failed to read log file spec grow from custom action data: %ls", pwz); + hr = ::StringCchCopyW(sfLog.wzGrow, countof(sfDb.wzGrow), pwzTemp); + ExitOnFailure(hr, "failed to copy log file spec grow value: %ls", pwzTemp); + } + + if (iAttributes & SCADB_CONFIRM_OVERWRITE) + { + // Check if the database already exists + hr = SqlDatabaseExists(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, &bstrErrorDescription); + MessageExitOnFailure(hr, msierrSQLFailedCreateDatabase, "failed to check if database exists: '%ls', error: %ls", pwzDatabase, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription); + + if (S_OK == hr) // found an existing database, confirm that they don't want to stop before it gets trampled, in no UI case just continue anyways + { + hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS); + if (IDNO == WcaErrorMessage(msierrSQLDatabaseAlreadyExists, hr, MB_YESNO, 1, pwzDatabase)) + ExitOnFailure(hr, "failed to initialize"); + } + } + + hr = SqlDatabaseEnsureExists(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, fHaveDbFileSpec ? &sfDb : NULL, fHaveLogFileSpec ? &sfLog : NULL, &bstrErrorDescription); + if ((iAttributes & SCADB_CONTINUE_ON_ERROR) && FAILED(hr)) + { + WcaLog(LOGMSG_STANDARD, "Error 0x%x: failed to create SQL database but continuing, error: %ls, Database: %ls", hr, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzDatabase); + hr = S_OK; + } + MessageExitOnFailure(hr, msierrSQLFailedCreateDatabase, "failed to create to database: '%ls', error: %ls", pwzDatabase, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription); + + hr = WcaProgressMessage(COST_SQL_CONNECTDB, FALSE); +LExit: + ReleaseStr(pwzDatabaseKey); + ReleaseStr(pwzServer); + ReleaseStr(pwzInstance); + ReleaseStr(pwzDatabase); + ReleaseStr(pwzUser); + ReleaseStr(pwzPassword); + ReleaseObject(pidbSession); + ReleaseBSTR(bstrErrorDescription); + + if (fInitializedCom) + { + ::CoUninitialize(); + } + + if (FAILED(hr)) + { + er = ERROR_INSTALL_FAILURE; + } + return WcaFinalize(er); +} + + +/******************************************************************** + DropDatabase - CUSTOM ACTION ENTRY POINT for removing databases + + Input: deferred CustomActionData - DbKey\tServer\tInstance\tDatabase\tAttributes\tIntegratedAuth\tUser\tPassword + * ****************************************************************/ +extern "C" UINT __stdcall DropDatabase(MSIHANDLE hInstall) +{ +//Assert(FALSE); + UINT er = ERROR_SUCCESS; + HRESULT hr = S_OK; + + LPWSTR pwzData = NULL; + IDBCreateSession* pidbSession = NULL; + BSTR bstrErrorDescription = NULL; + LPWSTR pwz = NULL; + LPWSTR pwzDatabaseKey = NULL; + LPWSTR pwzServer = NULL; + LPWSTR pwzInstance = NULL; + LPWSTR pwzDatabase = NULL; + long lAttributes; + BOOL fIntegratedAuth; + LPWSTR pwzUser = NULL; + LPWSTR pwzPassword = NULL; + BOOL fInitializedCom = TRUE; + + hr = WcaInitialize(hInstall, "DropDatabase"); + ExitOnFailure(hr, "failed to initialize"); + + hr = ::CoInitialize(NULL); + ExitOnFailure(hr, "failed to intialize COM"); + fInitializedCom = TRUE; + + hr = WcaGetProperty( L"CustomActionData", &pwzData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData); + + pwz = pwzData; + hr = WcaReadStringFromCaData(&pwz, &pwzDatabaseKey); + ExitOnFailure(hr, "failed to read database key"); + hr = WcaReadStringFromCaData(&pwz, &pwzServer); + ExitOnFailure(hr, "failed to read server"); + hr = WcaReadStringFromCaData(&pwz, &pwzInstance); + ExitOnFailure(hr, "failed to read instance"); + hr = WcaReadStringFromCaData(&pwz, &pwzDatabase); + ExitOnFailure(hr, "failed to read database"); + hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&lAttributes)); + ExitOnFailure(hr, "failed to read attributes"); + hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&fIntegratedAuth)); // Integrated Windows Authentication? + ExitOnFailure(hr, "failed to read integrated auth flag"); + hr = WcaReadStringFromCaData(&pwz, &pwzUser); + ExitOnFailure(hr, "failed to read user"); + hr = WcaReadStringFromCaData(&pwz, &pwzPassword); + ExitOnFailure(hr, "failed to read password"); + + hr = SqlDropDatabase(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, &bstrErrorDescription); + if ((lAttributes & SCADB_CONTINUE_ON_ERROR) && FAILED(hr)) + { + WcaLog(LOGMSG_STANDARD, "Error 0x%x: failed to drop SQL database but continuing, error: %ls, Database: %ls", hr, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzDatabase); + hr = S_OK; + } + MessageExitOnFailure(hr, msierrSQLFailedDropDatabase, "failed to drop to database: '%ls', error: %ls", pwzDatabase, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription); + + hr = WcaProgressMessage(COST_SQL_CONNECTDB, FALSE); + +LExit: + ReleaseStr(pwzDatabaseKey); + ReleaseStr(pwzServer); + ReleaseStr(pwzInstance); + ReleaseStr(pwzDatabase); + ReleaseStr(pwzUser); + ReleaseStr(pwzPassword); + ReleaseStr(pwzData); + ReleaseObject(pidbSession); + ReleaseBSTR(bstrErrorDescription); + + if (fInitializedCom) + { + ::CoUninitialize(); + } + + if (FAILED(hr)) + { + er = ERROR_INSTALL_FAILURE; + } + return WcaFinalize(er); +} + + +/******************************************************************** + ExecuteSqlStrings - CUSTOM ACTION ENTRY POINT for running SQL strings + + Input: deferred CustomActionData - DbKey\tServer\tInstance\tDatabase\tAttributes\tIntegratedAuth\tUser\tPassword\tSQLKey1\tSQLString1\tSQLKey2\tSQLString2\tSQLKey3\tSQLString3\t... + rollback CustomActionData - same as above + * ****************************************************************/ +extern "C" UINT __stdcall ExecuteSqlStrings(MSIHANDLE hInstall) +{ +//Assert(FALSE); + UINT er = ERROR_SUCCESS; + HRESULT hr = S_OK; + HRESULT hrDB = S_OK; + + LPWSTR pwzData = NULL; + IDBCreateSession* pidbSession = NULL; + BSTR bstrErrorDescription = NULL; + + LPWSTR pwz = NULL; + LPWSTR pwzDatabaseKey = NULL; + LPWSTR pwzServer = NULL; + LPWSTR pwzInstance = NULL; + LPWSTR pwzDatabase = NULL; + int iAttributesDB; + int iAttributesSQL; + BOOL fIntegratedAuth; + LPWSTR pwzUser = NULL; + LPWSTR pwzPassword = NULL; + LPWSTR pwzSqlKey = NULL; + LPWSTR pwzSql = NULL; + BOOL fInitializedCom = FALSE; + + hr = WcaInitialize(hInstall, "ExecuteSqlStrings"); + ExitOnFailure(hr, "failed to initialize"); + + hr = ::CoInitialize(NULL); + ExitOnFailure(hr, "failed to intialize COM"); + fInitializedCom = TRUE; + + hr = WcaGetProperty( L"CustomActionData", &pwzData); + ExitOnFailure(hr, "failed to get CustomActionData"); + + WcaLog(LOGMSG_TRACEONLY, "CustomActionData: %ls", pwzData); + + pwz = pwzData; + hr = WcaReadStringFromCaData(&pwz, &pwzDatabaseKey); + ExitOnFailure(hr, "failed to read database key"); + hr = WcaReadStringFromCaData(&pwz, &pwzServer); + ExitOnFailure(hr, "failed to read server"); + hr = WcaReadStringFromCaData(&pwz, &pwzInstance); + ExitOnFailure(hr, "failed to read instance"); + hr = WcaReadStringFromCaData(&pwz, &pwzDatabase); + ExitOnFailure(hr, "failed to read database"); + hr = WcaReadIntegerFromCaData(&pwz, &iAttributesDB); + ExitOnFailure(hr, "failed to read attributes"); + hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast(&fIntegratedAuth)); // Integrated Windows Authentication? + ExitOnFailure(hr, "failed to read integrated auth flag"); + hr = WcaReadStringFromCaData(&pwz, &pwzUser); + ExitOnFailure(hr, "failed to read user"); + hr = WcaReadStringFromCaData(&pwz, &pwzPassword); + ExitOnFailure(hr, "failed to read password"); + + // Store off the result of the connect, only exit if we don't care if the database connection succeeds + // Wait to fail until later to see if we actually have work to do that is not set to continue on error + hrDB = SqlConnectDatabase(pwzServer, pwzInstance, pwzDatabase, fIntegratedAuth, pwzUser, pwzPassword, &pidbSession); + if ((iAttributesDB & SCADB_CONTINUE_ON_ERROR) && FAILED(hrDB)) + { + WcaLog(LOGMSG_STANDARD, "Error 0x%x: continuing after failure to connect to database: %ls", hrDB, pwzDatabase); + ExitFunction1(hr = S_OK); + } + + while (S_OK == hr && S_OK == (hr = WcaReadStringFromCaData(&pwz, &pwzSqlKey))) + { + hr = WcaReadIntegerFromCaData(&pwz, &iAttributesSQL); + ExitOnFailure(hr, "failed to read attributes for SQL string: %ls", pwzSqlKey); + + hr = WcaReadStringFromCaData(&pwz, &pwzSql); + ExitOnFailure(hr, "failed to read SQL string for key: %ls", pwzSqlKey); + + // If the Wix4SqlString row is set to continue on error and the DB connection failed, skip attempting to execute + if ((iAttributesSQL & SCASQL_CONTINUE_ON_ERROR) && FAILED(hrDB)) + { + WcaLog(LOGMSG_STANDARD, "Error 0x%x: continuing after failure to connect to database: %ls", hrDB, pwzDatabase); + continue; + } + + // Now check if the DB connection succeeded + MessageExitOnFailure(hr = hrDB, msierrSQLFailedConnectDatabase, "failed to connect to database: '%ls'", pwzDatabase); + + WcaLog(LOGMSG_VERBOSE, "Executing SQL string: %ls", pwzSql); + hr = SqlSessionExecuteQuery(pidbSession, pwzSql, NULL, NULL, &bstrErrorDescription); + if ((iAttributesSQL & SCASQL_CONTINUE_ON_ERROR) && FAILED(hr)) + { + WcaLog(LOGMSG_STANDARD, "Error 0x%x: failed to execute SQL string but continuing, error: %ls, SQL key: %ls SQL string: %ls", hr, NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzSqlKey, pwzSql); + hr = S_OK; + } + MessageExitOnFailure(hr, msierrSQLFailedExecString, "failed to execute SQL string, error: %ls, SQL key: %ls SQL string: %ls", NULL == bstrErrorDescription ? L"unknown error" : bstrErrorDescription, pwzSqlKey, pwzSql); + + WcaProgressMessage(COST_SQL_STRING, FALSE); + } + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + +LExit: + ReleaseStr(pwzDatabaseKey); + ReleaseStr(pwzServer); + ReleaseStr(pwzInstance); + ReleaseStr(pwzDatabase); + ReleaseStr(pwzUser); + ReleaseStr(pwzPassword); + ReleaseStr(pwzData); + + ReleaseBSTR(bstrErrorDescription); + ReleaseObject(pidbSession); + + if (fInitializedCom) + { + ::CoUninitialize(); + } + + if (FAILED(hr)) + { + er = ERROR_INSTALL_FAILURE; + } + return WcaFinalize(er); +} diff --git a/src/ext/Sql/ca/scasql.cpp b/src/ext/Sql/ca/scasql.cpp new file mode 100644 index 00000000..b0216950 --- /dev/null +++ b/src/ext/Sql/ca/scasql.cpp @@ -0,0 +1,113 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +// prototypes +static HRESULT ConfigureSqlData( + __in SCA_ACTION saAction + ); + + +/******************************************************************** +InstallSqlData - CUSTOM ACTION ENTRY POINT for installing + SQL data + +********************************************************************/ +extern "C" UINT __stdcall InstallSqlData( + __in MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + // initialize + hr = WcaInitialize(hInstall, "InstallSqlData"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = ConfigureSqlData(SCA_ACTION_INSTALL); + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +/******************************************************************** +UninstallSqlData - CUSTOM ACTION ENTRY POINT for uninstalling + SQL data + +********************************************************************/ +extern "C" UINT __stdcall UninstallSqlData( + __in MSIHANDLE hInstall + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + // initialize + hr = WcaInitialize(hInstall, "UninstallCertificates"); + ExitOnFailure(hr, "Failed to initialize"); + + hr = ConfigureSqlData(SCA_ACTION_UNINSTALL); + +LExit: + er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + + +static HRESULT ConfigureSqlData( + __in SCA_ACTION saAction + ) +{ + //AssertSz(FALSE, "debug ConfigureSqlData()"); + HRESULT hr = S_OK; + + SCA_DB* psdList = NULL; + SCA_SQLSTR* psssList = NULL; + + // check for the prerequsite tables + if (S_OK != WcaTableExists(L"Wix4SqlDatabase")) + { + WcaLog(LOGMSG_VERBOSE, "skipping SQL CustomAction, no Wix4SqlDatabase table"); + ExitFunction1(hr = S_FALSE); + } + + // read tables + hr = ScaDbsRead(&psdList, saAction); + ExitOnFailure(hr, "failed to read Wix4SqlDatabase table"); + + hr = ScaSqlStrsRead(&psssList, saAction); + ExitOnFailure(hr, "failed to read Wix4SqlString table"); + + hr = ScaSqlStrsReadScripts(&psssList, saAction); + ExitOnFailure(hr, "failed to read Wix4SqlScript table"); + + if (SCA_ACTION_UNINSTALL == saAction) + { + // do uninstall actions (order is important!) + hr = ScaSqlStrsUninstall(psdList, psssList); + ExitOnFailure(hr, "failed to execute uninstall SQL strings"); + + hr = ScaDbsUninstall(psdList); + ExitOnFailure(hr, "failed to uninstall databases"); + } + else + { + // do install actions (order is important!) + hr = ScaDbsInstall(psdList); + ExitOnFailure(hr, "failed to install databases"); + + hr = ScaSqlStrsInstall(psdList, psssList); + ExitOnFailure(hr, "failed to execute install SQL strings, length may be too long, try add GO to break up"); + } + +LExit: + if (psssList) + ScaSqlStrsFreeList(psssList); + + if (psdList) + ScaDbsFreeList(psdList); + + return hr; +} diff --git a/src/ext/Sql/ca/scasqlstr.cpp b/src/ext/Sql/ca/scasqlstr.cpp new file mode 100644 index 00000000..c3ebd43d --- /dev/null +++ b/src/ext/Sql/ca/scasqlstr.cpp @@ -0,0 +1,728 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +// sql queries +LPCWSTR vcsSqlStringQuery = L"SELECT `String`, `SqlDb_`, `Component_`,`SQL`,`User_`,`Attributes`,`Sequence` " +L"FROM `Wix4SqlString` ORDER BY `SqlDb_`,`Sequence`"; +enum eSqlStringQuery { ssqSqlString = 1, ssqSqlDb, ssqComponent, ssqSQL, ssqUser, ssqAttributes, ssqSequence }; + +LPCWSTR vcsSqlScriptQuery = L"SELECT `ScriptBinary_`,`Script`, `SqlDb_`, `Component_`,`User_`,`Attributes`,`Sequence` " +L"FROM `Wix4SqlScript` ORDER BY `SqlDb_`,`Sequence`"; +enum eSqlScriptQuery { sscrqScriptBinary=1, sscrqSqlScript, sscrqSqlDb, sscrqComponent, sscrqUser, sscrqAttributes, sscrqSequence }; + +LPCWSTR vcsSqlBinaryScriptQuery = L"SELECT `Data` FROM `Binary` WHERE `Name`=?"; +enum eSqlBinaryScriptQuery { ssbsqData = 1 }; + + +// prototypes for private helper functions +static HRESULT NewSqlStr( + __out SCA_SQLSTR** ppsss + ); +static SCA_SQLSTR* AddSqlStrToList( + __in SCA_SQLSTR* psssList, + __in SCA_SQLSTR* psss + ); +static HRESULT ExecuteStrings( + __in SCA_DB* psdList, + __in SCA_SQLSTR* psssList, + __in BOOL fInstall + ); + +HRESULT ScaSqlStrsRead( + __inout SCA_SQLSTR** ppsssList, + __in SCA_ACTION saAction + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + PMSIHANDLE hView, hRec; + PMSIHANDLE hViewUser, hRecUser; + + LPWSTR pwzComponent = NULL; + LPWSTR pwzData = NULL; + + SCA_SQLSTR* psss = NULL; + + if (S_OK != WcaTableExists(L"Wix4SqlString") || S_OK != WcaTableExists(L"Wix4SqlDatabase")) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaSqlStrsRead() - Wix4SqlString and/or Wix4SqlDatabase table not present"); + ExitFunction1(hr = S_FALSE); + } + + // loop through all the sql strings + hr = WcaOpenExecuteView(vcsSqlStringQuery, &hView); + ExitOnFailure(hr, "Failed to open view on Wix4SqlString table"); + while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) + { + INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; + INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; + + hr = WcaGetRecordString(hRec, ssqComponent, &pwzComponent); + ExitOnFailure(hr, "Failed to get Component for SQL String."); + + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "Failed to get state for component: %ls", pwzComponent); + + // If we're doing install but the Component is not being installed or we're doing + // uninstall but the Component is not being uninstalled, skip it. + if ((WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL != saAction) || + (WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL != saAction)) + { + continue; + } + + hr = NewSqlStr(&psss); + ExitOnFailure(hr, "failed to allocation new sql string element"); + + psss->isInstalled = isInstalled; + psss->isAction = isAction; + + hr = WcaGetRecordString(hRec, ssqSqlString, &pwzData); + ExitOnFailure(hr, "Failed to get Wix4SqlString.String"); + hr = ::StringCchCopyW(psss->wzKey, countof(psss->wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy Wix4SqlString.String: %ls", pwzData); + + // find the database information for this string + hr = WcaGetRecordString(hRec, ssqSqlDb, &pwzData); + ExitOnFailure(hr, "Failed to get Wix4SqlString.SqlDb_ for SqlString '%ls'", psss->wzKey); + hr = ::StringCchCopyW(psss->wzSqlDb, countof(psss->wzSqlDb), pwzData); + ExitOnFailure(hr, "Failed to copy Wix4SqlString.SqlDb_: %ls", pwzData); + + hr = WcaGetRecordInteger(hRec, ssqAttributes, &psss->iAttributes); + ExitOnFailure(hr, "Failed to get Wix4SqlString.Attributes for SqlString '%ls'", psss->wzKey); + + //get the sequence number for the string (note that this will be sequenced with scripts too) + hr = WcaGetRecordInteger(hRec, ssqSequence, &psss->iSequence); + ExitOnFailure(hr, "Failed to get Wix4SqlString.Sequence for SqlString '%ls'", psss->wzKey); + + // execute SQL + hr = WcaGetRecordFormattedString(hRec, ssqSQL, &pwzData); + ExitOnFailure(hr, "Failed to get Wix4SqlString.SQL for SQL string '%ls'", psss->wzKey); + + Assert(!psss->pwzSql); + hr = StrAllocString(&psss->pwzSql, pwzData, 0); + ExitOnFailure(hr, "Failed to alloc string for SQL string '%ls'", psss->wzKey); + + *ppsssList = AddSqlStrToList(*ppsssList, psss); + psss = NULL; // set the sss to NULL so it doesn't get freed below + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure occured while reading Wix4SqlString table"); + +LExit: + // if anything was left over after an error clean it all up + if (psss) + { + ScaSqlStrsFreeList(psss); + } + + ReleaseStr(pwzData); + ReleaseStr(pwzComponent); + + return hr; +} + + +HRESULT ScaSqlStrsReadScripts( + __inout SCA_SQLSTR** ppsssList, + __in SCA_ACTION saAction + ) +{ + HRESULT hr = S_OK; + UINT er = ERROR_SUCCESS; + + PMSIHANDLE hView, hRec; + PMSIHANDLE hViewBinary, hRecBinary; + PMSIHANDLE hViewUser, hRecUser; + + LPWSTR pwzComponent = NULL; + LPWSTR pwzData = NULL; + + BYTE* pbScript = NULL; + DWORD cbRead = 0; + DWORD cbScript = 0; + DWORD cchScript = 0; + + LPWSTR pwzScriptBuffer = NULL; + WCHAR* pwzScript = NULL; + WCHAR* pwz; + DWORD cch = 0; + + SCA_SQLSTR sss; + SCA_SQLSTR* psss = NULL; + + if (S_OK != WcaTableExists(L"Wix4SqlScript") || S_OK != WcaTableExists(L"Wix4SqlDatabase") || S_OK != WcaTableExists(L"Binary")) + { + WcaLog(LOGMSG_VERBOSE, "Skipping ScaSqlStrsReadScripts() - Wix4SqlScript and/or Wix4SqlDatabase table not present"); + ExitFunction1(hr = S_FALSE); + } + + // open a view on the binary table + hr = WcaOpenView(vcsSqlBinaryScriptQuery, &hViewBinary); + ExitOnFailure(hr, "Failed to open view on Binary table for SQL scripts"); + + // loop through all the sql scripts + hr = WcaOpenExecuteView(vcsSqlScriptQuery, &hView); + ExitOnFailure(hr, "Failed to open view on Wix4SqlScript table"); + while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) + { + INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; + INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; + + hr = WcaGetRecordString(hRec, sscrqComponent, &pwzComponent); + ExitOnFailure(hr, "Failed to get Component for SQL Script."); + + er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "Failed to get state for component: %ls", pwzComponent); + + // If we're doing install but the Component is not being installed or we're doing + // uninstall but the Component is not being uninstalled, skip it. + if ((WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL != saAction) || + (WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL != saAction)) + { + continue; + } + + ::ZeroMemory(&sss, sizeof(sss)); + + sss.isInstalled = isInstalled; + sss.isAction = isAction; + + hr = WcaGetRecordString(hRec, sscrqSqlScript, &pwzData); + ExitOnFailure(hr, "Failed to get Wix4SqlScript.Script"); + hr = ::StringCchCopyW(sss.wzKey, countof(sss.wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy Wix4SqlScript.Script: %ls", pwzData); + + // find the database information for this string + hr = WcaGetRecordString(hRec, sscrqSqlDb, &pwzData); + ExitOnFailure(hr, "Failed to get Wix4SqlScript.SqlDb_ for SqlScript '%ls'", sss.wzKey); + hr = ::StringCchCopyW(sss.wzSqlDb, countof(sss.wzSqlDb), pwzData); + ExitOnFailure(hr, "Failed to copy Wix4SqlScript.SqlDbb: %ls", pwzData); + + hr = WcaGetRecordInteger(hRec, sscrqAttributes, &sss.iAttributes); + ExitOnFailure(hr, "Failed to get Wix4SqlScript.Attributes for SqlScript '%ls'", sss.wzKey); + + hr = WcaGetRecordInteger(hRec, sscrqSequence, &sss.iSequence); + ExitOnFailure(hr, "Failed to get Wix4SqlScript.Sequence for SqlScript '%ls'", sss.wzKey); + + // get the sql script out of the binary stream + hr = WcaExecuteView(hViewBinary, hRec); + ExitOnFailure(hr, "Failed to open Wix4SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey); + hr = WcaFetchSingleRecord(hViewBinary, &hRecBinary); + ExitOnFailure(hr, "Failed to fetch Wix4SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey); + + // Note: We need to allocate an extra character on the stream to NULL terminate the SQL script. + // The WcaGetRecordStream() function won't let us add extra space on the end of the stream + // so we'll read the stream "the old fashioned way". + //hr = WcaGetRecordStream(hRecBinary, ssbsqData, (BYTE**)&pbScript, &cbScript); + //ExitOnFailure(hr, "Failed to read Wix4SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey); + er = ::MsiRecordReadStream(hRecBinary, ssbsqData, NULL, &cbRead); + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to get size of stream"); + + cbScript = cbRead + sizeof(WCHAR); // we may have an ANSI SQL script but leave enough to even NULL terminate a WCHAR string + hr = WcaAllocStream(&pbScript, cbScript); // this will allocate a fully zeroed out buffer so our string will be NULL terminated + ExitOnFailure(hr, "failed to allocate data for stream"); + + er = ::MsiRecordReadStream(hRecBinary, ssbsqData, reinterpret_cast(pbScript), &cbRead); //read the buffer but leave the space for the NULL terminator + hr = HRESULT_FROM_WIN32(er); + ExitOnFailure(hr, "failed to read from stream"); + + Assert(cbRead + sizeof(WCHAR) == cbScript); + + // Check for the UNICODE BOM file marker. + if ((0xFF == *pbScript) && (0xFE == *(pbScript + 1))) + { + // Copy the UNICODE string after the BOM marker (subtract one because we'll skip the BOM marker). + cchScript = (cbScript / sizeof(WCHAR)) - 1; + + hr = StrAllocString(&pwzScriptBuffer, reinterpret_cast(pbScript) + 1, 0); + ExitOnFailure(hr, "Failed to allocate WCHAR string of size '%d'", cchScript); + } + else + { + // We have an ANSI string so convert it to UNICODE. + cchScript = cbScript; + + hr = StrAllocStringAnsi(&pwzScriptBuffer, reinterpret_cast(pbScript), 0, CP_ACP); + ExitOnFailure(hr, "Failed to allocate WCHAR string of size '%d'", cchScript); + } + + // Free the byte buffer since it has been converted to a new UNICODE string, one way or another. + if (pbScript) + { + WcaFreeStream(pbScript); + pbScript = NULL; + } + + // Process the SQL script stripping out unnecessary stuff (like comments) and looking for "GO" statements. + pwzScript = pwzScriptBuffer; + while (cchScript && pwzScript && *pwzScript) + { + // strip off leading whitespace + while (cchScript && *pwzScript && iswspace(*pwzScript)) + { + ++pwzScript; + --cchScript; + } + + Assert(0 <= cchScript); + + // if there is a SQL comment remove it + while (cchScript && L'/' == *pwzScript && L'*' == *(pwzScript + 1)) + { + // go until end of comment + while (cchScript && *pwzScript && *(pwzScript + 1) && !(L'*' == *pwzScript && L'/' == *(pwzScript + 1))) + { + ++pwzScript; + --cchScript; + } + + Assert(2 <= cchScript); + + if (2 <= cchScript) + { + // to account for */ at end + pwzScript+=2; + cchScript-=2; + } + + Assert(0 <= cchScript); + + // strip off any new leading whitespace + while (cchScript && *pwzScript && iswspace(*pwzScript)) + { + ++pwzScript; + --cchScript; + } + } + + while (cchScript && L'-' == *pwzScript && L'-' == *(pwzScript + 1)) + { + // go past the new line character + while (cchScript && *pwzScript && L'\n' != *pwzScript) + { + ++pwzScript; + --cchScript; + } + + Assert(0 <= cchScript); + + if (cchScript && L'\n' == *pwzScript) + { + ++pwzScript; + --cchScript; + } + + Assert(0 <= cchScript); + + // strip off any new leading whitespace + while (cchScript && *pwzScript && iswspace(*pwzScript)) + { + ++pwzScript; + --cchScript; + } + } + + Assert(0 <= cchScript); + + // try to isolate a "GO" keyword and count the characters in the SQL string + pwz = pwzScript; + cch = 0; + while (cchScript && *pwz) + { + //skip past comment lines that might have "go" in them + //note that these comments are "in the middle" of our function, + //or possibly at the end of a line + if (cchScript && L'-' == *pwz && L'-' == *(pwz + 1)) + { + // skip past chars until the new line character + while (cchScript && *pwz && (L'\n' != *pwz)) + { + ++pwz; + ++cch; + --cchScript; + } + } + + //skip past comment lines of form /* to */ that might have "go" in them + //note that these comments are "in the middle" of our function, + //or possibly at the end of a line + if (cchScript && L'/' == *pwz && L'*' == *(pwz + 1)) + { + // skip past chars until the new line character + while (cchScript && *pwz && *(pwz + 1) && !((L'*' == *pwz) && (L'/' == *(pwz + 1)))) + { + ++pwz; + ++cch; + --cchScript; + } + + if (2 <= cchScript) + { + // to account for */ at end + pwz+=2; + cch+=2; + cchScript-=2; + } + } + + // Skip past strings that may be part of the SQL statement that might have a "go" in them + if ( cchScript && L'\'' == *pwz ) + { + ++pwz; + ++cch; + --cchScript; + + // Skip past chars until the end of the string + while ( cchScript && *pwz && !(L'\'' == *pwz) ) + { + ++pwz; + ++cch; + --cchScript; + } + } + + // Skip past strings that may be part of the SQL statement that might have a "go" in them + if ( cchScript && L'\"' == *pwz ) + { + ++pwz; + ++cch; + --cchScript; + + // Skip past chars until the end of the string + while ( cchScript && *pwz && !(L'\"' == *pwz) ) + { + ++pwz; + ++cch; + --cchScript; + } + } + + // if "GO" is isolated + if ((pwzScript == pwz || iswspace(*(pwz - 1))) && + (L'G' == *pwz || L'g' == *pwz) && + (L'O' == *(pwz + 1) || L'o' == *(pwz + 1)) && + (0 == *(pwz + 2) || iswspace(*(pwz + 2)))) + { + *pwz = 0; // null terminate the SQL string on the "G" + pwz += 2; + cchScript -= 2; + break; // found "GO" now add SQL string to list + } + + ++pwz; + ++cch; + --cchScript; + } + + Assert(0 <= cchScript); + + if (0 < cch) //don't process if there's nothing to process + { + // replace tabs with spaces + for (LPWSTR pwzTab = wcsstr(pwzScript, L"\t"); pwzTab; pwzTab = wcsstr(pwzTab, L"\t")) + *pwzTab = ' '; + + // strip off whitespace at the end of the script string + for (LPWSTR pwzErase = pwzScript + cch - 1; pwzScript < pwzErase && iswspace(*pwzErase); pwzErase--) + { + *(pwzErase) = 0; + cch--; + } + } + + if (0 < cch) + { + hr = NewSqlStr(&psss); + ExitOnFailure(hr, "failed to allocate new sql string element"); + + // copy everything over + hr = ::StringCchCopyW(psss->wzKey, countof(psss->wzKey), sss.wzKey); + ExitOnFailure(hr, "Failed to copy key string to sqlstr object"); + hr = ::StringCchCopyW(psss->wzSqlDb, countof(psss->wzSqlDb), sss.wzSqlDb); + ExitOnFailure(hr, "Failed to copy DB string to sqlstr object"); + hr = ::StringCchCopyW(psss->wzComponent, countof(psss->wzComponent), sss.wzComponent); + ExitOnFailure(hr, "Failed to copy component string to sqlstr object"); + psss->isInstalled = sss.isInstalled; + psss->isAction = sss.isAction; + psss->iAttributes = sss.iAttributes; + psss->iSequence = sss.iSequence; + + // cchRequired includes the NULL terminating char + hr = StrAllocString(&psss->pwzSql, pwzScript, 0); + ExitOnFailure(hr, "Failed to allocate string for SQL script: '%ls'", psss->wzKey); + + *ppsssList = AddSqlStrToList(*ppsssList, psss); + psss = NULL; // set the db NULL so it doesn't accidentally get freed below + } + + pwzScript = pwz; + } + } + + if (E_NOMOREITEMS == hr) + { + hr = S_OK; + } + ExitOnFailure(hr, "Failure occured while reading Wix4SqlScript table"); + +LExit: + // if anything was left over after an error clean it all up + if (psss) + { + ScaSqlStrsFreeList(psss); + } + + if (pbScript) + { + WcaFreeStream(pbScript); + } + + ReleaseStr(pwzScriptBuffer); + ReleaseStr(pwzData); + ReleaseStr(pwzComponent); + + return hr; +} + + +HRESULT ScaSqlStrsInstall( + __in SCA_DB* psdList, + __in SCA_SQLSTR* psssList + ) +{ + HRESULT hr = ExecuteStrings(psdList, psssList, TRUE); + + return hr; +} + + +HRESULT ScaSqlStrsUninstall( + __in SCA_DB* psdList, + __in SCA_SQLSTR* psssList + ) +{ + HRESULT hr = ExecuteStrings(psdList, psssList, FALSE); + + return hr; +} + + +void ScaSqlStrsFreeList( + __in SCA_SQLSTR* psssList + ) +{ + SCA_SQLSTR* psssDelete = psssList; + while (psssList) + { + psssDelete = psssList; + psssList = psssList->psssNext; + + if (psssDelete->pwzSql) + { + ReleaseStr(psssDelete->pwzSql); + } + + MemFree(psssDelete); + } +} + + +// private helper functions + +static HRESULT NewSqlStr( + __out SCA_SQLSTR** ppsss + ) +{ + HRESULT hr = S_OK; + SCA_SQLSTR* psss = static_cast(MemAlloc(sizeof(SCA_SQLSTR), TRUE)); + ExitOnNull(psss, hr, E_OUTOFMEMORY, "failed to allocate memory for new sql string element"); + + *ppsss = psss; + +LExit: + return hr; +} + + +static SCA_SQLSTR* AddSqlStrToList( + __in SCA_SQLSTR* psssList, + __in SCA_SQLSTR* psss + ) +{ + Assert(psss); //just checking + + //make certain we have a valid sequence number; note that negatives are technically valid + if (MSI_NULL_INTEGER == psss->iSequence) + { + psss->iSequence = 0; + } + + if (psssList) + { + //list already exists, so insert psss into the list in Sequence order + + //see if we need to change the head, otherwise figure out where in the order it fits + if (psss->iSequence < psssList->iSequence) + { + psss->psssNext = psssList; + psssList = psss; + } + else + { + SCA_SQLSTR* psssT = psssList; + //note that if Sequence numbers are duplicated, as in the case of a sqlscript, + //we need to insert them "at the end" of the group so the sqlfile stays in order + while (psssT->psssNext && (psssT->psssNext->iSequence <= psss->iSequence)) + { + psssT = psssT->psssNext; + } + + //insert our new psss AFTER psssT + psss->psssNext = psssT->psssNext; + psssT->psssNext = psss; + } + } + else + { + psssList = psss; + } + + return psssList; +} + + +static HRESULT ExecuteStrings( + __in SCA_DB* psdList, + __in SCA_SQLSTR* psssList, + __in BOOL fInstall + ) +{ + HRESULT hr = S_FALSE; // assume nothing will be done + + int iRollback = -1; + int iOldRollback = iRollback; + + LPCWSTR wzOldDb = NULL; + UINT uiCost = 0; + WCHAR* pwzCustomActionData = NULL; + WCHAR wzNumber[64]; + + // loop through all sql strings + for (SCA_SQLSTR* psss = psssList; psss; psss = psss->psssNext) + { + // if installing this component + if ((fInstall && (psss->iAttributes & SCASQL_EXECUTE_ON_INSTALL) && WcaIsInstalling(psss->isInstalled, psss->isAction) && !WcaIsReInstalling(psss->isInstalled, psss->isAction)) || + (fInstall && (psss->iAttributes & SCASQL_EXECUTE_ON_REINSTALL) && WcaIsReInstalling(psss->isInstalled, psss->isAction)) || + (!fInstall && (psss->iAttributes & SCASQL_EXECUTE_ON_UNINSTALL) && WcaIsUninstalling(psss->isInstalled, psss->isAction))) + { + // determine if this is a rollback scheduling or normal deferred scheduling + if (psss->iAttributes & SCASQL_ROLLBACK) + { + iRollback = 1; + } + else + { + iRollback = 0; + } + + // if we need to create a connection to a new server\database + if (!wzOldDb || 0 != lstrcmpW(wzOldDb, psss->wzSqlDb) || iOldRollback != iRollback) + { + const SCA_DB* psd = ScaDbsFindDatabase(psss->wzSqlDb, psdList); + if (!psd) + { + ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "failed to find data for Database: %ls", psss->wzSqlDb); + } + + if (-1 == iOldRollback) + { + iOldRollback = iRollback; + } + Assert(0 == iOldRollback || 1 == iOldRollback); + + // if there was custom action data before, schedule the action to write it + if (pwzCustomActionData && *pwzCustomActionData) + { + Assert(pwzCustomActionData && *pwzCustomActionData && uiCost); + + hr = WcaDoDeferredAction(1 == iOldRollback ? CUSTOM_ACTION_DECORATION(L"RollbackExecuteSqlStrings") : CUSTOM_ACTION_DECORATION(L"ExecuteSqlStrings"), pwzCustomActionData, uiCost); + ExitOnFailure(hr, "failed to schedule ExecuteSqlStrings action, rollback: %d", iOldRollback); + iOldRollback = iRollback; + + *pwzCustomActionData = L'\0'; + uiCost = 0; + } + + Assert(!pwzCustomActionData || (pwzCustomActionData && 0 == *pwzCustomActionData) && 0 == uiCost); + + hr = WcaWriteStringToCaData(psd->wzKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add SQL Server Database String to CustomActionData for Database String: %ls", psd->wzKey); + + hr = WcaWriteStringToCaData(psd->wzServer, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add SQL Server to CustomActionData for Database String: %ls", psd->wzKey); + + hr = WcaWriteStringToCaData(psd->wzInstance, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add SQL Instance to CustomActionData for Database String: %ls", psd->wzKey); + + hr = WcaWriteStringToCaData(psd->wzDatabase, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add SQL Database to CustomActionData for Database String: %ls", psd->wzKey); + + hr = ::StringCchPrintfW(wzNumber, countof(wzNumber), L"%d", psd->iAttributes); + ExitOnFailure(hr, "Failed to format attributes integer value to string"); + hr = WcaWriteStringToCaData(wzNumber, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add SQL Attributes to CustomActionData for Database String: %ls", psd->wzKey); + + hr = ::StringCchPrintfW(wzNumber, countof(wzNumber), L"%d", psd->fUseIntegratedAuth); + ExitOnFailure(hr, "Failed to format UseIntegratedAuth integer value to string"); + hr = WcaWriteStringToCaData(wzNumber, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add SQL IntegratedAuth flag to CustomActionData for Database String: %ls", psd->wzKey); + + hr = WcaWriteStringToCaData(psd->scau.wzName, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add SQL UserName to CustomActionData for Database String: %ls", psd->wzKey); + + hr = WcaWriteStringToCaData(psd->scau.wzPassword, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add SQL Password to CustomActionData for Database String: %ls", psd->wzKey); + + uiCost += COST_SQL_CONNECTDB; + + wzOldDb = psss->wzSqlDb; + } + + WcaLog(LOGMSG_VERBOSE, "Scheduling SQL string: %ls", psss->pwzSql); + + hr = WcaWriteStringToCaData(psss->wzKey, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to add SQL Key to CustomActionData for SQL string: %ls", psss->wzKey); + + hr = WcaWriteIntegerToCaData(psss->iAttributes, &pwzCustomActionData); + ExitOnFailure(hr, "failed to add attributes to CustomActionData for SQL string: %ls", psss->wzKey); + + hr = WcaWriteStringToCaData(psss->pwzSql, &pwzCustomActionData); + ExitOnFailure(hr, "Failed to to add SQL Query to CustomActionData for SQL string: %ls", psss->wzKey); + uiCost += COST_SQL_STRING; + } + } + + if (pwzCustomActionData && *pwzCustomActionData) + { + Assert(pwzCustomActionData && *pwzCustomActionData && uiCost); + hr = WcaDoDeferredAction(1 == iRollback ? CUSTOM_ACTION_DECORATION(L"RollbackExecuteSqlStrings") : CUSTOM_ACTION_DECORATION(L"ExecuteSqlStrings"), pwzCustomActionData, uiCost); + ExitOnFailure(hr, "Failed to schedule ExecuteSqlStrings action"); + + *pwzCustomActionData = L'\0'; + uiCost = 0; + } + +LExit: + ReleaseStr(pwzCustomActionData); + + return hr; +} diff --git a/src/ext/Sql/ca/scasqlstr.h b/src/ext/Sql/ca/scasqlstr.h new file mode 100644 index 00000000..72c1d770 --- /dev/null +++ b/src/ext/Sql/ca/scasqlstr.h @@ -0,0 +1,51 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +#include "scadb.h" + +struct SCA_SQLSTR +{ + // darwin information + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + INSTALLSTATE isInstalled, isAction; + + WCHAR wzSqlDb[MAX_DARWIN_COLUMN + 1]; + + BOOL fHasUser; + SCA_USER scau; + + LPWSTR pwzSql; + int iAttributes; + int iSequence; //used to sequence Wix4SqlString and Wix4SqlScript tables together + + SCA_SQLSTR* psssNext; +}; + + +// prototypes +HRESULT ScaSqlStrsRead( + __inout SCA_SQLSTR** ppsssList, + __in SCA_ACTION saAction + ); + +HRESULT ScaSqlStrsReadScripts( + __inout SCA_SQLSTR** ppsssList, + __in SCA_ACTION saAction + ); + +HRESULT ScaSqlStrsInstall( + __in SCA_DB* psdList, + __in SCA_SQLSTR* psssList + ); + +HRESULT ScaSqlStrsUninstall( + __in SCA_DB* psdList, + __in SCA_SQLSTR* psssList + ); + +void ScaSqlStrsFreeList( + __in SCA_SQLSTR* psssList + ); + diff --git a/src/ext/Sql/ca/scauser.cpp b/src/ext/Sql/ca/scauser.cpp new file mode 100644 index 00000000..4d74e4d4 --- /dev/null +++ b/src/ext/Sql/ca/scauser.cpp @@ -0,0 +1,82 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" + +LPCWSTR vcsUserQuery = L"SELECT `User`, `Component_`, `Name`, `Domain`, `Password` FROM `User` WHERE `User`=?"; +enum eUserQuery { vuqUser = 1, vuqComponent, vuqName, vuqDomain, vuqPassword }; + + +HRESULT __stdcall ScaGetUser( + __in LPCWSTR wzUser, + __out SCA_USER* pscau + ) +{ + if (!wzUser || !pscau) + { + return E_INVALIDARG; + } + + HRESULT hr = S_OK; + PMSIHANDLE hView, hRec; + + LPWSTR pwzData = NULL; + + // clear struct and bail right away if no user key was passed to search for + ::ZeroMemory(pscau, sizeof(*pscau)); + if (!*wzUser) + { + ExitFunction1(hr = S_OK); + } + + hRec = ::MsiCreateRecord(1); + hr = WcaSetRecordString(hRec, 1, wzUser); + ExitOnFailure(hr, "Failed to look up User"); + + hr = WcaOpenView(vcsUserQuery, &hView); + ExitOnFailure(hr, "Failed to open view on User table"); + hr = WcaExecuteView(hView, hRec); + ExitOnFailure(hr, "Failed to execute view on User table"); + + hr = WcaFetchSingleRecord(hView, &hRec); + if (S_OK == hr) + { + hr = WcaGetRecordString(hRec, vuqUser, &pwzData); + ExitOnFailure(hr, "Failed to get User.User"); + hr = ::StringCchCopyW(pscau->wzKey, countof(pscau->wzKey), pwzData); + ExitOnFailure(hr, "Failed to copy key string to user object"); + + hr = WcaGetRecordString(hRec, vuqComponent, &pwzData); + ExitOnFailure(hr, "Failed to get User.Component_"); + hr = ::StringCchCopyW(pscau->wzComponent, countof(pscau->wzComponent), pwzData); + ExitOnFailure(hr, "Failed to copy component string to user object"); + + hr = WcaGetRecordFormattedString(hRec, vuqName, &pwzData); + ExitOnFailure(hr, "Failed to get User.Name"); + hr = ::StringCchCopyW(pscau->wzName, countof(pscau->wzName), pwzData); + ExitOnFailure(hr, "Failed to copy name string to user object"); + + hr = WcaGetRecordFormattedString(hRec, vuqDomain, &pwzData); + ExitOnFailure(hr, "Failed to get User.Domain"); + hr = ::StringCchCopyW(pscau->wzDomain, countof(pscau->wzDomain), pwzData); + ExitOnFailure(hr, "Failed to copy domain string to user object"); + + hr = WcaGetRecordFormattedString(hRec, vuqPassword, &pwzData); + ExitOnFailure(hr, "Failed to get User.Password"); + hr = ::StringCchCopyW(pscau->wzPassword, countof(pscau->wzPassword), pwzData); + ExitOnFailure(hr, "Failed to copy password string to user object"); + } + else if (E_NOMOREITEMS == hr) + { + WcaLog(LOGMSG_STANDARD, "Error: Cannot locate User.User='%ls'", wzUser); + hr = E_FAIL; + } + else + { + ExitOnFailure(hr, "Error or found multiple matching User rows"); + } + +LExit: + ReleaseStr(pwzData); + + return hr; +} diff --git a/src/ext/Sql/ca/scauser.h b/src/ext/Sql/ca/scauser.h new file mode 100644 index 00000000..20e561f2 --- /dev/null +++ b/src/ext/Sql/ca/scauser.h @@ -0,0 +1,40 @@ +#pragma once +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + + +// structs +struct SCA_GROUP +{ + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + + WCHAR wzDomain[MAX_DARWIN_COLUMN + 1]; + WCHAR wzName[MAX_DARWIN_COLUMN + 1]; + + SCA_GROUP *psgNext; +}; + +struct SCA_USER +{ + WCHAR wzKey[MAX_DARWIN_KEY + 1]; + WCHAR wzComponent[MAX_DARWIN_KEY + 1]; + INSTALLSTATE isInstalled; + INSTALLSTATE isAction; + + WCHAR wzDomain[MAX_DARWIN_COLUMN + 1]; + WCHAR wzName[MAX_DARWIN_COLUMN + 1]; + WCHAR wzPassword[MAX_DARWIN_COLUMN + 1]; + INT iAttributes; + + SCA_GROUP *psgGroups; + + SCA_USER *psuNext; +}; + + +// prototypes +HRESULT __stdcall ScaGetUser( + __in LPCWSTR wzUser, + __out SCA_USER* pscau + ); diff --git a/src/ext/Sql/ca/sqlca.cpp b/src/ext/Sql/ca/sqlca.cpp new file mode 100644 index 00000000..37664a1c --- /dev/null +++ b/src/ext/Sql/ca/sqlca.cpp @@ -0,0 +1,3 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" diff --git a/src/ext/Sql/ca/sqlca.def b/src/ext/Sql/ca/sqlca.def new file mode 100644 index 00000000..e899d560 --- /dev/null +++ b/src/ext/Sql/ca/sqlca.def @@ -0,0 +1,13 @@ +; Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + + +LIBRARY "sqlca" + +EXPORTS +;scaexec.cpp + CreateDatabase + DropDatabase + ExecuteSqlStrings +;scasql.cpp + InstallSqlData + UninstallSqlData diff --git a/src/ext/Sql/ca/sqlca.vcxproj b/src/ext/Sql/ca/sqlca.vcxproj new file mode 100644 index 00000000..18becc5f --- /dev/null +++ b/src/ext/Sql/ca/sqlca.vcxproj @@ -0,0 +1,83 @@ + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + + {4DCA6E4B-A1F1-4450-BC2D-94AC20F31935} + DynamicLibrary + sqlca + v142 + Unicode + sqlca.def + WiX Toolset Sql CustomAction + + + + + + + msi.lib + + + + + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Sql/nuget.config b/src/ext/Sql/nuget.config new file mode 100644 index 00000000..db7aba29 --- /dev/null +++ b/src/ext/Sql/nuget.config @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ext/Sql/test/WixToolsetTest.Sql/SqlExtensionFixture.cs b/src/ext/Sql/test/WixToolsetTest.Sql/SqlExtensionFixture.cs new file mode 100644 index 00000000..aa9d7a1f --- /dev/null +++ b/src/ext/Sql/test/WixToolsetTest.Sql/SqlExtensionFixture.cs @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolsetTest.Sql +{ + using System.Linq; + using WixBuildTools.TestSupport; + using WixToolset.Core.TestPackage; + using WixToolset.Sql; + using Xunit; + + public class SqlExtensionFixture + { + [Fact] + public void CanBuildUsingSqlStuff() + { + var folder = TestData.Get(@"TestData\UsingSql"); + var build = new Builder(folder, typeof(SqlExtensionFactory), new[] { folder }); + + var results = build.BuildAndQuery(Build, "Wix4SqlDatabase", "Wix4SqlFileSpec", "Wix4SqlScript", "Wix4SqlString"); + WixAssert.CompareLineByLine(new[] + { + "Wix4SqlDatabase:TestDB\tMySQLHostName\tMyInstanceName\tMyDB\tDatabaseComponent\t\tTestFileSpecId\tTestLogFileSpecId\t35", + "Wix4SqlFileSpec:TestFileSpecId\tTestFileSpecLogicalName\tTestFileSpec\t10MB\t100MB\t10%", + "Wix4SqlFileSpec:TestLogFileSpecId\tTestLogFileSpecLogicalName\tTestLogFileSpec\t1MB\t10MB\t1%", + "Wix4SqlScript:TestScript\tTestDB\tDatabaseComponent\tScriptBinary\t\t1\t", + "Wix4SqlString:TestString\tTestDB\tDatabaseComponent\tCREATE TABLE TestTable1(name varchar(20), value varchar(20))\t\t1\t", + }, results.ToArray()); + } + + private static void Build(string[] args) + { + var result = WixRunner.Execute(args) + .AssertSuccess(); + } + } +} diff --git a/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/Package.en-us.wxl b/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/Package.en-us.wxl new file mode 100644 index 00000000..38c12ac1 --- /dev/null +++ b/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/Package.en-us.wxl @@ -0,0 +1,11 @@ + + + + + + A newer version of [ProductName] is already installed. + MsiPackage + + diff --git a/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/Package.wxs b/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/Package.wxs new file mode 100644 index 00000000..ee3bc921 --- /dev/null +++ b/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/Package.wxs @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/PackageComponents.wxs b/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/PackageComponents.wxs new file mode 100644 index 00000000..f7626926 --- /dev/null +++ b/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/PackageComponents.wxs @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/example.txt b/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/example.txt new file mode 100644 index 00000000..1b4ffe8a --- /dev/null +++ b/src/ext/Sql/test/WixToolsetTest.Sql/TestData/UsingSql/example.txt @@ -0,0 +1 @@ +This is example.txt. \ No newline at end of file diff --git a/src/ext/Sql/test/WixToolsetTest.Sql/WixToolsetTest.Sql.csproj b/src/ext/Sql/test/WixToolsetTest.Sql/WixToolsetTest.Sql.csproj new file mode 100644 index 00000000..bbf3041d --- /dev/null +++ b/src/ext/Sql/test/WixToolsetTest.Sql/WixToolsetTest.Sql.csproj @@ -0,0 +1,38 @@ + + + + + + netcoreapp3.1 + false + + + + NU1701 + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Sql/test/WixToolsetTest.Sql/WixToolsetTest.Sql.v3.ncrunchproject b/src/ext/Sql/test/WixToolsetTest.Sql/WixToolsetTest.Sql.v3.ncrunchproject new file mode 100644 index 00000000..7b5b2139 --- /dev/null +++ b/src/ext/Sql/test/WixToolsetTest.Sql/WixToolsetTest.Sql.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/src/ext/Sql/wix.snk b/src/ext/Sql/wix.snk new file mode 100644 index 00000000..3908a66a Binary files /dev/null and b/src/ext/Sql/wix.snk differ diff --git a/src/ext/Sql/wixext/SqlCompiler.cs b/src/ext/Sql/wixext/SqlCompiler.cs new file mode 100644 index 00000000..46196e95 --- /dev/null +++ b/src/ext/Sql/wixext/SqlCompiler.cs @@ -0,0 +1,804 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using System; + using System.Collections.Generic; + using System.Xml.Linq; + using WixToolset.Data; + using WixToolset.Extensibility; + using WixToolset.Extensibility.Data; + using WixToolset.Sql.Symbols; + + /// + /// The compiler for the WiX Toolset SQL Server Extension. + /// + public sealed class SqlCompiler : BaseCompilerExtension + { + // sql database attributes definitions (from sca.h) + internal const int DbCreateOnInstall = 0x00000001; + internal const int DbDropOnUninstall = 0x00000002; + internal const int DbContinueOnError = 0x00000004; + internal const int DbDropOnInstall = 0x00000008; + internal const int DbCreateOnUninstall = 0x00000010; + internal const int DbConfirmOverwrite = 0x00000020; + internal const int DbCreateOnReinstall = 0x00000040; + internal const int DbDropOnReinstall = 0x00000080; + + // sql string/script attributes definitions (from sca.h) + internal const int SqlExecuteOnInstall = 0x00000001; + internal const int SqlExecuteOnUninstall = 0x00000002; + internal const int SqlContinueOnError = 0x00000004; + internal const int SqlRollback = 0x00000008; + internal const int SqlExecuteOnReinstall = 0x00000010; + + public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/sql"; + + /// + /// Processes an element for the Compiler. + /// + /// + /// + /// Parent element of element to process. + /// Element to process. + /// Extra information about the context in which this element is being parsed. + public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary context) + { + switch (parentElement.Name.LocalName) + { + case "Component": + var componentId = context["ComponentId"]; + + switch (element.Name.LocalName) + { + case "SqlDatabase": + this.ParseSqlDatabaseElement(intermediate, section, element, componentId); + break; + case "SqlScript": + this.ParseSqlScriptElement(intermediate, section, element, componentId, null); + break; + case "SqlString": + this.ParseSqlStringElement(intermediate, section, element, componentId, null); + break; + default: + this.ParseHelper.UnexpectedElement(parentElement, element); + break; + } + break; + case "Fragment": + case "Module": + case "Package": + switch (element.Name.LocalName) + { + case "SqlDatabase": + this.ParseSqlDatabaseElement(intermediate, section, element, null); + break; + default: + this.ParseHelper.UnexpectedElement(parentElement, element); + break; + } + break; + default: + this.ParseHelper.UnexpectedElement(parentElement, element); + break; + } + } + + /// + /// Parses a sql database element + /// + /// + /// + /// Element to parse. + /// Identifier for parent component. + private void ParseSqlDatabaseElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + int attributes = 0; + string database = null; + Identifier fileSpec = null; + string instance = null; + Identifier logFileSpec = null; + string server = null; + string user = null; + + foreach (var attrib in element.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "Id": + id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); + break; + case "ConfirmOverwrite": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= DbConfirmOverwrite; + } + break; + case "ContinueOnError": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= DbContinueOnError; + } + break; + case "CreateOnInstall": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= DbCreateOnInstall; + } + break; + case "CreateOnReinstall": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= DbCreateOnReinstall; + } + break; + case "CreateOnUninstall": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= DbCreateOnUninstall; + } + break; + case "Database": + database = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "DropOnInstall": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= DbDropOnInstall; + } + break; + case "DropOnReinstall": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= DbDropOnReinstall; + } + break; + + case "DropOnUninstall": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); + } + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= DbDropOnUninstall; + } + break; + case "Instance": + instance = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Server": + server = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "User": + user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + if (!this.ParseHelper.ContainsProperty(user)) + { + user = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user); + } + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("sdb", componentId, server, database); + } + + if (null == database) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Database")); + } + else if (128 < database.Length) + { + this.Messaging.Write(ErrorMessages.IdentifierTooLongError(sourceLineNumbers, element.Name.LocalName, "Database", database, 128)); + } + + if (null == server) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Server")); + } + + if (0 == attributes && null != componentId) + { + this.Messaging.Write(SqlErrors.OneOfAttributesRequiredUnderComponent(sourceLineNumbers, element.Name.LocalName, "CreateOnInstall", "CreateOnUninstall", "DropOnInstall", "DropOnUninstall")); + } + + foreach (var child in element.Elements()) + { + if (this.Namespace == child.Name.Namespace) + { + var childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); + switch (child.Name.LocalName) + { + case "SqlScript": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + this.ParseSqlScriptElement(intermediate, section, child, componentId, id?.Id); + break; + case "SqlString": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + + this.ParseSqlStringElement(intermediate, section, child, componentId, id?.Id); + break; + case "SqlFileSpec": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + else if (null != fileSpec) + { + this.Messaging.Write(ErrorMessages.TooManyElements(sourceLineNumbers, element.Name.LocalName, child.Name.LocalName, 1)); + } + + fileSpec = this.ParseSqlFileSpecElement(intermediate, section, child, id?.Id); + break; + case "SqlLogFileSpec": + if (null == componentId) + { + this.Messaging.Write(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); + } + else if (null != logFileSpec) + { + this.Messaging.Write(ErrorMessages.TooManyElements(sourceLineNumbers, element.Name.LocalName, child.Name.LocalName, 1)); + } + + logFileSpec = this.ParseSqlFileSpecElement(intermediate, section, child, id?.Id); + break; + default: + this.ParseHelper.UnexpectedElement(element, child); + break; + } + } + else + { + this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); + } + } + + if (null != componentId) + { + // Reference InstallSqlData and UninstallSqlData since nothing will happen without it + this.AddReferenceToInstallSqlData(section, sourceLineNumbers); + } + + if (!this.Messaging.EncounteredError) + { + var symbol = section.AddSymbol(new SqlDatabaseSymbol(sourceLineNumbers, id) + { + Server = server, + Instance = instance, + Database = database, + ComponentRef = componentId, + UserRef = user, + FileSpecRef = fileSpec?.Id, + LogFileSpecRef = logFileSpec?.Id, + }); + + if (0 != attributes) + { + symbol.Attributes = attributes; + } + } + } + + /// + /// Parses a sql file specification element. + /// + /// + /// + /// Element to parse. + /// Identifier of sql file specification. + private Identifier ParseSqlFileSpecElement(Intermediate intermediate, IntermediateSection section, XElement element, string parentId) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + string fileName = null; + string growthSize = null; + string maxSize = null; + string name = null; + string size = null; + + foreach (var attrib in element.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "Id": + id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); + break; + case "Name": + name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Filename": + fileName = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Size": + size = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "MaxSize": + maxSize = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "GrowthSize": + growthSize = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("sfs", parentId, name, fileName); + } + + if (null == name) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); + } + + if (null == fileName) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Filename")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + if (!this.Messaging.EncounteredError) + { + var symbol = section.AddSymbol(new SqlFileSpecSymbol(sourceLineNumbers, id) + { + Name = name, + Filename = fileName, + }); + + if (null != size) + { + symbol.Size = size; + } + + if (null != maxSize) + { + symbol.MaxSize = maxSize; + } + + if (null != growthSize) + { + symbol.GrowthSize = growthSize; + } + } + + return id; + } + + /// + /// Parses a sql script element. + /// + /// Element to parse. + /// Identifier for parent component. + /// Optional database to execute script against. + private void ParseSqlScriptElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string sqlDb) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + int attributes = 0; + var rollbackAttribute = false; + var nonRollbackAttribute = false; + string binaryRef = null; + var sequence = CompilerConstants.IntegerNotSet; + string user = null; + + foreach (var attrib in element.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "Id": + id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); + break; + case "BinaryRef": + binaryRef = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Binary, binaryRef); + break; + case "Sequence": + sequence = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); + break; + case "SqlDb": + if (null != sqlDb) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, element.Parent.Name.LocalName)); + } + sqlDb = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SqlSymbolDefinitions.SqlDatabase, sqlDb); + break; + case "User": + user = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user); + break; + + // Flag-setting attributes + case "ContinueOnError": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlContinueOnError; + } + break; + case "ExecuteOnInstall": + if (rollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); + } + nonRollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnInstall; + } + break; + case "ExecuteOnReinstall": + if (rollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); + } + nonRollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnReinstall; + } + break; + case "ExecuteOnUninstall": + if (rollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); + } + nonRollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnUninstall; + } + break; + case "RollbackOnInstall": + if (nonRollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); + } + rollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnInstall; + attributes |= SqlRollback; + } + break; + case "RollbackOnReinstall": + if (nonRollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); + } + rollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnReinstall; + attributes |= SqlRollback; + } + break; + case "RollbackOnUninstall": + if (nonRollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); + } + rollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnUninstall; + attributes |= SqlRollback; + } + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("ssc", componentId, binaryRef, sqlDb); + } + + if (null == binaryRef) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "BinaryRef")); + } + + if (null == sqlDb) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "SqlDb")); + } + + if (0 == attributes) + { + this.Messaging.Write(ErrorMessages.ExpectedAttributes(sourceLineNumbers, element.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall", "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + // Reference InstallSqlData and UninstallSqlData since nothing will happen without it + this.AddReferenceToInstallSqlData(section, sourceLineNumbers); + + if (!this.Messaging.EncounteredError) + { + var symbol = section.AddSymbol(new SqlScriptSymbol(sourceLineNumbers, id) + { + SqlDbRef = sqlDb, + ComponentRef = componentId, + ScriptBinaryRef = binaryRef, + UserRef = user, + Attributes = attributes, + }); + + if (CompilerConstants.IntegerNotSet != sequence) + { + symbol.Sequence = sequence; + } + } + } + + /// + /// Parses a sql string element. + /// + /// Element to parse. + /// Identifier for parent component. + /// Optional database to execute string against. + private void ParseSqlStringElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string sqlDb) + { + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + Identifier id = null; + int attributes = 0; + var rollbackAttribute = false; + var nonRollbackAttribute = false; + var sequence = CompilerConstants.IntegerNotSet; + string sql = null; + string user = null; + + foreach (var attrib in element.Attributes()) + { + if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) + { + switch (attrib.Name.LocalName) + { + case "Id": + id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); + break; + case "ContinueOnError": + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlContinueOnError; + } + break; + case "ExecuteOnInstall": + if (rollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); + } + nonRollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnInstall; + } + break; + case "ExecuteOnReinstall": + if (rollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); + } + nonRollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnReinstall; + } + break; + case "ExecuteOnUninstall": + if (rollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); + } + nonRollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnUninstall; + } + break; + case "RollbackOnInstall": + if (nonRollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); + } + rollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnInstall; + attributes |= SqlRollback; + } + break; + case "RollbackOnReinstall": + if (nonRollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); + } + rollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnReinstall; + attributes |= SqlRollback; + } + break; + case "RollbackOnUninstall": + if (nonRollbackAttribute) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); + } + rollbackAttribute = true; + + if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnUninstall; + attributes |= SqlRollback; + } + break; + case "Sequence": + sequence = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); + break; + case "SQL": + sql = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "SqlDb": + if (null != sqlDb) + { + this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "SqlDb", "SqlDatabase")); + } + + sqlDb = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SqlSymbolDefinitions.SqlDatabase, sqlDb); + break; + case "User": + user = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user); + break; + default: + this.ParseHelper.UnexpectedAttribute(element, attrib); + break; + } + } + else + { + this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); + } + } + + if (null == id) + { + id = this.ParseHelper.CreateIdentifier("sst", componentId, sql, sqlDb); + } + + if (null == sql) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "SQL")); + } + + if (null == sqlDb) + { + this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "SqlDb")); + } + + if (0 == attributes) + { + this.Messaging.Write(ErrorMessages.ExpectedAttributes(sourceLineNumbers, element.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall", "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); + } + + this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); + + // Reference InstallSqlData and UninstallSqlData since nothing will happen without it + this.AddReferenceToInstallSqlData(section, sourceLineNumbers); + + if (!this.Messaging.EncounteredError) + { + var symbol = section.AddSymbol(new SqlStringSymbol(sourceLineNumbers, id) + { + SqlDbRef = sqlDb, + ComponentRef = componentId, + SQL = sql, + UserRef = user, + Attributes = attributes, + }); + + if (CompilerConstants.IntegerNotSet != sequence) + { + symbol.Sequence = sequence; + } + } + } + + private void AddReferenceToInstallSqlData(IntermediateSection section, SourceLineNumber sourceLineNumbers) + { + this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4InstallSqlData", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); + this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4UninstallSqlData", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); + } + } +} diff --git a/src/ext/Sql/wixext/SqlDecompiler.cs b/src/ext/Sql/wixext/SqlDecompiler.cs new file mode 100644 index 00000000..52436b87 --- /dev/null +++ b/src/ext/Sql/wixext/SqlDecompiler.cs @@ -0,0 +1,514 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ +#if TODO_CONSIDER_DECOMPILER + using System.Collections; + using WixToolset.Data; + using WixToolset.Extensibility; + using Sql = WixToolset.Extensions.Serialize.Sql; + using Wix = WixToolset.Data.Serialize; + + /// + /// The decompiler for the WiX Toolset SQL Server Extension. + /// + public sealed class SqlDecompiler : DecompilerExtension + { + /// + /// Creates a decompiler for SQL Extension. + /// + public SqlDecompiler() + { + this.TableDefinitions = SqlExtensionData.GetExtensionTableDefinitions(); + } + + /// + /// Get the extensions library to be removed. + /// + /// Table definitions for library. + /// Library to remove from decompiled output. + public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions) + { + return SqlExtensionData.GetExtensionLibrary(tableDefinitions); + } + + /// + /// Decompiles an extension table. + /// + /// The table to decompile. + public override void DecompileTable(Table table) + { + switch (table.Name) + { + case "SqlDatabase": + this.DecompileSqlDatabaseTable(table); + break; + case "SqlFileSpec": + // handled in FinalizeSqlFileSpecTable + break; + case "SqlScript": + this.DecompileSqlScriptTable(table); + break; + case "SqlString": + this.DecompileSqlStringTable(table); + break; + default: + base.DecompileTable(table); + break; + } + } + + /// + /// Finalize decompilation. + /// + /// The collection of all tables. + public override void Finish(TableIndexedCollection tables) + { + this.FinalizeSqlFileSpecTable(tables); + this.FinalizeSqlScriptAndSqlStringTables(tables); + } + + /// + /// Decompile the SqlDatabase table. + /// + /// The table to decompile. + private void DecompileSqlDatabaseTable(Table table) + { + foreach (Row row in table.Rows) + { + Sql.SqlDatabase sqlDatabase = new Sql.SqlDatabase(); + + sqlDatabase.Id = (string)row[0]; + + if (null != row[1]) + { + sqlDatabase.Server = (string)row[1]; + } + + if (null != row[2]) + { + sqlDatabase.Instance = (string)row[2]; + } + + sqlDatabase.Database = (string)row[3]; + + if (null != row[5]) + { + sqlDatabase.User = (string)row[5]; + } + + // the FileSpec_ and FileSpec_Log columns will be handled in FinalizeSqlFileSpecTable + + if (null != row[8]) + { + int attributes = (int)row[8]; + + if (SqlCompiler.DbCreateOnInstall == (attributes & SqlCompiler.DbCreateOnInstall)) + { + sqlDatabase.CreateOnInstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbDropOnUninstall == (attributes & SqlCompiler.DbDropOnUninstall)) + { + sqlDatabase.DropOnUninstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbContinueOnError == (attributes & SqlCompiler.DbContinueOnError)) + { + sqlDatabase.ContinueOnError = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbDropOnInstall == (attributes & SqlCompiler.DbDropOnInstall)) + { + sqlDatabase.DropOnInstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbCreateOnUninstall == (attributes & SqlCompiler.DbCreateOnUninstall)) + { + sqlDatabase.CreateOnUninstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbConfirmOverwrite == (attributes & SqlCompiler.DbConfirmOverwrite)) + { + sqlDatabase.ConfirmOverwrite = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbCreateOnReinstall == (attributes & SqlCompiler.DbCreateOnReinstall)) + { + sqlDatabase.CreateOnReinstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbDropOnReinstall == (attributes & SqlCompiler.DbDropOnReinstall)) + { + sqlDatabase.DropOnReinstall = Sql.YesNoType.yes; + } + } + + if (null != row[4]) + { + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[4]); + + if (null != component) + { + component.AddChild(sqlDatabase); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[4], "Component")); + } + } + else + { + this.Core.RootElement.AddChild(sqlDatabase); + } + this.Core.IndexElement(row, sqlDatabase); + } + } + + /// + /// Decompile the SqlScript table. + /// + /// The table to decompile. + private void DecompileSqlScriptTable(Table table) + { + foreach (Row row in table.Rows) + { + Sql.SqlScript sqlScript = new Sql.SqlScript(); + + sqlScript.Id = (string)row[0]; + + // the Db_ and Component_ columns are handled in FinalizeSqlScriptAndSqlStringTables + + sqlScript.BinaryKey = (string)row[3]; + + if (null != row[4]) + { + sqlScript.User = (string)row[4]; + } + + int attributes = (int)row[5]; + + if (SqlCompiler.SqlContinueOnError == (attributes & SqlCompiler.SqlContinueOnError)) + { + sqlScript.ContinueOnError = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnInstall == (attributes & SqlCompiler.SqlExecuteOnInstall)) + { + sqlScript.ExecuteOnInstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnReinstall == (attributes & SqlCompiler.SqlExecuteOnReinstall)) + { + sqlScript.ExecuteOnReinstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnUninstall == (attributes & SqlCompiler.SqlExecuteOnUninstall)) + { + sqlScript.ExecuteOnUninstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall))) + { + sqlScript.RollbackOnInstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall))) + { + sqlScript.RollbackOnReinstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall))) + { + sqlScript.RollbackOnUninstall = Sql.YesNoType.yes; + } + + if (null != row[6]) + { + sqlScript.Sequence = (int)row[6]; + } + + this.Core.IndexElement(row, sqlScript); + } + } + + /// + /// Decompile the SqlString table. + /// + /// The table to decompile. + private void DecompileSqlStringTable(Table table) + { + foreach (Row row in table.Rows) + { + Sql.SqlString sqlString = new Sql.SqlString(); + + sqlString.Id = (string)row[0]; + + // the Db_ and Component_ columns are handled in FinalizeSqlScriptAndSqlStringTables + + sqlString.SQL = (string)row[3]; + + if (null != row[4]) + { + sqlString.User = (string)row[4]; + } + + int attributes = (int)row[5]; + + if (SqlCompiler.SqlContinueOnError == (attributes & SqlCompiler.SqlContinueOnError)) + { + sqlString.ContinueOnError = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnInstall == (attributes & SqlCompiler.SqlExecuteOnInstall)) + { + sqlString.ExecuteOnInstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnReinstall == (attributes & SqlCompiler.SqlExecuteOnReinstall)) + { + sqlString.ExecuteOnReinstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnUninstall == (attributes & SqlCompiler.SqlExecuteOnUninstall)) + { + sqlString.ExecuteOnUninstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall))) + { + sqlString.RollbackOnInstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall))) + { + sqlString.RollbackOnReinstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall))) + { + sqlString.RollbackOnUninstall = Sql.YesNoType.yes; + } + + if (null != row[6]) + { + sqlString.Sequence = (int)row[6]; + } + + this.Core.IndexElement(row, sqlString); + } + } + + /// + /// Finalize the SqlFileSpec table. + /// + /// The collection of all tables. + /// + /// Since rows of the SqlFileSpec table are represented by either + /// the SqlFileSpec or SqlLogFileSpec depending upon the context in + /// which they are used in the SqlDatabase table, decompilation of this + /// table must occur after the SqlDatbase parents are decompiled. + /// + private void FinalizeSqlFileSpecTable(TableIndexedCollection tables) + { + Table sqlDatabaseTable = tables["SqlDatabase"]; + Table sqlFileSpecTable = tables["SqlFileSpec"]; + + if (null != sqlDatabaseTable && null != sqlFileSpecTable) + { + Hashtable sqlFileSpecRows = new Hashtable(); + + // index each SqlFileSpec row by its primary key + foreach (Row row in sqlFileSpecTable.Rows) + { + sqlFileSpecRows.Add(row[0], row); + } + + // create the necessary SqlFileSpec and SqlLogFileSpec elements for each row + foreach (Row row in sqlDatabaseTable.Rows) + { + Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(row); + + if (null != row[6]) + { + Row sqlFileSpecRow = (Row)sqlFileSpecRows[row[6]]; + + if (null != sqlFileSpecRow) + { + Sql.SqlFileSpec sqlFileSpec = new Sql.SqlFileSpec(); + + sqlFileSpec.Id = (string)sqlFileSpecRow[0]; + + if (null != sqlFileSpecRow[1]) + { + sqlFileSpec.Name = (string)sqlFileSpecRow[1]; + } + + sqlFileSpec.Filename = (string)sqlFileSpecRow[2]; + + if (null != sqlFileSpecRow[3]) + { + sqlFileSpec.Size = (string)sqlFileSpecRow[3]; + } + + if (null != sqlFileSpecRow[4]) + { + sqlFileSpec.MaxSize = (string)sqlFileSpecRow[4]; + } + + if (null != sqlFileSpecRow[5]) + { + sqlFileSpec.GrowthSize = (string)sqlFileSpecRow[5]; + } + + sqlDatabase.AddChild(sqlFileSpec); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlDatabaseTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "FileSpec_", (string)row[6], "SqlFileSpec")); + } + } + + if (null != row[7]) + { + Row sqlFileSpecRow = (Row)sqlFileSpecRows[row[7]]; + + if (null != sqlFileSpecRow) + { + Sql.SqlLogFileSpec sqlLogFileSpec = new Sql.SqlLogFileSpec(); + + sqlLogFileSpec.Id = (string)sqlFileSpecRow[0]; + + if (null != sqlFileSpecRow[1]) + { + sqlLogFileSpec.Name = (string)sqlFileSpecRow[1]; + } + + sqlLogFileSpec.Filename = (string)sqlFileSpecRow[2]; + + if (null != sqlFileSpecRow[3]) + { + sqlLogFileSpec.Size = (string)sqlFileSpecRow[3]; + } + + if (null != sqlFileSpecRow[4]) + { + sqlLogFileSpec.MaxSize = (string)sqlFileSpecRow[4]; + } + + if (null != sqlFileSpecRow[5]) + { + sqlLogFileSpec.GrowthSize = (string)sqlFileSpecRow[5]; + } + + sqlDatabase.AddChild(sqlLogFileSpec); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlDatabaseTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "FileSpec_Log", (string)row[7], "SqlFileSpec")); + } + } + } + } + } + + /// + /// Finalize the SqlScript table. + /// + /// The collection of all tables. + /// + /// The SqlScript and SqlString tables contain a foreign key into the SqlDatabase + /// and Component tables. Depending upon the parent of the SqlDatabase + /// element, the SqlScript and SqlString elements are nested under either the + /// SqlDatabase or the Component element. + /// + private void FinalizeSqlScriptAndSqlStringTables(TableIndexedCollection tables) + { + Table sqlDatabaseTable = tables["SqlDatabase"]; + Table sqlScriptTable = tables["SqlScript"]; + Table sqlStringTable = tables["SqlString"]; + + Hashtable sqlDatabaseRows = new Hashtable(); + + // index each SqlDatabase row by its primary key + if (null != sqlDatabaseTable) + { + foreach (Row row in sqlDatabaseTable.Rows) + { + sqlDatabaseRows.Add(row[0], row); + } + } + + if (null != sqlScriptTable) + { + foreach (Row row in sqlScriptTable.Rows) + { + Sql.SqlScript sqlScript = (Sql.SqlScript)this.Core.GetIndexedElement(row); + + Row sqlDatabaseRow = (Row)sqlDatabaseRows[row[1]]; + string databaseComponent = (string)sqlDatabaseRow[4]; + + // determine if the SqlScript element should be nested under the database or another component + if (null != databaseComponent && databaseComponent == (string)row[2]) + { + Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(sqlDatabaseRow); + + sqlDatabase.AddChild(sqlScript); + } + else // nest under the component of the SqlDatabase row + { + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); + + // set the Database value + sqlScript.SqlDb = (string)row[1]; + + if (null != component) + { + component.AddChild(sqlScript); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlScriptTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); + } + } + } + } + + if (null != sqlStringTable) + { + foreach (Row row in sqlStringTable.Rows) + { + Sql.SqlString sqlString = (Sql.SqlString)this.Core.GetIndexedElement(row); + + Row sqlDatabaseRow = (Row)sqlDatabaseRows[row[1]]; + string databaseComponent = (string)sqlDatabaseRow[4]; + + // determine if the SqlScript element should be nested under the database or another component + if (null != databaseComponent && databaseComponent == (string)row[2]) + { + Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(sqlDatabaseRow); + + sqlDatabase.AddChild(sqlString); + } + else // nest under the component of the SqlDatabase row + { + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); + + // set the Database value + sqlString.SqlDb = (string)row[1]; + + if (null != component) + { + component.AddChild(sqlString); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlStringTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); + } + } + } + } + } + } +#endif +} diff --git a/src/ext/Sql/wixext/SqlErrors.cs b/src/ext/Sql/wixext/SqlErrors.cs new file mode 100644 index 00000000..f25728bd --- /dev/null +++ b/src/ext/Sql/wixext/SqlErrors.cs @@ -0,0 +1,48 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using System.Resources; + using WixToolset.Data; + + public static class SqlErrors + { + public static Message IllegalAttributeWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName) + { + return Message(sourceLineNumbers, Ids.IllegalAttributeWithoutComponent, "The {0}/@{1} attribute cannot be specified unless the element has a Component as an ancestor. A {0} that does not have a Component ancestor is not installed.", elementName, attributeName); + } + + public static Message IllegalElementWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName) + { + return Message(sourceLineNumbers, Ids.IllegalElementWithoutComponent, "The {0} element cannot be specified unless the element has a Component as an ancestor. A {0} that does not have a Component ancestor is not installed.", elementName); + } + + public static Message OneOfAttributesRequiredUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2, string attributeName3, string attributeName4) + { + return Message(sourceLineNumbers, Ids.OneOfAttributesRequiredUnderComponent, "When nested under a Component, the {0} element must have one of the following attributes specified: {1}, {2}, {3} or {4}.", elementName, attributeName1, attributeName2, attributeName3, attributeName4); + } + + public static Message DeprecatedBinaryChildElement(SourceLineNumber sourceLineNumbers, string elementName) + { + return Message(sourceLineNumbers, Ids.DeprecatedBinaryChildElement, "The {0} element contains a deprecated child Binary element. Please move the Binary element under a Fragment, Module, or Product element and set the {0}/@BinaryKey attribute to the value of the Binary/@Id attribute.", elementName); + } + + private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) + { + return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args); + } + + private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args) + { + return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args); + } + + public enum Ids + { + IllegalAttributeWithoutComponent = 5100, + IllegalElementWithoutComponent = 5101, + OneOfAttributesRequiredUnderComponent = 5102, + DeprecatedBinaryChildElement = 5103, + } + } +} \ No newline at end of file diff --git a/src/ext/Sql/wixext/SqlExtensionData.cs b/src/ext/Sql/wixext/SqlExtensionData.cs new file mode 100644 index 00000000..60de94fe --- /dev/null +++ b/src/ext/Sql/wixext/SqlExtensionData.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using WixToolset.Data; + using WixToolset.Extensibility; + + /// + /// The WiX Toolset SQL Server Extension. + /// + public sealed class SqlExtensionData : BaseExtensionData + { + /// + /// Gets the default culture. + /// + /// The default culture. + public override string DefaultCulture => "en-US"; + + public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition) + { + symbolDefinition = SqlSymbolDefinitions.ByName(name); + return symbolDefinition != null; + } + + public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions) + { + return Intermediate.Load(typeof(SqlExtensionData).Assembly, "WixToolset.Sql.sql.wixlib", symbolDefinitions); + } + } +} diff --git a/src/ext/Sql/wixext/SqlExtensionFactory.cs b/src/ext/Sql/wixext/SqlExtensionFactory.cs new file mode 100644 index 00000000..279106d3 --- /dev/null +++ b/src/ext/Sql/wixext/SqlExtensionFactory.cs @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using System; + using System.Collections.Generic; + using WixToolset.Extensibility; + + public class SqlExtensionFactory : BaseExtensionFactory + { + protected override IReadOnlyCollection ExtensionTypes => new[] + { + typeof(SqlCompiler), + typeof(SqlExtensionData), + typeof(SqlWindowsInstallerBackendBinderExtension), + }; + } +} diff --git a/src/ext/Sql/wixext/SqlTableDefinitions.cs b/src/ext/Sql/wixext/SqlTableDefinitions.cs new file mode 100644 index 00000000..029a092e --- /dev/null +++ b/src/ext/Sql/wixext/SqlTableDefinitions.cs @@ -0,0 +1,82 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using WixToolset.Data.WindowsInstaller; + + public static class SqlTableDefinitions + { + public static readonly TableDefinition SqlDatabase = new TableDefinition( + "Wix4SqlDatabase", + SqlSymbolDefinitions.SqlDatabase, + new[] + { + new ColumnDefinition("SqlDb", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Server", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Primary key, name of server running SQL Server"), + new ColumnDefinition("Instance", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Primary key, name of SQL Server instance"), + new ColumnDefinition("Database", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Primary key, name of database in a SQL Server"), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key, Component used to determine install state ", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "User", keyColumn: 1, description: "Foreign key, User used to log into database", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("FileSpec_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Wix4SqlFileSpec", keyColumn: 1, description: "Foreign key referencing SqlFileSpec.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("FileSpec_Log", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Wix4SqlFileSpec", keyColumn: 1, description: "Foreign key referencing SqlFileSpec.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, minValue: 0, maxValue: 255, description: "1 == create on install, 2 == drop on uninstall, 4 == continue on error, 8 == drop on install, 16 == create on uninstall, 32 == confirm update existing table, 64 == create on reinstall, 128 == drop on reinstall"), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition SqlFileSpec = new TableDefinition( + "Wix4SqlFileSpec", + SqlSymbolDefinitions.SqlFileSpec, + new[] + { + new ColumnDefinition("FileSpec", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Logical name of filespec", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Filename", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Filename to use (path must exist)", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Size", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Initial size for file", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("MaxSize", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Maximum size for file", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("GrowthSize", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Size file should grow when necessary", modularizeType: ColumnModularizeType.Property), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition SqlScript = new TableDefinition( + "Wix4SqlScript", + SqlSymbolDefinitions.SqlScript, + new[] + { + new ColumnDefinition("Script", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token"), + new ColumnDefinition("SqlDb_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Wix4SqlDatabase", keyColumn: 1, description: "Foreign key, SQL Server key", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key, Component used to determine install state", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("ScriptBinary_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Binary", keyColumn: 1, description: "Foreign key, Binary stream that contains SQL Script to execute", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "User", keyColumn: 1, description: "Foreign key, User used to log into database", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, possibilities: "1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31", description: "1 == execute on install, 2 == execute on uninstall, 4 == continue on error, 8 == rollback on install, 16 == rollback on uninstall"), + new ColumnDefinition("Sequence", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Order to execute SQL Queries in"), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition SqlString = new TableDefinition( + "Wix4SqlString", + SqlSymbolDefinitions.SqlString, + new[] + { + new ColumnDefinition("String", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Id for the Wix4SqlString", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("SqlDb_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Wix4SqlDatabase", keyColumn: 1, description: "Foreign key, SQL Server key", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key, Component used to determine install state", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("SQL", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "SQL query to execute"), + new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "User", keyColumn: 1, description: "Foreign key, User used to log into database", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, possibilities: "1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31", description: "1 == execute on install, 2 == execute on uninstall, 4 == continue on error, 8 == rollback on install, 16 == rollback on uninstall"), + new ColumnDefinition("Sequence", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Order to execute SQL Queries in"), + }, + symbolIdIsPrimaryKey: true + ); + + public static readonly TableDefinition[] All = new[] + { + SqlDatabase, + SqlFileSpec, + SqlScript, + SqlString, + }; + } +} diff --git a/src/ext/Sql/wixext/SqlWindowsInstallerBackendExtension.cs b/src/ext/Sql/wixext/SqlWindowsInstallerBackendExtension.cs new file mode 100644 index 00000000..2ccdcc56 --- /dev/null +++ b/src/ext/Sql/wixext/SqlWindowsInstallerBackendExtension.cs @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using System.Collections.Generic; + using WixToolset.Data.WindowsInstaller; + using WixToolset.Extensibility; + + public class SqlWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension + { + public override IReadOnlyCollection TableDefinitions => SqlTableDefinitions.All; + } +} diff --git a/src/ext/Sql/wixext/Symbols/SqlDatabaseSymbol.cs b/src/ext/Sql/wixext/Symbols/SqlDatabaseSymbol.cs new file mode 100644 index 00000000..6f0820ac --- /dev/null +++ b/src/ext/Sql/wixext/Symbols/SqlDatabaseSymbol.cs @@ -0,0 +1,103 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using WixToolset.Data; + using WixToolset.Sql.Symbols; + + public static partial class SqlSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition SqlDatabase = new IntermediateSymbolDefinition( + SqlSymbolDefinitionType.SqlDatabase.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.Server), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.Instance), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.Database), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.UserRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.FileSpecRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.LogFileSpecRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.Attributes), IntermediateFieldType.Number), + }, + typeof(SqlDatabaseSymbol)); + } +} + +namespace WixToolset.Sql.Symbols +{ + using WixToolset.Data; + + public enum SqlDatabaseSymbolFields + { + Server, + Instance, + Database, + ComponentRef, + UserRef, + FileSpecRef, + LogFileSpecRef, + Attributes, + } + + public class SqlDatabaseSymbol : IntermediateSymbol + { + public SqlDatabaseSymbol() : base(SqlSymbolDefinitions.SqlDatabase, null, null) + { + } + + public SqlDatabaseSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(SqlSymbolDefinitions.SqlDatabase, sourceLineNumber, id) + { + } + + public IntermediateField this[SqlDatabaseSymbolFields index] => this.Fields[(int)index]; + + public string Server + { + get => this.Fields[(int)SqlDatabaseSymbolFields.Server].AsString(); + set => this.Set((int)SqlDatabaseSymbolFields.Server, value); + } + + public string Instance + { + get => this.Fields[(int)SqlDatabaseSymbolFields.Instance].AsString(); + set => this.Set((int)SqlDatabaseSymbolFields.Instance, value); + } + + public string Database + { + get => this.Fields[(int)SqlDatabaseSymbolFields.Database].AsString(); + set => this.Set((int)SqlDatabaseSymbolFields.Database, value); + } + + public string ComponentRef + { + get => this.Fields[(int)SqlDatabaseSymbolFields.ComponentRef].AsString(); + set => this.Set((int)SqlDatabaseSymbolFields.ComponentRef, value); + } + + public string UserRef + { + get => this.Fields[(int)SqlDatabaseSymbolFields.UserRef].AsString(); + set => this.Set((int)SqlDatabaseSymbolFields.UserRef, value); + } + + public string FileSpecRef + { + get => this.Fields[(int)SqlDatabaseSymbolFields.FileSpecRef].AsString(); + set => this.Set((int)SqlDatabaseSymbolFields.FileSpecRef, value); + } + + public string LogFileSpecRef + { + get => this.Fields[(int)SqlDatabaseSymbolFields.LogFileSpecRef].AsString(); + set => this.Set((int)SqlDatabaseSymbolFields.LogFileSpecRef, value); + } + + public int Attributes + { + get => this.Fields[(int)SqlDatabaseSymbolFields.Attributes].AsNumber(); + set => this.Set((int)SqlDatabaseSymbolFields.Attributes, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Sql/wixext/Symbols/SqlFileSpecSymbol.cs b/src/ext/Sql/wixext/Symbols/SqlFileSpecSymbol.cs new file mode 100644 index 00000000..d9eecc62 --- /dev/null +++ b/src/ext/Sql/wixext/Symbols/SqlFileSpecSymbol.cs @@ -0,0 +1,79 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using WixToolset.Data; + using WixToolset.Sql.Symbols; + + public static partial class SqlSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition SqlFileSpec = new IntermediateSymbolDefinition( + SqlSymbolDefinitionType.SqlFileSpec.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(SqlFileSpecSymbolFields.Name), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlFileSpecSymbolFields.Filename), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlFileSpecSymbolFields.Size), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlFileSpecSymbolFields.MaxSize), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlFileSpecSymbolFields.GrowthSize), IntermediateFieldType.String), + }, + typeof(SqlFileSpecSymbol)); + } +} + +namespace WixToolset.Sql.Symbols +{ + using WixToolset.Data; + + public enum SqlFileSpecSymbolFields + { + Name, + Filename, + Size, + MaxSize, + GrowthSize, + } + + public class SqlFileSpecSymbol : IntermediateSymbol + { + public SqlFileSpecSymbol() : base(SqlSymbolDefinitions.SqlFileSpec, null, null) + { + } + + public SqlFileSpecSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(SqlSymbolDefinitions.SqlFileSpec, sourceLineNumber, id) + { + } + + public IntermediateField this[SqlFileSpecSymbolFields index] => this.Fields[(int)index]; + + public string Name + { + get => this.Fields[(int)SqlFileSpecSymbolFields.Name].AsString(); + set => this.Set((int)SqlFileSpecSymbolFields.Name, value); + } + + public string Filename + { + get => this.Fields[(int)SqlFileSpecSymbolFields.Filename].AsString(); + set => this.Set((int)SqlFileSpecSymbolFields.Filename, value); + } + + public string Size + { + get => this.Fields[(int)SqlFileSpecSymbolFields.Size].AsString(); + set => this.Set((int)SqlFileSpecSymbolFields.Size, value); + } + + public string MaxSize + { + get => this.Fields[(int)SqlFileSpecSymbolFields.MaxSize].AsString(); + set => this.Set((int)SqlFileSpecSymbolFields.MaxSize, value); + } + + public string GrowthSize + { + get => this.Fields[(int)SqlFileSpecSymbolFields.GrowthSize].AsString(); + set => this.Set((int)SqlFileSpecSymbolFields.GrowthSize, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Sql/wixext/Symbols/SqlScriptSymbol.cs b/src/ext/Sql/wixext/Symbols/SqlScriptSymbol.cs new file mode 100644 index 00000000..94c70390 --- /dev/null +++ b/src/ext/Sql/wixext/Symbols/SqlScriptSymbol.cs @@ -0,0 +1,87 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using WixToolset.Data; + using WixToolset.Sql.Symbols; + + public static partial class SqlSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition SqlScript = new IntermediateSymbolDefinition( + SqlSymbolDefinitionType.SqlScript.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.SqlDbRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.ScriptBinaryRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.UserRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.Attributes), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.Sequence), IntermediateFieldType.Number), + }, + typeof(SqlScriptSymbol)); + } +} + +namespace WixToolset.Sql.Symbols +{ + using WixToolset.Data; + + public enum SqlScriptSymbolFields + { + SqlDbRef, + ComponentRef, + ScriptBinaryRef, + UserRef, + Attributes, + Sequence, + } + + public class SqlScriptSymbol : IntermediateSymbol + { + public SqlScriptSymbol() : base(SqlSymbolDefinitions.SqlScript, null, null) + { + } + + public SqlScriptSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(SqlSymbolDefinitions.SqlScript, sourceLineNumber, id) + { + } + + public IntermediateField this[SqlScriptSymbolFields index] => this.Fields[(int)index]; + + public string SqlDbRef + { + get => this.Fields[(int)SqlScriptSymbolFields.SqlDbRef].AsString(); + set => this.Set((int)SqlScriptSymbolFields.SqlDbRef, value); + } + + public string ComponentRef + { + get => this.Fields[(int)SqlScriptSymbolFields.ComponentRef].AsString(); + set => this.Set((int)SqlScriptSymbolFields.ComponentRef, value); + } + + public string ScriptBinaryRef + { + get => this.Fields[(int)SqlScriptSymbolFields.ScriptBinaryRef].AsString(); + set => this.Set((int)SqlScriptSymbolFields.ScriptBinaryRef, value); + } + + public string UserRef + { + get => this.Fields[(int)SqlScriptSymbolFields.UserRef].AsString(); + set => this.Set((int)SqlScriptSymbolFields.UserRef, value); + } + + public int Attributes + { + get => this.Fields[(int)SqlScriptSymbolFields.Attributes].AsNumber(); + set => this.Set((int)SqlScriptSymbolFields.Attributes, value); + } + + public int? Sequence + { + get => this.Fields[(int)SqlScriptSymbolFields.Sequence].AsNullableNumber(); + set => this.Set((int)SqlScriptSymbolFields.Sequence, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Sql/wixext/Symbols/SqlStringSymbol.cs b/src/ext/Sql/wixext/Symbols/SqlStringSymbol.cs new file mode 100644 index 00000000..73a8206e --- /dev/null +++ b/src/ext/Sql/wixext/Symbols/SqlStringSymbol.cs @@ -0,0 +1,87 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using WixToolset.Data; + using WixToolset.Sql.Symbols; + + public static partial class SqlSymbolDefinitions + { + public static readonly IntermediateSymbolDefinition SqlString = new IntermediateSymbolDefinition( + SqlSymbolDefinitionType.SqlString.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.SqlDbRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.SQL), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.UserRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.Attributes), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.Sequence), IntermediateFieldType.Number), + }, + typeof(SqlStringSymbol)); + } +} + +namespace WixToolset.Sql.Symbols +{ + using WixToolset.Data; + + public enum SqlStringSymbolFields + { + SqlDbRef, + ComponentRef, + SQL, + UserRef, + Attributes, + Sequence, + } + + public class SqlStringSymbol : IntermediateSymbol + { + public SqlStringSymbol() : base(SqlSymbolDefinitions.SqlString, null, null) + { + } + + public SqlStringSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(SqlSymbolDefinitions.SqlString, sourceLineNumber, id) + { + } + + public IntermediateField this[SqlStringSymbolFields index] => this.Fields[(int)index]; + + public string SqlDbRef + { + get => this.Fields[(int)SqlStringSymbolFields.SqlDbRef].AsString(); + set => this.Set((int)SqlStringSymbolFields.SqlDbRef, value); + } + + public string ComponentRef + { + get => this.Fields[(int)SqlStringSymbolFields.ComponentRef].AsString(); + set => this.Set((int)SqlStringSymbolFields.ComponentRef, value); + } + + public string SQL + { + get => this.Fields[(int)SqlStringSymbolFields.SQL].AsString(); + set => this.Set((int)SqlStringSymbolFields.SQL, value); + } + + public string UserRef + { + get => this.Fields[(int)SqlStringSymbolFields.UserRef].AsString(); + set => this.Set((int)SqlStringSymbolFields.UserRef, value); + } + + public int Attributes + { + get => this.Fields[(int)SqlStringSymbolFields.Attributes].AsNumber(); + set => this.Set((int)SqlStringSymbolFields.Attributes, value); + } + + public int? Sequence + { + get => this.Fields[(int)SqlStringSymbolFields.Sequence].AsNullableNumber(); + set => this.Set((int)SqlStringSymbolFields.Sequence, value); + } + } +} \ No newline at end of file diff --git a/src/ext/Sql/wixext/Symbols/SqlSymbolDefinitions.cs b/src/ext/Sql/wixext/Symbols/SqlSymbolDefinitions.cs new file mode 100644 index 00000000..336f1546 --- /dev/null +++ b/src/ext/Sql/wixext/Symbols/SqlSymbolDefinitions.cs @@ -0,0 +1,51 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Sql +{ + using System; + using WixToolset.Data; + + public enum SqlSymbolDefinitionType + { + SqlDatabase, + SqlFileSpec, + SqlScript, + SqlString, + } + + public static partial class SqlSymbolDefinitions + { + public static readonly Version Version = new Version("4.0.0"); + + public static IntermediateSymbolDefinition ByName(string name) + { + if (!Enum.TryParse(name, out SqlSymbolDefinitionType type)) + { + return null; + } + + return ByType(type); + } + + public static IntermediateSymbolDefinition ByType(SqlSymbolDefinitionType type) + { + switch (type) + { + case SqlSymbolDefinitionType.SqlDatabase: + return SqlSymbolDefinitions.SqlDatabase; + + case SqlSymbolDefinitionType.SqlFileSpec: + return SqlSymbolDefinitions.SqlFileSpec; + + case SqlSymbolDefinitionType.SqlScript: + return SqlSymbolDefinitions.SqlScript; + + case SqlSymbolDefinitionType.SqlString: + return SqlSymbolDefinitions.SqlString; + + default: + throw new ArgumentOutOfRangeException(nameof(type)); + } + } + } +} diff --git a/src/ext/Sql/wixext/WixToolset.Sql.wixext.csproj b/src/ext/Sql/wixext/WixToolset.Sql.wixext.csproj new file mode 100644 index 00000000..5a1ebeb0 --- /dev/null +++ b/src/ext/Sql/wixext/WixToolset.Sql.wixext.csproj @@ -0,0 +1,30 @@ + + + + + + netstandard2.0 + WixToolset.Sql + WiX Toolset Sql Extension + WiX Toolset Sql Extension + embedded + true + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Sql/wixext/WixToolset.Sql.wixext.nuspec b/src/ext/Sql/wixext/WixToolset.Sql.wixext.nuspec new file mode 100644 index 00000000..ba3eaade --- /dev/null +++ b/src/ext/Sql/wixext/WixToolset.Sql.wixext.nuspec @@ -0,0 +1,25 @@ + + + + $id$ + $version$ + $title$ + $description$ + $authors$ + MS-RL + false + $copyright$ + $projectUrl$ + + + + + + + + + + + + + diff --git a/src/ext/Sql/wixext/WixToolset.Sql.wixext.targets b/src/ext/Sql/wixext/WixToolset.Sql.wixext.targets new file mode 100644 index 00000000..4950e119 --- /dev/null +++ b/src/ext/Sql/wixext/WixToolset.Sql.wixext.targets @@ -0,0 +1,11 @@ + + + + + + $(MSBuildThisFileDirectory)..\tools\WixToolset.Sql.wixext.dll + + + + + diff --git a/src/ext/Sql/wixlib/SqlExtension.wxi b/src/ext/Sql/wixlib/SqlExtension.wxi new file mode 100644 index 00000000..c9261f1d --- /dev/null +++ b/src/ext/Sql/wixlib/SqlExtension.wxi @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Sql/wixlib/SqlExtension.wxs b/src/ext/Sql/wixlib/SqlExtension.wxs new file mode 100644 index 00000000..8b5320fa --- /dev/null +++ b/src/ext/Sql/wixlib/SqlExtension.wxs @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/ext/Sql/wixlib/SqlExtension_arm64.wxs b/src/ext/Sql/wixlib/SqlExtension_arm64.wxs new file mode 100644 index 00000000..e8d22f69 --- /dev/null +++ b/src/ext/Sql/wixlib/SqlExtension_arm64.wxs @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/ext/Sql/wixlib/SqlExtension_x64.wxs b/src/ext/Sql/wixlib/SqlExtension_x64.wxs new file mode 100644 index 00000000..e55a14e4 --- /dev/null +++ b/src/ext/Sql/wixlib/SqlExtension_x64.wxs @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/ext/Sql/wixlib/SqlExtension_x86.wxs b/src/ext/Sql/wixlib/SqlExtension_x86.wxs new file mode 100644 index 00000000..1a51ed91 --- /dev/null +++ b/src/ext/Sql/wixlib/SqlExtension_x86.wxs @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/ext/Sql/wixlib/caDecor.wxi b/src/ext/Sql/wixlib/caDecor.wxi new file mode 100644 index 00000000..b1711518 --- /dev/null +++ b/src/ext/Sql/wixlib/caDecor.wxi @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ext/Sql/wixlib/caerr.wxi b/src/ext/Sql/wixlib/caerr.wxi new file mode 100644 index 00000000..ff7ec121 --- /dev/null +++ b/src/ext/Sql/wixlib/caerr.wxi @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ext/Sql/wixlib/de-de.wxl b/src/ext/Sql/wixlib/de-de.wxl new file mode 100644 index 00000000..ed2313a4 --- /dev/null +++ b/src/ext/Sql/wixlib/de-de.wxl @@ -0,0 +1,16 @@ + + + + + Fehler [2]: Erstellen der SQL-Datenbank fehlgeschlagen: [3], Fehlerbeschreibung: [4]. + Fehler [2]: Löschen der SQL-Datenbank fehlgeschlagen: [3], Fehlerbeschreibung: [4]. + Verbinden mit der SQL-Datenbank fehlgeschlagen. ([2] [3] [4] [5]) + Fehler [2]: Das Erstellen der SQL Zeichenfolge ist fehlgeschlagen, Fehlerbeschreibung: [3], SQL-Schlüssel: [4] SQL-Zeichenfolge: [5] + Die Datenbank [3] existiert bereits. Wollen Sie fortfahren? + + Konfiguriere SQL Server + Erstelle Datenbanken + Lösche Datenbanken + SQL-Zeichenfolgen werden erstellt + SQL-Zeichenfolgen werden zurückgesetzt + diff --git a/src/ext/Sql/wixlib/en-us.wxl b/src/ext/Sql/wixlib/en-us.wxl new file mode 100644 index 00000000..d3ffd5eb --- /dev/null +++ b/src/ext/Sql/wixlib/en-us.wxl @@ -0,0 +1,16 @@ + + + + + Error [2]: failed to create SQL database: [3], error detail: [4]. + Error [2]: failed to drop SQL database: [3], error detail: [4]. + Failed to connect to SQL database. ([2] [3] [4] [5]) + Error [2]: failed to execute SQL string, error detail: [3], SQL key: [4] SQL string: [5] + The database [3] already exists. Do you want to continue? + + Configuring SQL Server + Creating Databases + Dropping Databases + Executing SQL Strings + Rolling back SQL Strings + diff --git a/src/ext/Sql/wixlib/es-es.wxl b/src/ext/Sql/wixlib/es-es.wxl new file mode 100644 index 00000000..b2e5d499 --- /dev/null +++ b/src/ext/Sql/wixlib/es-es.wxl @@ -0,0 +1,17 @@ + + + + + Error [2]: falla al crear la base de datos SQL: [3], detalle del error: [4]. + Error [2]: falla al poner la base de datos SQL: [3], detalle del error: [4]. + Falla al conectarse con la base de datos SQL. ([2] [3] [4] [5]) + Error [2]: falla al ejecutar la cadena SQL, detalle del error: [3], Clave SQL: [4] Cadena SQL: [5] + La base de datos [3] ya existe. ¿Desea continuar? + + Configurando SQL Server + Creando Bases de Datos + Colocando Bases de Datos + Ejecutando cadenas SQL + Revirtiendo cadenas SQL + + diff --git a/src/ext/Sql/wixlib/ja-jp.wxl b/src/ext/Sql/wixlib/ja-jp.wxl new file mode 100644 index 00000000..6e35fd17 --- /dev/null +++ b/src/ext/Sql/wixlib/ja-jp.wxl @@ -0,0 +1,16 @@ + + + + + エラー [2]: SQL データベース [3] 作成に失敗しました、エラー詳細: [4]。 + エラー [2]: SQL データベース [3] の削除に失敗しました、エラー詳細: [4]。 + SQL データベースへ接続できませんでした。 ([2] [3] [4] [5]) + エラー [2]: SQL ストリングの実行に失敗しました、エラー詳細: [3]、 SQL キー: [4] SQL ストリング: [5] + データベース [3] は既に存在します。続行しますか? + + SQL サーバーを構成しています + データベースを作成しています + データベースを削除しています + SQL ストリングを実行しています + SQL ストリングをロールバックしています + diff --git a/src/ext/Sql/wixlib/pl-pl.wxl b/src/ext/Sql/wixlib/pl-pl.wxl new file mode 100644 index 00000000..6200e0e9 --- /dev/null +++ b/src/ext/Sql/wixlib/pl-pl.wxl @@ -0,0 +1,16 @@ + + + + + Błąd [2]: nie udało się utworzyć bazy danych: [3]. Szczegóły błędu: [4]. + Błąd [2]: nie udało się usunąć bazy danych: [3]. Szczegóły błędu: [4]. + Nie udało się połączyć z bazą danych. ([2] [3] [4] [5]) + Błąd [2]: nie udało się wykonać zapytania SQL. Szczegóły błędu: [3], klucz: [4] zapytanie SQL: [5] + Baza danych [3] już istnieje. Czy chcesz kontynuować? + + Konfigurowanie programu SQL Server + Tworzenie baz danych + Usuwanie baz danych + Wykonywanie zapytań SQL + Cofanie zapytań SQL + diff --git a/src/ext/Sql/wixlib/pt-br.wxl b/src/ext/Sql/wixlib/pt-br.wxl new file mode 100644 index 00000000..74c53313 --- /dev/null +++ b/src/ext/Sql/wixlib/pt-br.wxl @@ -0,0 +1,16 @@ + + + + + Error [2]: falha ao criar o Banco de Dados: [3], detalhes: [4]. + Error [2]: falha ao remover o Banco de Dados: [3], detalhes: [4]. + Falhou a ligação ao Banco de Dados. ([2] [3] [4] [5]) + Erro [2]: falha ao executar o comando de SQL, detalhes: [3], Comando: [4] Conteúdo: [5] + O Banco de Dados [3] já existe. Deseja continuar? + + Configurando o Servidor de SQL + Criando os Bancos de Dados + Removendo os Bancos de Dados + Executando comandos de SQL + Revertendo os comandos de SQL + diff --git a/src/ext/Sql/wixlib/pt-pt.wxl b/src/ext/Sql/wixlib/pt-pt.wxl new file mode 100644 index 00000000..90d9df4f --- /dev/null +++ b/src/ext/Sql/wixlib/pt-pt.wxl @@ -0,0 +1,16 @@ + + + + + Error [2]: falha ao criar a Base de Dados: [3], detalhes: [4]. + Error [2]: falha ao remover a Base de Dados: [3], detalhes: [4]. + Falhou a ligação à Base de Dados. ([2] [3] [4] [5]) + Erro [2]: falha ao executar o comando de SQL, detalhes: [3], Comando: [4] Conteúdo: [5] + A Base de Dados [3] já existe. Deseja continuar? + + Configurar o Servidor de SQL + Criar as Bases de Dados + Remover as Bases de Dados + Executar comandos de SQL + Reverter os comandos de SQL + diff --git a/src/ext/Sql/wixlib/sql.v3.ncrunchproject b/src/ext/Sql/wixlib/sql.v3.ncrunchproject new file mode 100644 index 00000000..319cd523 --- /dev/null +++ b/src/ext/Sql/wixlib/sql.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/src/ext/Sql/wixlib/sql.wixproj b/src/ext/Sql/wixlib/sql.wixproj new file mode 100644 index 00000000..ac994e6b --- /dev/null +++ b/src/ext/Sql/wixlib/sql.wixproj @@ -0,0 +1,24 @@ + + + + + Library + true + + + + + + + + + + + + + + + + + + diff --git a/src/ext/global.json b/src/ext/global.json new file mode 100644 index 00000000..23dd3fa6 --- /dev/null +++ b/src/ext/global.json @@ -0,0 +1,5 @@ +{ + "msbuild-sdks": { + "WixToolset.Sdk": "4.0.0-build-0211" + } +} diff --git a/src/test/WixToolsetTest.Sql/SqlExtensionFixture.cs b/src/test/WixToolsetTest.Sql/SqlExtensionFixture.cs deleted file mode 100644 index aa9d7a1f..00000000 --- a/src/test/WixToolsetTest.Sql/SqlExtensionFixture.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolsetTest.Sql -{ - using System.Linq; - using WixBuildTools.TestSupport; - using WixToolset.Core.TestPackage; - using WixToolset.Sql; - using Xunit; - - public class SqlExtensionFixture - { - [Fact] - public void CanBuildUsingSqlStuff() - { - var folder = TestData.Get(@"TestData\UsingSql"); - var build = new Builder(folder, typeof(SqlExtensionFactory), new[] { folder }); - - var results = build.BuildAndQuery(Build, "Wix4SqlDatabase", "Wix4SqlFileSpec", "Wix4SqlScript", "Wix4SqlString"); - WixAssert.CompareLineByLine(new[] - { - "Wix4SqlDatabase:TestDB\tMySQLHostName\tMyInstanceName\tMyDB\tDatabaseComponent\t\tTestFileSpecId\tTestLogFileSpecId\t35", - "Wix4SqlFileSpec:TestFileSpecId\tTestFileSpecLogicalName\tTestFileSpec\t10MB\t100MB\t10%", - "Wix4SqlFileSpec:TestLogFileSpecId\tTestLogFileSpecLogicalName\tTestLogFileSpec\t1MB\t10MB\t1%", - "Wix4SqlScript:TestScript\tTestDB\tDatabaseComponent\tScriptBinary\t\t1\t", - "Wix4SqlString:TestString\tTestDB\tDatabaseComponent\tCREATE TABLE TestTable1(name varchar(20), value varchar(20))\t\t1\t", - }, results.ToArray()); - } - - private static void Build(string[] args) - { - var result = WixRunner.Execute(args) - .AssertSuccess(); - } - } -} diff --git a/src/test/WixToolsetTest.Sql/TestData/UsingSql/Package.en-us.wxl b/src/test/WixToolsetTest.Sql/TestData/UsingSql/Package.en-us.wxl deleted file mode 100644 index 38c12ac1..00000000 --- a/src/test/WixToolsetTest.Sql/TestData/UsingSql/Package.en-us.wxl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - A newer version of [ProductName] is already installed. - MsiPackage - - diff --git a/src/test/WixToolsetTest.Sql/TestData/UsingSql/Package.wxs b/src/test/WixToolsetTest.Sql/TestData/UsingSql/Package.wxs deleted file mode 100644 index ee3bc921..00000000 --- a/src/test/WixToolsetTest.Sql/TestData/UsingSql/Package.wxs +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/src/test/WixToolsetTest.Sql/TestData/UsingSql/PackageComponents.wxs b/src/test/WixToolsetTest.Sql/TestData/UsingSql/PackageComponents.wxs deleted file mode 100644 index f7626926..00000000 --- a/src/test/WixToolsetTest.Sql/TestData/UsingSql/PackageComponents.wxs +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/WixToolsetTest.Sql/TestData/UsingSql/example.txt b/src/test/WixToolsetTest.Sql/TestData/UsingSql/example.txt deleted file mode 100644 index 1b4ffe8a..00000000 --- a/src/test/WixToolsetTest.Sql/TestData/UsingSql/example.txt +++ /dev/null @@ -1 +0,0 @@ -This is example.txt. \ No newline at end of file diff --git a/src/test/WixToolsetTest.Sql/WixToolsetTest.Sql.csproj b/src/test/WixToolsetTest.Sql/WixToolsetTest.Sql.csproj deleted file mode 100644 index bbf3041d..00000000 --- a/src/test/WixToolsetTest.Sql/WixToolsetTest.Sql.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - netcoreapp3.1 - false - - - - NU1701 - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/test/WixToolsetTest.Sql/WixToolsetTest.Sql.v3.ncrunchproject b/src/test/WixToolsetTest.Sql/WixToolsetTest.Sql.v3.ncrunchproject deleted file mode 100644 index 7b5b2139..00000000 --- a/src/test/WixToolsetTest.Sql/WixToolsetTest.Sql.v3.ncrunchproject +++ /dev/null @@ -1,5 +0,0 @@ - - - True - - \ No newline at end of file diff --git a/src/version.json b/src/version.json new file mode 100644 index 00000000..5f857771 --- /dev/null +++ b/src/version.json @@ -0,0 +1,11 @@ +{ + "version": "4.0", + "publicReleaseRefSpec": [ + "^refs/heads/master$" + ], + "cloudBuild": { + "buildNumber": { + "enabled": true + } + } +} diff --git a/src/wix.snk b/src/wix.snk deleted file mode 100644 index 3908a66a..00000000 Binary files a/src/wix.snk and /dev/null differ diff --git a/src/wixext/SqlCompiler.cs b/src/wixext/SqlCompiler.cs deleted file mode 100644 index 46196e95..00000000 --- a/src/wixext/SqlCompiler.cs +++ /dev/null @@ -1,804 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using System; - using System.Collections.Generic; - using System.Xml.Linq; - using WixToolset.Data; - using WixToolset.Extensibility; - using WixToolset.Extensibility.Data; - using WixToolset.Sql.Symbols; - - /// - /// The compiler for the WiX Toolset SQL Server Extension. - /// - public sealed class SqlCompiler : BaseCompilerExtension - { - // sql database attributes definitions (from sca.h) - internal const int DbCreateOnInstall = 0x00000001; - internal const int DbDropOnUninstall = 0x00000002; - internal const int DbContinueOnError = 0x00000004; - internal const int DbDropOnInstall = 0x00000008; - internal const int DbCreateOnUninstall = 0x00000010; - internal const int DbConfirmOverwrite = 0x00000020; - internal const int DbCreateOnReinstall = 0x00000040; - internal const int DbDropOnReinstall = 0x00000080; - - // sql string/script attributes definitions (from sca.h) - internal const int SqlExecuteOnInstall = 0x00000001; - internal const int SqlExecuteOnUninstall = 0x00000002; - internal const int SqlContinueOnError = 0x00000004; - internal const int SqlRollback = 0x00000008; - internal const int SqlExecuteOnReinstall = 0x00000010; - - public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/sql"; - - /// - /// Processes an element for the Compiler. - /// - /// - /// - /// Parent element of element to process. - /// Element to process. - /// Extra information about the context in which this element is being parsed. - public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary context) - { - switch (parentElement.Name.LocalName) - { - case "Component": - var componentId = context["ComponentId"]; - - switch (element.Name.LocalName) - { - case "SqlDatabase": - this.ParseSqlDatabaseElement(intermediate, section, element, componentId); - break; - case "SqlScript": - this.ParseSqlScriptElement(intermediate, section, element, componentId, null); - break; - case "SqlString": - this.ParseSqlStringElement(intermediate, section, element, componentId, null); - break; - default: - this.ParseHelper.UnexpectedElement(parentElement, element); - break; - } - break; - case "Fragment": - case "Module": - case "Package": - switch (element.Name.LocalName) - { - case "SqlDatabase": - this.ParseSqlDatabaseElement(intermediate, section, element, null); - break; - default: - this.ParseHelper.UnexpectedElement(parentElement, element); - break; - } - break; - default: - this.ParseHelper.UnexpectedElement(parentElement, element); - break; - } - } - - /// - /// Parses a sql database element - /// - /// - /// - /// Element to parse. - /// Identifier for parent component. - private void ParseSqlDatabaseElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - int attributes = 0; - string database = null; - Identifier fileSpec = null; - string instance = null; - Identifier logFileSpec = null; - string server = null; - string user = null; - - foreach (var attrib in element.Attributes()) - { - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) - { - switch (attrib.Name.LocalName) - { - case "Id": - id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); - break; - case "ConfirmOverwrite": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= DbConfirmOverwrite; - } - break; - case "ContinueOnError": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= DbContinueOnError; - } - break; - case "CreateOnInstall": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= DbCreateOnInstall; - } - break; - case "CreateOnReinstall": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= DbCreateOnReinstall; - } - break; - case "CreateOnUninstall": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= DbCreateOnUninstall; - } - break; - case "Database": - database = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "DropOnInstall": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= DbDropOnInstall; - } - break; - case "DropOnReinstall": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= DbDropOnReinstall; - } - break; - - case "DropOnUninstall": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName)); - } - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= DbDropOnUninstall; - } - break; - case "Instance": - instance = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Server": - server = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "User": - user = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - if (!this.ParseHelper.ContainsProperty(user)) - { - user = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user); - } - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("sdb", componentId, server, database); - } - - if (null == database) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Database")); - } - else if (128 < database.Length) - { - this.Messaging.Write(ErrorMessages.IdentifierTooLongError(sourceLineNumbers, element.Name.LocalName, "Database", database, 128)); - } - - if (null == server) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Server")); - } - - if (0 == attributes && null != componentId) - { - this.Messaging.Write(SqlErrors.OneOfAttributesRequiredUnderComponent(sourceLineNumbers, element.Name.LocalName, "CreateOnInstall", "CreateOnUninstall", "DropOnInstall", "DropOnUninstall")); - } - - foreach (var child in element.Elements()) - { - if (this.Namespace == child.Name.Namespace) - { - var childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); - switch (child.Name.LocalName) - { - case "SqlScript": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - this.ParseSqlScriptElement(intermediate, section, child, componentId, id?.Id); - break; - case "SqlString": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - - this.ParseSqlStringElement(intermediate, section, child, componentId, id?.Id); - break; - case "SqlFileSpec": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - else if (null != fileSpec) - { - this.Messaging.Write(ErrorMessages.TooManyElements(sourceLineNumbers, element.Name.LocalName, child.Name.LocalName, 1)); - } - - fileSpec = this.ParseSqlFileSpecElement(intermediate, section, child, id?.Id); - break; - case "SqlLogFileSpec": - if (null == componentId) - { - this.Messaging.Write(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); - } - else if (null != logFileSpec) - { - this.Messaging.Write(ErrorMessages.TooManyElements(sourceLineNumbers, element.Name.LocalName, child.Name.LocalName, 1)); - } - - logFileSpec = this.ParseSqlFileSpecElement(intermediate, section, child, id?.Id); - break; - default: - this.ParseHelper.UnexpectedElement(element, child); - break; - } - } - else - { - this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child); - } - } - - if (null != componentId) - { - // Reference InstallSqlData and UninstallSqlData since nothing will happen without it - this.AddReferenceToInstallSqlData(section, sourceLineNumbers); - } - - if (!this.Messaging.EncounteredError) - { - var symbol = section.AddSymbol(new SqlDatabaseSymbol(sourceLineNumbers, id) - { - Server = server, - Instance = instance, - Database = database, - ComponentRef = componentId, - UserRef = user, - FileSpecRef = fileSpec?.Id, - LogFileSpecRef = logFileSpec?.Id, - }); - - if (0 != attributes) - { - symbol.Attributes = attributes; - } - } - } - - /// - /// Parses a sql file specification element. - /// - /// - /// - /// Element to parse. - /// Identifier of sql file specification. - private Identifier ParseSqlFileSpecElement(Intermediate intermediate, IntermediateSection section, XElement element, string parentId) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - string fileName = null; - string growthSize = null; - string maxSize = null; - string name = null; - string size = null; - - foreach (var attrib in element.Attributes()) - { - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) - { - switch (attrib.Name.LocalName) - { - case "Id": - id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); - break; - case "Name": - name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Filename": - fileName = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "Size": - size = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "MaxSize": - maxSize = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "GrowthSize": - growthSize = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("sfs", parentId, name, fileName); - } - - if (null == name) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); - } - - if (null == fileName) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Filename")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - if (!this.Messaging.EncounteredError) - { - var symbol = section.AddSymbol(new SqlFileSpecSymbol(sourceLineNumbers, id) - { - Name = name, - Filename = fileName, - }); - - if (null != size) - { - symbol.Size = size; - } - - if (null != maxSize) - { - symbol.MaxSize = maxSize; - } - - if (null != growthSize) - { - symbol.GrowthSize = growthSize; - } - } - - return id; - } - - /// - /// Parses a sql script element. - /// - /// Element to parse. - /// Identifier for parent component. - /// Optional database to execute script against. - private void ParseSqlScriptElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string sqlDb) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - int attributes = 0; - var rollbackAttribute = false; - var nonRollbackAttribute = false; - string binaryRef = null; - var sequence = CompilerConstants.IntegerNotSet; - string user = null; - - foreach (var attrib in element.Attributes()) - { - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) - { - switch (attrib.Name.LocalName) - { - case "Id": - id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); - break; - case "BinaryRef": - binaryRef = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Binary, binaryRef); - break; - case "Sequence": - sequence = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); - break; - case "SqlDb": - if (null != sqlDb) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, element.Parent.Name.LocalName)); - } - sqlDb = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SqlSymbolDefinitions.SqlDatabase, sqlDb); - break; - case "User": - user = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user); - break; - - // Flag-setting attributes - case "ContinueOnError": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlContinueOnError; - } - break; - case "ExecuteOnInstall": - if (rollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); - } - nonRollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnInstall; - } - break; - case "ExecuteOnReinstall": - if (rollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); - } - nonRollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnReinstall; - } - break; - case "ExecuteOnUninstall": - if (rollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); - } - nonRollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnUninstall; - } - break; - case "RollbackOnInstall": - if (nonRollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); - } - rollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnInstall; - attributes |= SqlRollback; - } - break; - case "RollbackOnReinstall": - if (nonRollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); - } - rollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnReinstall; - attributes |= SqlRollback; - } - break; - case "RollbackOnUninstall": - if (nonRollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); - } - rollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnUninstall; - attributes |= SqlRollback; - } - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("ssc", componentId, binaryRef, sqlDb); - } - - if (null == binaryRef) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "BinaryRef")); - } - - if (null == sqlDb) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "SqlDb")); - } - - if (0 == attributes) - { - this.Messaging.Write(ErrorMessages.ExpectedAttributes(sourceLineNumbers, element.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall", "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - // Reference InstallSqlData and UninstallSqlData since nothing will happen without it - this.AddReferenceToInstallSqlData(section, sourceLineNumbers); - - if (!this.Messaging.EncounteredError) - { - var symbol = section.AddSymbol(new SqlScriptSymbol(sourceLineNumbers, id) - { - SqlDbRef = sqlDb, - ComponentRef = componentId, - ScriptBinaryRef = binaryRef, - UserRef = user, - Attributes = attributes, - }); - - if (CompilerConstants.IntegerNotSet != sequence) - { - symbol.Sequence = sequence; - } - } - } - - /// - /// Parses a sql string element. - /// - /// Element to parse. - /// Identifier for parent component. - /// Optional database to execute string against. - private void ParseSqlStringElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string sqlDb) - { - var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - Identifier id = null; - int attributes = 0; - var rollbackAttribute = false; - var nonRollbackAttribute = false; - var sequence = CompilerConstants.IntegerNotSet; - string sql = null; - string user = null; - - foreach (var attrib in element.Attributes()) - { - if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) - { - switch (attrib.Name.LocalName) - { - case "Id": - id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); - break; - case "ContinueOnError": - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlContinueOnError; - } - break; - case "ExecuteOnInstall": - if (rollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); - } - nonRollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnInstall; - } - break; - case "ExecuteOnReinstall": - if (rollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); - } - nonRollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnReinstall; - } - break; - case "ExecuteOnUninstall": - if (rollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); - } - nonRollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnUninstall; - } - break; - case "RollbackOnInstall": - if (nonRollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); - } - rollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnInstall; - attributes |= SqlRollback; - } - break; - case "RollbackOnReinstall": - if (nonRollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); - } - rollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnReinstall; - attributes |= SqlRollback; - } - break; - case "RollbackOnUninstall": - if (nonRollbackAttribute) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttributes(sourceLineNumbers, element.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); - } - rollbackAttribute = true; - - if (YesNoType.Yes == this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib)) - { - attributes |= SqlExecuteOnUninstall; - attributes |= SqlRollback; - } - break; - case "Sequence": - sequence = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); - break; - case "SQL": - sql = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); - break; - case "SqlDb": - if (null != sqlDb) - { - this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "SqlDb", "SqlDatabase")); - } - - sqlDb = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SqlSymbolDefinitions.SqlDatabase, sqlDb); - break; - case "User": - user = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "User", user); - break; - default: - this.ParseHelper.UnexpectedAttribute(element, attrib); - break; - } - } - else - { - this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib); - } - } - - if (null == id) - { - id = this.ParseHelper.CreateIdentifier("sst", componentId, sql, sqlDb); - } - - if (null == sql) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "SQL")); - } - - if (null == sqlDb) - { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "SqlDb")); - } - - if (0 == attributes) - { - this.Messaging.Write(ErrorMessages.ExpectedAttributes(sourceLineNumbers, element.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall", "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); - } - - this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - - // Reference InstallSqlData and UninstallSqlData since nothing will happen without it - this.AddReferenceToInstallSqlData(section, sourceLineNumbers); - - if (!this.Messaging.EncounteredError) - { - var symbol = section.AddSymbol(new SqlStringSymbol(sourceLineNumbers, id) - { - SqlDbRef = sqlDb, - ComponentRef = componentId, - SQL = sql, - UserRef = user, - Attributes = attributes, - }); - - if (CompilerConstants.IntegerNotSet != sequence) - { - symbol.Sequence = sequence; - } - } - } - - private void AddReferenceToInstallSqlData(IntermediateSection section, SourceLineNumber sourceLineNumbers) - { - this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4InstallSqlData", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); - this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4UninstallSqlData", this.Context.Platform, CustomActionPlatforms.X86 | CustomActionPlatforms.X64 | CustomActionPlatforms.ARM64); - } - } -} diff --git a/src/wixext/SqlDecompiler.cs b/src/wixext/SqlDecompiler.cs deleted file mode 100644 index 52436b87..00000000 --- a/src/wixext/SqlDecompiler.cs +++ /dev/null @@ -1,514 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ -#if TODO_CONSIDER_DECOMPILER - using System.Collections; - using WixToolset.Data; - using WixToolset.Extensibility; - using Sql = WixToolset.Extensions.Serialize.Sql; - using Wix = WixToolset.Data.Serialize; - - /// - /// The decompiler for the WiX Toolset SQL Server Extension. - /// - public sealed class SqlDecompiler : DecompilerExtension - { - /// - /// Creates a decompiler for SQL Extension. - /// - public SqlDecompiler() - { - this.TableDefinitions = SqlExtensionData.GetExtensionTableDefinitions(); - } - - /// - /// Get the extensions library to be removed. - /// - /// Table definitions for library. - /// Library to remove from decompiled output. - public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions) - { - return SqlExtensionData.GetExtensionLibrary(tableDefinitions); - } - - /// - /// Decompiles an extension table. - /// - /// The table to decompile. - public override void DecompileTable(Table table) - { - switch (table.Name) - { - case "SqlDatabase": - this.DecompileSqlDatabaseTable(table); - break; - case "SqlFileSpec": - // handled in FinalizeSqlFileSpecTable - break; - case "SqlScript": - this.DecompileSqlScriptTable(table); - break; - case "SqlString": - this.DecompileSqlStringTable(table); - break; - default: - base.DecompileTable(table); - break; - } - } - - /// - /// Finalize decompilation. - /// - /// The collection of all tables. - public override void Finish(TableIndexedCollection tables) - { - this.FinalizeSqlFileSpecTable(tables); - this.FinalizeSqlScriptAndSqlStringTables(tables); - } - - /// - /// Decompile the SqlDatabase table. - /// - /// The table to decompile. - private void DecompileSqlDatabaseTable(Table table) - { - foreach (Row row in table.Rows) - { - Sql.SqlDatabase sqlDatabase = new Sql.SqlDatabase(); - - sqlDatabase.Id = (string)row[0]; - - if (null != row[1]) - { - sqlDatabase.Server = (string)row[1]; - } - - if (null != row[2]) - { - sqlDatabase.Instance = (string)row[2]; - } - - sqlDatabase.Database = (string)row[3]; - - if (null != row[5]) - { - sqlDatabase.User = (string)row[5]; - } - - // the FileSpec_ and FileSpec_Log columns will be handled in FinalizeSqlFileSpecTable - - if (null != row[8]) - { - int attributes = (int)row[8]; - - if (SqlCompiler.DbCreateOnInstall == (attributes & SqlCompiler.DbCreateOnInstall)) - { - sqlDatabase.CreateOnInstall = Sql.YesNoType.yes; - } - - if (SqlCompiler.DbDropOnUninstall == (attributes & SqlCompiler.DbDropOnUninstall)) - { - sqlDatabase.DropOnUninstall = Sql.YesNoType.yes; - } - - if (SqlCompiler.DbContinueOnError == (attributes & SqlCompiler.DbContinueOnError)) - { - sqlDatabase.ContinueOnError = Sql.YesNoType.yes; - } - - if (SqlCompiler.DbDropOnInstall == (attributes & SqlCompiler.DbDropOnInstall)) - { - sqlDatabase.DropOnInstall = Sql.YesNoType.yes; - } - - if (SqlCompiler.DbCreateOnUninstall == (attributes & SqlCompiler.DbCreateOnUninstall)) - { - sqlDatabase.CreateOnUninstall = Sql.YesNoType.yes; - } - - if (SqlCompiler.DbConfirmOverwrite == (attributes & SqlCompiler.DbConfirmOverwrite)) - { - sqlDatabase.ConfirmOverwrite = Sql.YesNoType.yes; - } - - if (SqlCompiler.DbCreateOnReinstall == (attributes & SqlCompiler.DbCreateOnReinstall)) - { - sqlDatabase.CreateOnReinstall = Sql.YesNoType.yes; - } - - if (SqlCompiler.DbDropOnReinstall == (attributes & SqlCompiler.DbDropOnReinstall)) - { - sqlDatabase.DropOnReinstall = Sql.YesNoType.yes; - } - } - - if (null != row[4]) - { - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[4]); - - if (null != component) - { - component.AddChild(sqlDatabase); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[4], "Component")); - } - } - else - { - this.Core.RootElement.AddChild(sqlDatabase); - } - this.Core.IndexElement(row, sqlDatabase); - } - } - - /// - /// Decompile the SqlScript table. - /// - /// The table to decompile. - private void DecompileSqlScriptTable(Table table) - { - foreach (Row row in table.Rows) - { - Sql.SqlScript sqlScript = new Sql.SqlScript(); - - sqlScript.Id = (string)row[0]; - - // the Db_ and Component_ columns are handled in FinalizeSqlScriptAndSqlStringTables - - sqlScript.BinaryKey = (string)row[3]; - - if (null != row[4]) - { - sqlScript.User = (string)row[4]; - } - - int attributes = (int)row[5]; - - if (SqlCompiler.SqlContinueOnError == (attributes & SqlCompiler.SqlContinueOnError)) - { - sqlScript.ContinueOnError = Sql.YesNoType.yes; - } - - if (SqlCompiler.SqlExecuteOnInstall == (attributes & SqlCompiler.SqlExecuteOnInstall)) - { - sqlScript.ExecuteOnInstall = Sql.YesNoType.yes; - } - - if (SqlCompiler.SqlExecuteOnReinstall == (attributes & SqlCompiler.SqlExecuteOnReinstall)) - { - sqlScript.ExecuteOnReinstall = Sql.YesNoType.yes; - } - - if (SqlCompiler.SqlExecuteOnUninstall == (attributes & SqlCompiler.SqlExecuteOnUninstall)) - { - sqlScript.ExecuteOnUninstall = Sql.YesNoType.yes; - } - - if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall))) - { - sqlScript.RollbackOnInstall = Sql.YesNoType.yes; - } - - if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall))) - { - sqlScript.RollbackOnReinstall = Sql.YesNoType.yes; - } - - if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall))) - { - sqlScript.RollbackOnUninstall = Sql.YesNoType.yes; - } - - if (null != row[6]) - { - sqlScript.Sequence = (int)row[6]; - } - - this.Core.IndexElement(row, sqlScript); - } - } - - /// - /// Decompile the SqlString table. - /// - /// The table to decompile. - private void DecompileSqlStringTable(Table table) - { - foreach (Row row in table.Rows) - { - Sql.SqlString sqlString = new Sql.SqlString(); - - sqlString.Id = (string)row[0]; - - // the Db_ and Component_ columns are handled in FinalizeSqlScriptAndSqlStringTables - - sqlString.SQL = (string)row[3]; - - if (null != row[4]) - { - sqlString.User = (string)row[4]; - } - - int attributes = (int)row[5]; - - if (SqlCompiler.SqlContinueOnError == (attributes & SqlCompiler.SqlContinueOnError)) - { - sqlString.ContinueOnError = Sql.YesNoType.yes; - } - - if (SqlCompiler.SqlExecuteOnInstall == (attributes & SqlCompiler.SqlExecuteOnInstall)) - { - sqlString.ExecuteOnInstall = Sql.YesNoType.yes; - } - - if (SqlCompiler.SqlExecuteOnReinstall == (attributes & SqlCompiler.SqlExecuteOnReinstall)) - { - sqlString.ExecuteOnReinstall = Sql.YesNoType.yes; - } - - if (SqlCompiler.SqlExecuteOnUninstall == (attributes & SqlCompiler.SqlExecuteOnUninstall)) - { - sqlString.ExecuteOnUninstall = Sql.YesNoType.yes; - } - - if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall))) - { - sqlString.RollbackOnInstall = Sql.YesNoType.yes; - } - - if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall))) - { - sqlString.RollbackOnReinstall = Sql.YesNoType.yes; - } - - if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall))) - { - sqlString.RollbackOnUninstall = Sql.YesNoType.yes; - } - - if (null != row[6]) - { - sqlString.Sequence = (int)row[6]; - } - - this.Core.IndexElement(row, sqlString); - } - } - - /// - /// Finalize the SqlFileSpec table. - /// - /// The collection of all tables. - /// - /// Since rows of the SqlFileSpec table are represented by either - /// the SqlFileSpec or SqlLogFileSpec depending upon the context in - /// which they are used in the SqlDatabase table, decompilation of this - /// table must occur after the SqlDatbase parents are decompiled. - /// - private void FinalizeSqlFileSpecTable(TableIndexedCollection tables) - { - Table sqlDatabaseTable = tables["SqlDatabase"]; - Table sqlFileSpecTable = tables["SqlFileSpec"]; - - if (null != sqlDatabaseTable && null != sqlFileSpecTable) - { - Hashtable sqlFileSpecRows = new Hashtable(); - - // index each SqlFileSpec row by its primary key - foreach (Row row in sqlFileSpecTable.Rows) - { - sqlFileSpecRows.Add(row[0], row); - } - - // create the necessary SqlFileSpec and SqlLogFileSpec elements for each row - foreach (Row row in sqlDatabaseTable.Rows) - { - Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(row); - - if (null != row[6]) - { - Row sqlFileSpecRow = (Row)sqlFileSpecRows[row[6]]; - - if (null != sqlFileSpecRow) - { - Sql.SqlFileSpec sqlFileSpec = new Sql.SqlFileSpec(); - - sqlFileSpec.Id = (string)sqlFileSpecRow[0]; - - if (null != sqlFileSpecRow[1]) - { - sqlFileSpec.Name = (string)sqlFileSpecRow[1]; - } - - sqlFileSpec.Filename = (string)sqlFileSpecRow[2]; - - if (null != sqlFileSpecRow[3]) - { - sqlFileSpec.Size = (string)sqlFileSpecRow[3]; - } - - if (null != sqlFileSpecRow[4]) - { - sqlFileSpec.MaxSize = (string)sqlFileSpecRow[4]; - } - - if (null != sqlFileSpecRow[5]) - { - sqlFileSpec.GrowthSize = (string)sqlFileSpecRow[5]; - } - - sqlDatabase.AddChild(sqlFileSpec); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlDatabaseTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "FileSpec_", (string)row[6], "SqlFileSpec")); - } - } - - if (null != row[7]) - { - Row sqlFileSpecRow = (Row)sqlFileSpecRows[row[7]]; - - if (null != sqlFileSpecRow) - { - Sql.SqlLogFileSpec sqlLogFileSpec = new Sql.SqlLogFileSpec(); - - sqlLogFileSpec.Id = (string)sqlFileSpecRow[0]; - - if (null != sqlFileSpecRow[1]) - { - sqlLogFileSpec.Name = (string)sqlFileSpecRow[1]; - } - - sqlLogFileSpec.Filename = (string)sqlFileSpecRow[2]; - - if (null != sqlFileSpecRow[3]) - { - sqlLogFileSpec.Size = (string)sqlFileSpecRow[3]; - } - - if (null != sqlFileSpecRow[4]) - { - sqlLogFileSpec.MaxSize = (string)sqlFileSpecRow[4]; - } - - if (null != sqlFileSpecRow[5]) - { - sqlLogFileSpec.GrowthSize = (string)sqlFileSpecRow[5]; - } - - sqlDatabase.AddChild(sqlLogFileSpec); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlDatabaseTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "FileSpec_Log", (string)row[7], "SqlFileSpec")); - } - } - } - } - } - - /// - /// Finalize the SqlScript table. - /// - /// The collection of all tables. - /// - /// The SqlScript and SqlString tables contain a foreign key into the SqlDatabase - /// and Component tables. Depending upon the parent of the SqlDatabase - /// element, the SqlScript and SqlString elements are nested under either the - /// SqlDatabase or the Component element. - /// - private void FinalizeSqlScriptAndSqlStringTables(TableIndexedCollection tables) - { - Table sqlDatabaseTable = tables["SqlDatabase"]; - Table sqlScriptTable = tables["SqlScript"]; - Table sqlStringTable = tables["SqlString"]; - - Hashtable sqlDatabaseRows = new Hashtable(); - - // index each SqlDatabase row by its primary key - if (null != sqlDatabaseTable) - { - foreach (Row row in sqlDatabaseTable.Rows) - { - sqlDatabaseRows.Add(row[0], row); - } - } - - if (null != sqlScriptTable) - { - foreach (Row row in sqlScriptTable.Rows) - { - Sql.SqlScript sqlScript = (Sql.SqlScript)this.Core.GetIndexedElement(row); - - Row sqlDatabaseRow = (Row)sqlDatabaseRows[row[1]]; - string databaseComponent = (string)sqlDatabaseRow[4]; - - // determine if the SqlScript element should be nested under the database or another component - if (null != databaseComponent && databaseComponent == (string)row[2]) - { - Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(sqlDatabaseRow); - - sqlDatabase.AddChild(sqlScript); - } - else // nest under the component of the SqlDatabase row - { - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); - - // set the Database value - sqlScript.SqlDb = (string)row[1]; - - if (null != component) - { - component.AddChild(sqlScript); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlScriptTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); - } - } - } - } - - if (null != sqlStringTable) - { - foreach (Row row in sqlStringTable.Rows) - { - Sql.SqlString sqlString = (Sql.SqlString)this.Core.GetIndexedElement(row); - - Row sqlDatabaseRow = (Row)sqlDatabaseRows[row[1]]; - string databaseComponent = (string)sqlDatabaseRow[4]; - - // determine if the SqlScript element should be nested under the database or another component - if (null != databaseComponent && databaseComponent == (string)row[2]) - { - Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(sqlDatabaseRow); - - sqlDatabase.AddChild(sqlString); - } - else // nest under the component of the SqlDatabase row - { - Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); - - // set the Database value - sqlString.SqlDb = (string)row[1]; - - if (null != component) - { - component.AddChild(sqlString); - } - else - { - this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlStringTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); - } - } - } - } - } - } -#endif -} diff --git a/src/wixext/SqlErrors.cs b/src/wixext/SqlErrors.cs deleted file mode 100644 index f25728bd..00000000 --- a/src/wixext/SqlErrors.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using System.Resources; - using WixToolset.Data; - - public static class SqlErrors - { - public static Message IllegalAttributeWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName) - { - return Message(sourceLineNumbers, Ids.IllegalAttributeWithoutComponent, "The {0}/@{1} attribute cannot be specified unless the element has a Component as an ancestor. A {0} that does not have a Component ancestor is not installed.", elementName, attributeName); - } - - public static Message IllegalElementWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName) - { - return Message(sourceLineNumbers, Ids.IllegalElementWithoutComponent, "The {0} element cannot be specified unless the element has a Component as an ancestor. A {0} that does not have a Component ancestor is not installed.", elementName); - } - - public static Message OneOfAttributesRequiredUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2, string attributeName3, string attributeName4) - { - return Message(sourceLineNumbers, Ids.OneOfAttributesRequiredUnderComponent, "When nested under a Component, the {0} element must have one of the following attributes specified: {1}, {2}, {3} or {4}.", elementName, attributeName1, attributeName2, attributeName3, attributeName4); - } - - public static Message DeprecatedBinaryChildElement(SourceLineNumber sourceLineNumbers, string elementName) - { - return Message(sourceLineNumbers, Ids.DeprecatedBinaryChildElement, "The {0} element contains a deprecated child Binary element. Please move the Binary element under a Fragment, Module, or Product element and set the {0}/@BinaryKey attribute to the value of the Binary/@Id attribute.", elementName); - } - - private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) - { - return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args); - } - - private static Message Message(SourceLineNumber sourceLineNumber, Ids id, ResourceManager resourceManager, string resourceName, params object[] args) - { - return new Message(sourceLineNumber, MessageLevel.Error, (int)id, resourceManager, resourceName, args); - } - - public enum Ids - { - IllegalAttributeWithoutComponent = 5100, - IllegalElementWithoutComponent = 5101, - OneOfAttributesRequiredUnderComponent = 5102, - DeprecatedBinaryChildElement = 5103, - } - } -} \ No newline at end of file diff --git a/src/wixext/SqlExtensionData.cs b/src/wixext/SqlExtensionData.cs deleted file mode 100644 index 60de94fe..00000000 --- a/src/wixext/SqlExtensionData.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using WixToolset.Data; - using WixToolset.Extensibility; - - /// - /// The WiX Toolset SQL Server Extension. - /// - public sealed class SqlExtensionData : BaseExtensionData - { - /// - /// Gets the default culture. - /// - /// The default culture. - public override string DefaultCulture => "en-US"; - - public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition) - { - symbolDefinition = SqlSymbolDefinitions.ByName(name); - return symbolDefinition != null; - } - - public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions) - { - return Intermediate.Load(typeof(SqlExtensionData).Assembly, "WixToolset.Sql.sql.wixlib", symbolDefinitions); - } - } -} diff --git a/src/wixext/SqlExtensionFactory.cs b/src/wixext/SqlExtensionFactory.cs deleted file mode 100644 index 279106d3..00000000 --- a/src/wixext/SqlExtensionFactory.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using System; - using System.Collections.Generic; - using WixToolset.Extensibility; - - public class SqlExtensionFactory : BaseExtensionFactory - { - protected override IReadOnlyCollection ExtensionTypes => new[] - { - typeof(SqlCompiler), - typeof(SqlExtensionData), - typeof(SqlWindowsInstallerBackendBinderExtension), - }; - } -} diff --git a/src/wixext/SqlTableDefinitions.cs b/src/wixext/SqlTableDefinitions.cs deleted file mode 100644 index 029a092e..00000000 --- a/src/wixext/SqlTableDefinitions.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using WixToolset.Data.WindowsInstaller; - - public static class SqlTableDefinitions - { - public static readonly TableDefinition SqlDatabase = new TableDefinition( - "Wix4SqlDatabase", - SqlSymbolDefinitions.SqlDatabase, - new[] - { - new ColumnDefinition("SqlDb", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Server", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Primary key, name of server running SQL Server"), - new ColumnDefinition("Instance", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Primary key, name of SQL Server instance"), - new ColumnDefinition("Database", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Primary key, name of database in a SQL Server"), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key, Component used to determine install state ", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "User", keyColumn: 1, description: "Foreign key, User used to log into database", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("FileSpec_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Wix4SqlFileSpec", keyColumn: 1, description: "Foreign key referencing SqlFileSpec.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("FileSpec_Log", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "Wix4SqlFileSpec", keyColumn: 1, description: "Foreign key referencing SqlFileSpec.", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, minValue: 0, maxValue: 255, description: "1 == create on install, 2 == drop on uninstall, 4 == continue on error, 8 == drop on install, 16 == create on uninstall, 32 == confirm update existing table, 64 == create on reinstall, 128 == drop on reinstall"), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition SqlFileSpec = new TableDefinition( - "Wix4SqlFileSpec", - SqlSymbolDefinitions.SqlFileSpec, - new[] - { - new ColumnDefinition("FileSpec", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Name", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Logical name of filespec", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Filename", ColumnType.String, 255, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Filename to use (path must exist)", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("Size", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Initial size for file", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("MaxSize", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Maximum size for file", modularizeType: ColumnModularizeType.Property), - new ColumnDefinition("GrowthSize", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Size file should grow when necessary", modularizeType: ColumnModularizeType.Property), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition SqlScript = new TableDefinition( - "Wix4SqlScript", - SqlSymbolDefinitions.SqlScript, - new[] - { - new ColumnDefinition("Script", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary key, non-localized token"), - new ColumnDefinition("SqlDb_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Wix4SqlDatabase", keyColumn: 1, description: "Foreign key, SQL Server key", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key, Component used to determine install state", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("ScriptBinary_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Binary", keyColumn: 1, description: "Foreign key, Binary stream that contains SQL Script to execute", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "User", keyColumn: 1, description: "Foreign key, User used to log into database", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, possibilities: "1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31", description: "1 == execute on install, 2 == execute on uninstall, 4 == continue on error, 8 == rollback on install, 16 == rollback on uninstall"), - new ColumnDefinition("Sequence", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Order to execute SQL Queries in"), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition SqlString = new TableDefinition( - "Wix4SqlString", - SqlSymbolDefinitions.SqlString, - new[] - { - new ColumnDefinition("String", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Id for the Wix4SqlString", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("SqlDb_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Wix4SqlDatabase", keyColumn: 1, description: "Foreign key, SQL Server key", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key, Component used to determine install state", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("SQL", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "SQL query to execute"), - new ColumnDefinition("User_", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "User", keyColumn: 1, description: "Foreign key, User used to log into database", modularizeType: ColumnModularizeType.Column), - new ColumnDefinition("Attributes", ColumnType.Number, 2, primaryKey: false, nullable: false, ColumnCategory.Unknown, possibilities: "1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31", description: "1 == execute on install, 2 == execute on uninstall, 4 == continue on error, 8 == rollback on install, 16 == rollback on uninstall"), - new ColumnDefinition("Sequence", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Order to execute SQL Queries in"), - }, - symbolIdIsPrimaryKey: true - ); - - public static readonly TableDefinition[] All = new[] - { - SqlDatabase, - SqlFileSpec, - SqlScript, - SqlString, - }; - } -} diff --git a/src/wixext/SqlWindowsInstallerBackendExtension.cs b/src/wixext/SqlWindowsInstallerBackendExtension.cs deleted file mode 100644 index 2ccdcc56..00000000 --- a/src/wixext/SqlWindowsInstallerBackendExtension.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using System.Collections.Generic; - using WixToolset.Data.WindowsInstaller; - using WixToolset.Extensibility; - - public class SqlWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension - { - public override IReadOnlyCollection TableDefinitions => SqlTableDefinitions.All; - } -} diff --git a/src/wixext/Symbols/SqlDatabaseSymbol.cs b/src/wixext/Symbols/SqlDatabaseSymbol.cs deleted file mode 100644 index 6f0820ac..00000000 --- a/src/wixext/Symbols/SqlDatabaseSymbol.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using WixToolset.Data; - using WixToolset.Sql.Symbols; - - public static partial class SqlSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition SqlDatabase = new IntermediateSymbolDefinition( - SqlSymbolDefinitionType.SqlDatabase.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.Server), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.Instance), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.Database), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.UserRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.FileSpecRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.LogFileSpecRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlDatabaseSymbolFields.Attributes), IntermediateFieldType.Number), - }, - typeof(SqlDatabaseSymbol)); - } -} - -namespace WixToolset.Sql.Symbols -{ - using WixToolset.Data; - - public enum SqlDatabaseSymbolFields - { - Server, - Instance, - Database, - ComponentRef, - UserRef, - FileSpecRef, - LogFileSpecRef, - Attributes, - } - - public class SqlDatabaseSymbol : IntermediateSymbol - { - public SqlDatabaseSymbol() : base(SqlSymbolDefinitions.SqlDatabase, null, null) - { - } - - public SqlDatabaseSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(SqlSymbolDefinitions.SqlDatabase, sourceLineNumber, id) - { - } - - public IntermediateField this[SqlDatabaseSymbolFields index] => this.Fields[(int)index]; - - public string Server - { - get => this.Fields[(int)SqlDatabaseSymbolFields.Server].AsString(); - set => this.Set((int)SqlDatabaseSymbolFields.Server, value); - } - - public string Instance - { - get => this.Fields[(int)SqlDatabaseSymbolFields.Instance].AsString(); - set => this.Set((int)SqlDatabaseSymbolFields.Instance, value); - } - - public string Database - { - get => this.Fields[(int)SqlDatabaseSymbolFields.Database].AsString(); - set => this.Set((int)SqlDatabaseSymbolFields.Database, value); - } - - public string ComponentRef - { - get => this.Fields[(int)SqlDatabaseSymbolFields.ComponentRef].AsString(); - set => this.Set((int)SqlDatabaseSymbolFields.ComponentRef, value); - } - - public string UserRef - { - get => this.Fields[(int)SqlDatabaseSymbolFields.UserRef].AsString(); - set => this.Set((int)SqlDatabaseSymbolFields.UserRef, value); - } - - public string FileSpecRef - { - get => this.Fields[(int)SqlDatabaseSymbolFields.FileSpecRef].AsString(); - set => this.Set((int)SqlDatabaseSymbolFields.FileSpecRef, value); - } - - public string LogFileSpecRef - { - get => this.Fields[(int)SqlDatabaseSymbolFields.LogFileSpecRef].AsString(); - set => this.Set((int)SqlDatabaseSymbolFields.LogFileSpecRef, value); - } - - public int Attributes - { - get => this.Fields[(int)SqlDatabaseSymbolFields.Attributes].AsNumber(); - set => this.Set((int)SqlDatabaseSymbolFields.Attributes, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/SqlFileSpecSymbol.cs b/src/wixext/Symbols/SqlFileSpecSymbol.cs deleted file mode 100644 index d9eecc62..00000000 --- a/src/wixext/Symbols/SqlFileSpecSymbol.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using WixToolset.Data; - using WixToolset.Sql.Symbols; - - public static partial class SqlSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition SqlFileSpec = new IntermediateSymbolDefinition( - SqlSymbolDefinitionType.SqlFileSpec.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(SqlFileSpecSymbolFields.Name), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlFileSpecSymbolFields.Filename), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlFileSpecSymbolFields.Size), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlFileSpecSymbolFields.MaxSize), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlFileSpecSymbolFields.GrowthSize), IntermediateFieldType.String), - }, - typeof(SqlFileSpecSymbol)); - } -} - -namespace WixToolset.Sql.Symbols -{ - using WixToolset.Data; - - public enum SqlFileSpecSymbolFields - { - Name, - Filename, - Size, - MaxSize, - GrowthSize, - } - - public class SqlFileSpecSymbol : IntermediateSymbol - { - public SqlFileSpecSymbol() : base(SqlSymbolDefinitions.SqlFileSpec, null, null) - { - } - - public SqlFileSpecSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(SqlSymbolDefinitions.SqlFileSpec, sourceLineNumber, id) - { - } - - public IntermediateField this[SqlFileSpecSymbolFields index] => this.Fields[(int)index]; - - public string Name - { - get => this.Fields[(int)SqlFileSpecSymbolFields.Name].AsString(); - set => this.Set((int)SqlFileSpecSymbolFields.Name, value); - } - - public string Filename - { - get => this.Fields[(int)SqlFileSpecSymbolFields.Filename].AsString(); - set => this.Set((int)SqlFileSpecSymbolFields.Filename, value); - } - - public string Size - { - get => this.Fields[(int)SqlFileSpecSymbolFields.Size].AsString(); - set => this.Set((int)SqlFileSpecSymbolFields.Size, value); - } - - public string MaxSize - { - get => this.Fields[(int)SqlFileSpecSymbolFields.MaxSize].AsString(); - set => this.Set((int)SqlFileSpecSymbolFields.MaxSize, value); - } - - public string GrowthSize - { - get => this.Fields[(int)SqlFileSpecSymbolFields.GrowthSize].AsString(); - set => this.Set((int)SqlFileSpecSymbolFields.GrowthSize, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/SqlScriptSymbol.cs b/src/wixext/Symbols/SqlScriptSymbol.cs deleted file mode 100644 index 94c70390..00000000 --- a/src/wixext/Symbols/SqlScriptSymbol.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using WixToolset.Data; - using WixToolset.Sql.Symbols; - - public static partial class SqlSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition SqlScript = new IntermediateSymbolDefinition( - SqlSymbolDefinitionType.SqlScript.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.SqlDbRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.ScriptBinaryRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.UserRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.Attributes), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(SqlScriptSymbolFields.Sequence), IntermediateFieldType.Number), - }, - typeof(SqlScriptSymbol)); - } -} - -namespace WixToolset.Sql.Symbols -{ - using WixToolset.Data; - - public enum SqlScriptSymbolFields - { - SqlDbRef, - ComponentRef, - ScriptBinaryRef, - UserRef, - Attributes, - Sequence, - } - - public class SqlScriptSymbol : IntermediateSymbol - { - public SqlScriptSymbol() : base(SqlSymbolDefinitions.SqlScript, null, null) - { - } - - public SqlScriptSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(SqlSymbolDefinitions.SqlScript, sourceLineNumber, id) - { - } - - public IntermediateField this[SqlScriptSymbolFields index] => this.Fields[(int)index]; - - public string SqlDbRef - { - get => this.Fields[(int)SqlScriptSymbolFields.SqlDbRef].AsString(); - set => this.Set((int)SqlScriptSymbolFields.SqlDbRef, value); - } - - public string ComponentRef - { - get => this.Fields[(int)SqlScriptSymbolFields.ComponentRef].AsString(); - set => this.Set((int)SqlScriptSymbolFields.ComponentRef, value); - } - - public string ScriptBinaryRef - { - get => this.Fields[(int)SqlScriptSymbolFields.ScriptBinaryRef].AsString(); - set => this.Set((int)SqlScriptSymbolFields.ScriptBinaryRef, value); - } - - public string UserRef - { - get => this.Fields[(int)SqlScriptSymbolFields.UserRef].AsString(); - set => this.Set((int)SqlScriptSymbolFields.UserRef, value); - } - - public int Attributes - { - get => this.Fields[(int)SqlScriptSymbolFields.Attributes].AsNumber(); - set => this.Set((int)SqlScriptSymbolFields.Attributes, value); - } - - public int? Sequence - { - get => this.Fields[(int)SqlScriptSymbolFields.Sequence].AsNullableNumber(); - set => this.Set((int)SqlScriptSymbolFields.Sequence, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/SqlStringSymbol.cs b/src/wixext/Symbols/SqlStringSymbol.cs deleted file mode 100644 index 73a8206e..00000000 --- a/src/wixext/Symbols/SqlStringSymbol.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using WixToolset.Data; - using WixToolset.Sql.Symbols; - - public static partial class SqlSymbolDefinitions - { - public static readonly IntermediateSymbolDefinition SqlString = new IntermediateSymbolDefinition( - SqlSymbolDefinitionType.SqlString.ToString(), - new[] - { - new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.SqlDbRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.SQL), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.UserRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.Attributes), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(SqlStringSymbolFields.Sequence), IntermediateFieldType.Number), - }, - typeof(SqlStringSymbol)); - } -} - -namespace WixToolset.Sql.Symbols -{ - using WixToolset.Data; - - public enum SqlStringSymbolFields - { - SqlDbRef, - ComponentRef, - SQL, - UserRef, - Attributes, - Sequence, - } - - public class SqlStringSymbol : IntermediateSymbol - { - public SqlStringSymbol() : base(SqlSymbolDefinitions.SqlString, null, null) - { - } - - public SqlStringSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(SqlSymbolDefinitions.SqlString, sourceLineNumber, id) - { - } - - public IntermediateField this[SqlStringSymbolFields index] => this.Fields[(int)index]; - - public string SqlDbRef - { - get => this.Fields[(int)SqlStringSymbolFields.SqlDbRef].AsString(); - set => this.Set((int)SqlStringSymbolFields.SqlDbRef, value); - } - - public string ComponentRef - { - get => this.Fields[(int)SqlStringSymbolFields.ComponentRef].AsString(); - set => this.Set((int)SqlStringSymbolFields.ComponentRef, value); - } - - public string SQL - { - get => this.Fields[(int)SqlStringSymbolFields.SQL].AsString(); - set => this.Set((int)SqlStringSymbolFields.SQL, value); - } - - public string UserRef - { - get => this.Fields[(int)SqlStringSymbolFields.UserRef].AsString(); - set => this.Set((int)SqlStringSymbolFields.UserRef, value); - } - - public int Attributes - { - get => this.Fields[(int)SqlStringSymbolFields.Attributes].AsNumber(); - set => this.Set((int)SqlStringSymbolFields.Attributes, value); - } - - public int? Sequence - { - get => this.Fields[(int)SqlStringSymbolFields.Sequence].AsNullableNumber(); - set => this.Set((int)SqlStringSymbolFields.Sequence, value); - } - } -} \ No newline at end of file diff --git a/src/wixext/Symbols/SqlSymbolDefinitions.cs b/src/wixext/Symbols/SqlSymbolDefinitions.cs deleted file mode 100644 index 336f1546..00000000 --- a/src/wixext/Symbols/SqlSymbolDefinitions.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Sql -{ - using System; - using WixToolset.Data; - - public enum SqlSymbolDefinitionType - { - SqlDatabase, - SqlFileSpec, - SqlScript, - SqlString, - } - - public static partial class SqlSymbolDefinitions - { - public static readonly Version Version = new Version("4.0.0"); - - public static IntermediateSymbolDefinition ByName(string name) - { - if (!Enum.TryParse(name, out SqlSymbolDefinitionType type)) - { - return null; - } - - return ByType(type); - } - - public static IntermediateSymbolDefinition ByType(SqlSymbolDefinitionType type) - { - switch (type) - { - case SqlSymbolDefinitionType.SqlDatabase: - return SqlSymbolDefinitions.SqlDatabase; - - case SqlSymbolDefinitionType.SqlFileSpec: - return SqlSymbolDefinitions.SqlFileSpec; - - case SqlSymbolDefinitionType.SqlScript: - return SqlSymbolDefinitions.SqlScript; - - case SqlSymbolDefinitionType.SqlString: - return SqlSymbolDefinitions.SqlString; - - default: - throw new ArgumentOutOfRangeException(nameof(type)); - } - } - } -} diff --git a/src/wixext/WixToolset.Sql.wixext.csproj b/src/wixext/WixToolset.Sql.wixext.csproj deleted file mode 100644 index 5a1ebeb0..00000000 --- a/src/wixext/WixToolset.Sql.wixext.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - netstandard2.0 - WixToolset.Sql - WiX Toolset Sql Extension - WiX Toolset Sql Extension - embedded - true - - - - - - - - - - - - - - - - - - - diff --git a/src/wixext/WixToolset.Sql.wixext.nuspec b/src/wixext/WixToolset.Sql.wixext.nuspec deleted file mode 100644 index ba3eaade..00000000 --- a/src/wixext/WixToolset.Sql.wixext.nuspec +++ /dev/null @@ -1,25 +0,0 @@ - - - - $id$ - $version$ - $title$ - $description$ - $authors$ - MS-RL - false - $copyright$ - $projectUrl$ - - - - - - - - - - - - - diff --git a/src/wixext/WixToolset.Sql.wixext.targets b/src/wixext/WixToolset.Sql.wixext.targets deleted file mode 100644 index 4950e119..00000000 --- a/src/wixext/WixToolset.Sql.wixext.targets +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - $(MSBuildThisFileDirectory)..\tools\WixToolset.Sql.wixext.dll - - - - - diff --git a/src/wixlib/SqlExtension.wxi b/src/wixlib/SqlExtension.wxi deleted file mode 100644 index c9261f1d..00000000 --- a/src/wixlib/SqlExtension.wxi +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/wixlib/SqlExtension.wxs b/src/wixlib/SqlExtension.wxs deleted file mode 100644 index 8b5320fa..00000000 --- a/src/wixlib/SqlExtension.wxs +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/wixlib/SqlExtension_arm64.wxs b/src/wixlib/SqlExtension_arm64.wxs deleted file mode 100644 index e8d22f69..00000000 --- a/src/wixlib/SqlExtension_arm64.wxs +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/wixlib/SqlExtension_x64.wxs b/src/wixlib/SqlExtension_x64.wxs deleted file mode 100644 index e55a14e4..00000000 --- a/src/wixlib/SqlExtension_x64.wxs +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/wixlib/SqlExtension_x86.wxs b/src/wixlib/SqlExtension_x86.wxs deleted file mode 100644 index 1a51ed91..00000000 --- a/src/wixlib/SqlExtension_x86.wxs +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/wixlib/caDecor.wxi b/src/wixlib/caDecor.wxi deleted file mode 100644 index b1711518..00000000 --- a/src/wixlib/caDecor.wxi +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/wixlib/caerr.wxi b/src/wixlib/caerr.wxi deleted file mode 100644 index ff7ec121..00000000 --- a/src/wixlib/caerr.wxi +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/wixlib/de-de.wxl b/src/wixlib/de-de.wxl deleted file mode 100644 index ed2313a4..00000000 --- a/src/wixlib/de-de.wxl +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Fehler [2]: Erstellen der SQL-Datenbank fehlgeschlagen: [3], Fehlerbeschreibung: [4]. - Fehler [2]: Löschen der SQL-Datenbank fehlgeschlagen: [3], Fehlerbeschreibung: [4]. - Verbinden mit der SQL-Datenbank fehlgeschlagen. ([2] [3] [4] [5]) - Fehler [2]: Das Erstellen der SQL Zeichenfolge ist fehlgeschlagen, Fehlerbeschreibung: [3], SQL-Schlüssel: [4] SQL-Zeichenfolge: [5] - Die Datenbank [3] existiert bereits. Wollen Sie fortfahren? - - Konfiguriere SQL Server - Erstelle Datenbanken - Lösche Datenbanken - SQL-Zeichenfolgen werden erstellt - SQL-Zeichenfolgen werden zurückgesetzt - diff --git a/src/wixlib/en-us.wxl b/src/wixlib/en-us.wxl deleted file mode 100644 index d3ffd5eb..00000000 --- a/src/wixlib/en-us.wxl +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Error [2]: failed to create SQL database: [3], error detail: [4]. - Error [2]: failed to drop SQL database: [3], error detail: [4]. - Failed to connect to SQL database. ([2] [3] [4] [5]) - Error [2]: failed to execute SQL string, error detail: [3], SQL key: [4] SQL string: [5] - The database [3] already exists. Do you want to continue? - - Configuring SQL Server - Creating Databases - Dropping Databases - Executing SQL Strings - Rolling back SQL Strings - diff --git a/src/wixlib/es-es.wxl b/src/wixlib/es-es.wxl deleted file mode 100644 index b2e5d499..00000000 --- a/src/wixlib/es-es.wxl +++ /dev/null @@ -1,17 +0,0 @@ - - - - - Error [2]: falla al crear la base de datos SQL: [3], detalle del error: [4]. - Error [2]: falla al poner la base de datos SQL: [3], detalle del error: [4]. - Falla al conectarse con la base de datos SQL. ([2] [3] [4] [5]) - Error [2]: falla al ejecutar la cadena SQL, detalle del error: [3], Clave SQL: [4] Cadena SQL: [5] - La base de datos [3] ya existe. ¿Desea continuar? - - Configurando SQL Server - Creando Bases de Datos - Colocando Bases de Datos - Ejecutando cadenas SQL - Revirtiendo cadenas SQL - - diff --git a/src/wixlib/ja-jp.wxl b/src/wixlib/ja-jp.wxl deleted file mode 100644 index 6e35fd17..00000000 --- a/src/wixlib/ja-jp.wxl +++ /dev/null @@ -1,16 +0,0 @@ - - - - - エラー [2]: SQL データベース [3] 作成に失敗しました、エラー詳細: [4]。 - エラー [2]: SQL データベース [3] の削除に失敗しました、エラー詳細: [4]。 - SQL データベースへ接続できませんでした。 ([2] [3] [4] [5]) - エラー [2]: SQL ストリングの実行に失敗しました、エラー詳細: [3]、 SQL キー: [4] SQL ストリング: [5] - データベース [3] は既に存在します。続行しますか? - - SQL サーバーを構成しています - データベースを作成しています - データベースを削除しています - SQL ストリングを実行しています - SQL ストリングをロールバックしています - diff --git a/src/wixlib/pl-pl.wxl b/src/wixlib/pl-pl.wxl deleted file mode 100644 index 6200e0e9..00000000 --- a/src/wixlib/pl-pl.wxl +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Błąd [2]: nie udało się utworzyć bazy danych: [3]. Szczegóły błędu: [4]. - Błąd [2]: nie udało się usunąć bazy danych: [3]. Szczegóły błędu: [4]. - Nie udało się połączyć z bazą danych. ([2] [3] [4] [5]) - Błąd [2]: nie udało się wykonać zapytania SQL. Szczegóły błędu: [3], klucz: [4] zapytanie SQL: [5] - Baza danych [3] już istnieje. Czy chcesz kontynuować? - - Konfigurowanie programu SQL Server - Tworzenie baz danych - Usuwanie baz danych - Wykonywanie zapytań SQL - Cofanie zapytań SQL - diff --git a/src/wixlib/pt-br.wxl b/src/wixlib/pt-br.wxl deleted file mode 100644 index 74c53313..00000000 --- a/src/wixlib/pt-br.wxl +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Error [2]: falha ao criar o Banco de Dados: [3], detalhes: [4]. - Error [2]: falha ao remover o Banco de Dados: [3], detalhes: [4]. - Falhou a ligação ao Banco de Dados. ([2] [3] [4] [5]) - Erro [2]: falha ao executar o comando de SQL, detalhes: [3], Comando: [4] Conteúdo: [5] - O Banco de Dados [3] já existe. Deseja continuar? - - Configurando o Servidor de SQL - Criando os Bancos de Dados - Removendo os Bancos de Dados - Executando comandos de SQL - Revertendo os comandos de SQL - diff --git a/src/wixlib/pt-pt.wxl b/src/wixlib/pt-pt.wxl deleted file mode 100644 index 90d9df4f..00000000 --- a/src/wixlib/pt-pt.wxl +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Error [2]: falha ao criar a Base de Dados: [3], detalhes: [4]. - Error [2]: falha ao remover a Base de Dados: [3], detalhes: [4]. - Falhou a ligação à Base de Dados. ([2] [3] [4] [5]) - Erro [2]: falha ao executar o comando de SQL, detalhes: [3], Comando: [4] Conteúdo: [5] - A Base de Dados [3] já existe. Deseja continuar? - - Configurar o Servidor de SQL - Criar as Bases de Dados - Remover as Bases de Dados - Executar comandos de SQL - Reverter os comandos de SQL - diff --git a/src/wixlib/sql.v3.ncrunchproject b/src/wixlib/sql.v3.ncrunchproject deleted file mode 100644 index 319cd523..00000000 --- a/src/wixlib/sql.v3.ncrunchproject +++ /dev/null @@ -1,5 +0,0 @@ - - - True - - \ No newline at end of file diff --git a/src/wixlib/sql.wixproj b/src/wixlib/sql.wixproj deleted file mode 100644 index ac994e6b..00000000 --- a/src/wixlib/sql.wixproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Library - true - - - - - - - - - - - - - - - - - - -- cgit v1.2.3-55-g6feb