diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5e09eb0f67d..1ac44fa05ad 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -14,16 +14,36 @@ variables: _PublishUsingPipelines: true _DotNetArtifactsCategory: WINDOWSDESKTOP +# This is set in the pipeline directly +# When set to false, CI tests will not be enabled in builds. +# +# _ContinuousIntegrationTestsEnabled: false + +# Setting batch to true, triggers one build at a time. +# if there is a push while a build in progress, it will wait, +# until the running build finishes, and produce a build with all the changes +# # only trigger ci builds for the master and release branches trigger: -- master -- release/3.0 -- arcade - -# To be added in the future when VSTS supports this feature -# only trigger pull request builds for the master branch -# pr: -# - master + batch: true + branches: + include: + - master + - release/3.0 + # - arcade + paths: + exclude: + - Documentation/* + +pr: + autoCancel: true + branches: + include: + - master + - release/3.0 + paths: + exclude: + - Documentation/* # Call the pipeline.yml template, which does the real work jobs: diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3195ec438cb..9045527ef65 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,111 +1,111 @@ - + https://github.com/dotnet/winforms - 52be7e5282560d26926a288d75a8489cd856ec4a + b0e49f17123cda852fecfc4610036f31de0d3b94 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/core-setup - e1d780539e85f4d8de263957715f9d08db2ceef4 + 915722554dc08a7075f89eddb40691caca23b6be - + https://github.com/dotnet/arcade - 332e44d0a09e1c781c9bea9a48c07d0b0151d6c7 + a8e982d3bac01d8f4f91a4c57191147570079448 - + https://github.com/dotnet/arcade - 332e44d0a09e1c781c9bea9a48c07d0b0151d6c7 + a8e982d3bac01d8f4f91a4c57191147570079448 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://dev.azure.com/dnceng/internal/_git/dotnet-wpf-int - 120e86951727331e5b899ed8b5b3b4ac35764b42 + 8248026ca9df8ba891de6de97b91779ecaa35983 - + https://github.com/dotnet/corefx - 468355e66daf9eaeb1978703fa6365cd1e37e644 + 80f411d58df8338ccd9430900b541a037a9cb383 - + https://github.com/dotnet/coreclr - 8974a699899bdc2cc5687504e1ada606ac803e9b + c01a9a157d512343ef104bb2b1f97b356e708b11 - + https://github.com/dotnet/coreclr - 8974a699899bdc2cc5687504e1ada606ac803e9b + c01a9a157d512343ef104bb2b1f97b356e708b11 - + https://github.com/dotnet/coreclr - 8974a699899bdc2cc5687504e1ada606ac803e9b + c01a9a157d512343ef104bb2b1f97b356e708b11 - + https://github.com/dotnet/arcade - 332e44d0a09e1c781c9bea9a48c07d0b0151d6c7 + a8e982d3bac01d8f4f91a4c57191147570079448 - + https://github.com/dotnet/arcade - 332e44d0a09e1c781c9bea9a48c07d0b0151d6c7 + a8e982d3bac01d8f4f91a4c57191147570079448 - + https://github.com/dotnet/arcade - 332e44d0a09e1c781c9bea9a48c07d0b0151d6c7 + a8e982d3bac01d8f4f91a4c57191147570079448 diff --git a/eng/Versions.props b/eng/Versions.props index 8b90edcb41f..4fe293f86e0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -2,47 +2,47 @@ 4.8.0 - preview7 + preview8 4.0.0.0 - 4.6.0-preview7.19320.1 + 4.6.0-preview8.19378.8 - 4.8.0-preview7.19352.2 + 4.8.0-preview8.19379.9 - 3.0.0-preview7.19323.2 - 3.0.0-preview7.19323.2 - 3.0.0-preview7.19323.2 + 3.0.0-preview8.19372.4 + 3.0.0-preview8.19372.4 + 3.0.0-preview8.19372.4 - 3.0.0-preview7-27824-03 - 3.0.0-preview7.19320.1 - 4.6.0-preview7.19320.1 - 4.6.0-preview7.19320.1 - 4.6.0-preview7.19320.1 + 3.0.0-preview8-28379-03 + 3.0.0-preview8.19378.8 + 4.6.0-preview8.19378.8 + 4.6.0-preview8.19378.8 + 4.6.0-preview8.19378.8 - 4.6.0-preview7.19320.1 - 4.6.0-preview7.19320.1 - 4.6.0-preview7.19320.1 - 4.6.0-preview7.19320.1 - 4.6.0-preview7.19320.1 + 4.6.0-preview8.19378.8 + 4.6.0-preview8.19378.8 + 4.6.0-preview8.19378.8 + 4.6.0-preview8.19378.8 + 4.6.0-preview8.19378.8 4.6.0-preview4.19176.11 - 4.6.0-preview7.19320.1 - 4.6.0-preview7.19320.1 - 4.6.0-preview7.19320.1 - 4.6.0-preview7.19320.1 - 4.6.0-preview7.19320.1 + 4.6.0-preview8.19378.8 + 4.6.0-preview8.19378.8 + 4.6.0-preview8.19378.8 + 4.6.0-preview8.19378.8 + 4.6.0-preview8.19378.8 - 1.0.0-beta.19326.23 - 1.0.0-beta.19326.23 - 1.0.0-beta.19326.23 + 1.0.0-beta.19378.1 + 1.0.0-beta.19378.1 + 1.0.0-beta.19378.1 @@ -59,6 +59,11 @@ 2.4.0 $(XUnitVersion) $(XUnitVersion) + + 0.0.0.6 - 4.8.0-preview7.19326.21 + 4.8.0-preview8.19379.4 diff --git a/eng/WpfArcadeSdk/Sdk/Sdk.props b/eng/WpfArcadeSdk/Sdk/Sdk.props index d10a40453e1..d5f6c0629be 100644 --- a/eng/WpfArcadeSdk/Sdk/Sdk.props +++ b/eng/WpfArcadeSdk/Sdk/Sdk.props @@ -68,6 +68,20 @@ Suppress NU1605 (Package downgrade warnings) when building inside Visual Studio --> $(NoWarn);NU1605 + + + $(AdditionalNoWarn);$(NoWarn) diff --git a/eng/WpfArcadeSdk/tools/TestProjects.targets b/eng/WpfArcadeSdk/tools/TestProjects.targets index 335d9cacf16..1cd360f2579 100644 --- a/eng/WpfArcadeSdk/tools/TestProjects.targets +++ b/eng/WpfArcadeSdk/tools/TestProjects.targets @@ -30,7 +30,6 @@ - diff --git a/eng/WpfArcadeSdk/tools/Wpf.Cpp.PrivateTools.props b/eng/WpfArcadeSdk/tools/Wpf.Cpp.PrivateTools.props new file mode 100644 index 00000000000..fae7d5a8e14 --- /dev/null +++ b/eng/WpfArcadeSdk/tools/Wpf.Cpp.PrivateTools.props @@ -0,0 +1,27 @@ + + + + + $(RepoRoot).tools\native\bin\msvcurt-c1xx\$(MsvcurtC1xxVersion)\$(Architecture)\ + $(MsvcurtC1xxToolsPath)msvcurt$(LibSuffix)_netcore.lib + + + + + + %(AdditionalDependencies);$(MsvcurtNetCoreLib) + + + diff --git a/eng/WpfArcadeSdk/tools/Wpf.Cpp.PrivateTools.targets b/eng/WpfArcadeSdk/tools/Wpf.Cpp.PrivateTools.targets new file mode 100644 index 00000000000..80ad4843126 --- /dev/null +++ b/eng/WpfArcadeSdk/tools/Wpf.Cpp.PrivateTools.targets @@ -0,0 +1,43 @@ + + + + + $(MsvcurtC1xxToolsPath)HostX86\c1xx.dll + $(MsvcurtC1xxToolsPath)HostX64\c1xx.dll + + $(MsvcurtC1xxToolsPath)HostX86\c2.dll + $(MsvcurtC1xxToolsPath)HostX64\c2.dll + + + + + + + + %(AdditionalOptions) /Bx"$(FrontEndPath)" + + + %(AdditionalOptions) /fe:"$(FrontEndPath)" + + + + + + %(AdditionalOptions) /B2"$(BackEndPath)" + + + + diff --git a/eng/WpfArcadeSdk/tools/Wpf.Cpp.props b/eng/WpfArcadeSdk/tools/Wpf.Cpp.props index 5624ab16cb0..5b83f7f792b 100644 --- a/eng/WpfArcadeSdk/tools/Wpf.Cpp.props +++ b/eng/WpfArcadeSdk/tools/Wpf.Cpp.props @@ -89,30 +89,10 @@ - - - - 0.0.0.4 - true - $(RepoRoot).tools\native\bin\msvcurt-c1xx\$(MsvcurtC1xxVersion)\$(Architecture)\ - $(MsvcurtC1xxToolsPath)msvcurt$(LibSuffix)_netcore.lib - + true + - - - %(AdditionalDependencies);$(MsvcurtNetCoreLib) - - - diff --git a/eng/WpfArcadeSdk/tools/Wpf.Cpp.targets b/eng/WpfArcadeSdk/tools/Wpf.Cpp.targets index d2c806f217b..f14aa74b1f1 100644 --- a/eng/WpfArcadeSdk/tools/Wpf.Cpp.targets +++ b/eng/WpfArcadeSdk/tools/Wpf.Cpp.targets @@ -4,33 +4,8 @@ $([System.IO.Path]::GetDirectoryName($(NativeVersionFile))) - - - - - $(MsvcurtC1xxToolsPath)HostX86\c1xx.dll - $(MsvcurtC1xxToolsPath)HostX64\c1xx.dll - - $(MsvcurtC1xxToolsPath)HostX86\c2.dll - $(MsvcurtC1xxToolsPath)HostX64\c2.dll - - - - %(AdditionalOptions) /Bx"$(FrontEndPath)" - - - %(AdditionalOptions) /fe:"$(FrontEndPath)" - - - - - %(AdditionalOptions) /B2"$(BackEndPath)" - - - - + + %(AdditionalIncludeDirectories);$(WpfSharedDir)inc\ diff --git a/eng/common/SigningValidation.proj b/eng/common/SigningValidation.proj index 7045fb6fb9d..3d0ac80af3f 100644 --- a/eng/common/SigningValidation.proj +++ b/eng/common/SigningValidation.proj @@ -3,7 +3,7 @@ + + + $(WorkItemDirectory) + $(WorkItemCommand) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(CoreRunArgument) --artifacts $(ArtifactsDirectory) --partition-count $(PartitionCount) --partition-index %(HelixWorkItem.Index)" + 4:00 + + + + + $(WorkItemDirectory) + $(WorkItemCommand) --bdn-arguments="--anyCategories $(BDNCategories) $(ExtraBenchmarkDotNetArguments) $(CoreRunArgument) --artifacts $(ArtifactsDirectory)" + 4:00 + + + \ No newline at end of file diff --git a/eng/common/performance/performance-setup.ps1 b/eng/common/performance/performance-setup.ps1 new file mode 100644 index 00000000000..7e5441f7974 --- /dev/null +++ b/eng/common/performance/performance-setup.ps1 @@ -0,0 +1,91 @@ +Param( + [string] $SourceDirectory=$env:BUILD_SOURCESDIRECTORY, + [string] $CoreRootDirectory, + [string] $Architecture="x64", + [string] $Framework="netcoreapp3.0", + [string] $CompilationMode="Tiered", + [string] $Repository=$env:BUILD_REPOSITORY_NAME, + [string] $Branch=$env:BUILD_SOURCEBRANCH, + [string] $CommitSha=$env:BUILD_SOURCEVERSION, + [string] $BuildNumber=$env:BUILD_BUILDNUMBER, + [string] $RunCategories="coreclr corefx", + [string] $Csproj="src\benchmarks\micro\MicroBenchmarks.csproj", + [string] $Kind="micro", + [switch] $Internal, + [string] $Configurations="CompilationMode=$CompilationMode" +) + +$RunFromPerformanceRepo = ($Repository -eq "dotnet/performance") +$UseCoreRun = ($CoreRootDirectory -ne [string]::Empty) + +$PayloadDirectory = (Join-Path $SourceDirectory "Payload") +$PerformanceDirectory = (Join-Path $PayloadDirectory "performance") +$WorkItemDirectory = (Join-Path $SourceDirectory "workitem") +$ExtraBenchmarkDotNetArguments = "--iterationCount 1 --warmupCount 0 --invocationCount 1 --unrollFactor 1 --strategy ColdStart --stopOnFirstError true" +$Creator = $env:BUILD_DEFINITIONNAME +$PerfLabArguments = "" +$HelixSourcePrefix = "pr" + +$Queue = "Windows.10.Amd64.ClientRS4.DevEx.15.8.Open" + +if ($Framework.StartsWith("netcoreapp")) { + $Queue = "Windows.10.Amd64.ClientRS4.Open" +} + +if ($Internal) { + $Queue = "Windows.10.Amd64.ClientRS5.Perf" + $PerfLabArguments = "--upload-to-perflab-container" + $ExtraBenchmarkDotNetArguments = "" + $Creator = "" + $HelixSourcePrefix = "official" +} + +$CommonSetupArguments="--frameworks $Framework --queue $Queue --build-number $BuildNumber --build-configs $Configurations" +$SetupArguments = "--repository https://github.com/$Repository --branch $Branch --get-perf-hash --commit-sha $CommitSha $CommonSetupArguments" + +if ($RunFromPerformanceRepo) { + $SetupArguments = "--perf-hash $CommitSha $CommonSetupArguments" + + robocopy $SourceDirectory $PerformanceDirectory /E /XD $PayloadDirectory $SourceDirectory\artifacts $SourceDirectory\.git +} +else { + git clone --branch master --depth 1 --quiet https://github.com/dotnet/performance $PerformanceDirectory +} + +if ($UseCoreRun) { + $NewCoreRoot = (Join-Path $PayloadDirectory "Core_Root") + Move-Item -Path $CoreRootDirectory -Destination $NewCoreRoot +} + +$DocsDir = (Join-Path $PerformanceDirectory "docs") +robocopy $DocsDir $WorkItemDirectory + +# Set variables that we will need to have in future steps +$ci = $true + +. "$PSScriptRoot\..\pipeline-logging-functions.ps1" + +# Directories +Write-PipelineSetVariable -Name 'PayloadDirectory' -Value "$PayloadDirectory" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'PerformanceDirectory' -Value "$PerformanceDirectory" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'WorkItemDirectory' -Value "$WorkItemDirectory" -IsMultiJobVariable $false + +# Script Arguments +Write-PipelineSetVariable -Name 'Python' -Value "py -3" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'ExtraBenchmarkDotNetArguments' -Value "$ExtraBenchmarkDotNetArguments" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'SetupArguments' -Value "$SetupArguments" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'PerfLabArguments' -Value "$PerfLabArguments" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'BDNCategories' -Value "$RunCategories" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'TargetCsproj' -Value "$Csproj" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'Kind' -Value "$Kind" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'Architecture' -Value "$Architecture" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'UseCoreRun' -Value "$UseCoreRun" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'RunFromPerfRepo' -Value "$RunFromPerformanceRepo" -IsMultiJobVariable $false + +# Helix Arguments +Write-PipelineSetVariable -Name 'Creator' -Value "$Creator" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'Queue' -Value "$Queue" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name 'HelixSourcePrefix' -Value "$HelixSourcePrefix" -IsMultiJobVariable $false +Write-PipelineSetVariable -Name '_BuildConfig' -Value "$Architecture.$Kind.$Framework" -IsMultiJobVariable $false + +exit 0 \ No newline at end of file diff --git a/eng/common/performance/performance-setup.sh b/eng/common/performance/performance-setup.sh new file mode 100755 index 00000000000..126da5f76d4 --- /dev/null +++ b/eng/common/performance/performance-setup.sh @@ -0,0 +1,176 @@ +#!/usr/bin/env bash + +source_directory=$BUILD_SOURCESDIRECTORY +core_root_directory= +architecture=x64 +framework=netcoreapp3.0 +compilation_mode=tiered +repository=$BUILD_REPOSITORY_NAME +branch=$BUILD_SOURCEBRANCH +commit_sha=$BUILD_SOURCEVERSION +build_number=$BUILD_BUILDNUMBER +internal=false +kind="micro" +run_categories="coreclr corefx" +csproj="src\benchmarks\micro\MicroBenchmarks.csproj" +configurations= +run_from_perf_repo=false +use_core_run=true + +while (($# > 0)); do + lowerI="$(echo $1 | awk '{print tolower($0)}')" + case $lowerI in + --sourcedirectory) + source_directory=$2 + shift 2 + ;; + --corerootdirectory) + core_root_directory=$2 + shift 2 + ;; + --architecture) + architecture=$2 + shift 2 + ;; + --framework) + framework=$2 + shift 2 + ;; + --compilationmode) + compilation_mode=$2 + shift 2 + ;; + --repository) + repository=$2 + shift 2 + ;; + --branch) + branch=$2 + shift 2 + ;; + --commitsha) + commit_sha=$2 + shift 2 + ;; + --buildnumber) + build_number=$2 + shift 2 + ;; + --kind) + kind=$2 + shift 2 + ;; + --runcategories) + run_categories=$2 + shift 2 + ;; + --csproj) + csproj=$2 + shift 2 + ;; + --internal) + internal=true + shift 1 + ;; + --configurations) + configurations=$2 + shift 2 + ;; + --help) + echo "Common settings:" + echo " --corerootdirectory Directory where Core_Root exists, if running perf testing with --corerun" + echo " --architecture Architecture of the testing being run" + echo " --configurations List of key=value pairs that will be passed to perf testing infrastructure." + echo " ex: --configurations \"CompilationMode=Tiered OptimzationLevel=PGO\"" + echo " --help Print help and exit" + echo "" + echo "Advanced settings:" + echo " --framework The framework to run, if not running in master" + echo " --compliationmode The compilation mode if not passing --configurations" + echo " --sourcedirectory The directory of the sources. Defaults to env:BUILD_SOURCESDIRECTORY" + echo " --repository The name of the repository in the / format. Defaults to env:BUILD_REPOSITORY_NAME" + echo " --branch The name of the branch. Defaults to env:BUILD_SOURCEBRANCH" + echo " --commitsha The commit sha1 to run against. Defaults to env:BUILD_SOURCEVERSION" + echo " --buildnumber The build number currently running. Defaults to env:BUILD_BUILDNUMBER" + echo " --csproj The relative path to the benchmark csproj whose tests should be run. Defaults to src\benchmarks\micro\MicroBenchmarks.csproj" + echo " --kind Related to csproj. The kind of benchmarks that should be run. Defaults to micro" + echo " --runcategories Related to csproj. Categories of benchmarks to run. Defaults to \"coreclr corefx\"" + echo " --internal If the benchmarks are running as an official job." + echo "" + exit 0 + ;; + esac +done + +if [[ "$repository" == "dotnet/performance" ]]; then + run_from_perf_repo=true +fi + +if [ -z "$configurations" ]; then + configurations="CompliationMode=$compilation_mode" +fi + +if [ -z "$core_root_directory" ]; then + use_core_run=false +fi + +payload_directory=$source_directory/Payload +performance_directory=$payload_directory/performance +workitem_directory=$source_directory/workitem +extra_benchmark_dotnet_arguments="--iterationCount 1 --warmupCount 0 --invocationCount 1 --unrollFactor 1 --strategy ColdStart --stopOnFirstError true" +perflab_arguments= +queue=Ubuntu.1804.Amd64.Open +creator=$BUILD_DEFINITIONNAME +helix_source_prefix="pr" + +if [[ "$internal" == true ]]; then + perflab_arguments="--upload-to-perflab-container" + helix_source_prefix="official" + creator= + extra_benchmark_dotnet_arguments= + + if [[ "$architecture" = "arm64" ]]; then + queue=Ubuntu.1804.Arm64.Perf + else + queue=Ubuntu.1804.Amd64.Perf + fi +fi + +common_setup_arguments="--frameworks $framework --queue $queue --build-number $build_number --build-configs $configurations" +setup_arguments="--repository https://github.com/$repository --branch $branch --get-perf-hash --commit-sha $commit_sha $common_setup_arguments" + +if [[ "$run_from_perf_repo" = true ]]; then + payload_directory= + workitem_directory=$source_directory + performance_directory=$workitem_directory + setup_arguments="--perf-hash $commit_sha $common_setup_arguments" +else + git clone --branch master --depth 1 --quiet https://github.com/dotnet/performance $performance_directory + + docs_directory=$performance_directory/docs + mv $docs_directory $workitem_directory +fi + +if [[ "$use_core_run" = true ]]; then + new_core_root=$payload_directory/Core_Root + mv $core_root_directory $new_core_root +fi + +# Make sure all of our variables are available for future steps +echo "##vso[task.setvariable variable=UseCoreRun]$use_core_run" +echo "##vso[task.setvariable variable=Architecture]$architecture" +echo "##vso[task.setvariable variable=PayloadDirectory]$payload_directory" +echo "##vso[task.setvariable variable=PerformanceDirectory]$performance_directory" +echo "##vso[task.setvariable variable=WorkItemDirectory]$workitem_directory" +echo "##vso[task.setvariable variable=Queue]$queue" +echo "##vso[task.setvariable variable=SetupArguments]$setup_arguments" +echo "##vso[task.setvariable variable=Python]python3" +echo "##vso[task.setvariable variable=PerfLabArguments]$perflab_arguments" +echo "##vso[task.setvariable variable=ExtraBenchmarkDotNetArguments]$extra_benchmark_dotnet_arguments" +echo "##vso[task.setvariable variable=BDNCategories]$run_categories" +echo "##vso[task.setvariable variable=TargetCsproj]$csproj" +echo "##vso[task.setvariable variable=RunFromPerfRepo]$run_from_perf_repo" +echo "##vso[task.setvariable variable=Creator]$creator" +echo "##vso[task.setvariable variable=HelixSourcePrefix]$helix_source_prefix" +echo "##vso[task.setvariable variable=Kind]$kind" +echo "##vso[task.setvariable variable=_BuildConfig]$architecture.$kind.$framework" \ No newline at end of file diff --git a/eng/common/pipeline-logging-functions.ps1 b/eng/common/pipeline-logging-functions.ps1 index 7b61376f8aa..af5f48aaceb 100644 --- a/eng/common/pipeline-logging-functions.ps1 +++ b/eng/common/pipeline-logging-functions.ps1 @@ -77,13 +77,14 @@ function Write-PipelineTaskError { [string]$Name, [string]$Value, [switch]$Secret, - [switch]$AsOutput) - + [switch]$AsOutput, + [bool]$IsMultiJobVariable=$true) + if($ci) { Write-LoggingCommand -Area 'task' -Event 'setvariable' -Data $Value -Properties @{ 'variable' = $Name 'isSecret' = $Secret - 'isOutput' = 'true' + 'isOutput' = $IsMultiJobVariable } -AsOutput:$AsOutput } } diff --git a/eng/common/pipeline-logging-functions.sh b/eng/common/pipeline-logging-functions.sh old mode 100644 new mode 100755 index 6098f9a5438..1c560a50613 --- a/eng/common/pipeline-logging-functions.sh +++ b/eng/common/pipeline-logging-functions.sh @@ -39,11 +39,11 @@ function Write-PipelineTaskError { return fi - message_type="error" - sourcepath='' - linenumber='' - columnnumber='' - error_code='' + local message_type="error" + local sourcepath='' + local linenumber='' + local columnnumber='' + local error_code='' while [[ $# -gt 0 ]]; do opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')" @@ -76,7 +76,7 @@ function Write-PipelineTaskError { shift done - message="##vso[task.logissue" + local message="##vso[task.logissue" message="$message type=$message_type" @@ -100,3 +100,73 @@ function Write-PipelineTaskError { echo "$message" } +function Write-PipelineSetVariable { + if [[ "$ci" != true ]]; then + return + fi + + local name='' + local value='' + local secret=false + local as_output=false + local is_multi_job_variable=true + + while [[ $# -gt 0 ]]; do + opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')" + case "$opt" in + -name|-n) + name=$2 + shift + ;; + -value|-v) + value=$2 + shift + ;; + -secret|-s) + secret=true + ;; + -as_output|-a) + as_output=true + ;; + -is_multi_job_variable|-i) + is_multi_job_variable=$2 + shift + ;; + esac + shift + done + + value=${value/;/%3B} + value=${value/\\r/%0D} + value=${value/\\n/%0A} + value=${value/]/%5D} + + local message="##vso[task.setvariable variable=$name;isSecret=$secret;isOutput=$is_multi_job_variable]$value" + + if [[ "$as_output" == true ]]; then + $message + else + echo "$message" + fi +} + +function Write-PipelinePrependPath { + local prepend_path='' + + while [[ $# -gt 0 ]]; do + opt="$(echo "${1/#--/-}" | awk '{print tolower($0)}')" + case "$opt" in + -path|-p) + prepend_path=$2 + shift + ;; + esac + shift + done + + export PATH="$prepend_path:$PATH" + + if [[ "$ci" == true ]]; then + echo "##vso[task.prependpath]$prepend_path" + fi +} \ No newline at end of file diff --git a/eng/common/post-build/darc-gather-drop.ps1 b/eng/common/post-build/darc-gather-drop.ps1 new file mode 100644 index 00000000000..93a0bd83285 --- /dev/null +++ b/eng/common/post-build/darc-gather-drop.ps1 @@ -0,0 +1,35 @@ +param( + [Parameter(Mandatory=$true)][int] $BarBuildId, # ID of the build which assets should be downloaded + [Parameter(Mandatory=$true)][string] $DropLocation, # Where the assets should be downloaded to + [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, # Token used to access Maestro API + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = "https://maestro-prod.westus2.cloudapp.azure.com", # Maestro API URL + [Parameter(Mandatory=$false)][string] $MaestroApiVersion = "2019-01-16" # Version of Maestro API to use +) + +. $PSScriptRoot\post-build-utils.ps1 + +try { + Write-Host "Installing DARC ..." + + . $PSScriptRoot\..\darc-init.ps1 + $exitCode = $LASTEXITCODE + + if ($exitCode -ne 0) { + Write-PipelineTaskError "Something failed while running 'darc-init.ps1'. Check for errors above. Exiting now..." + ExitWithExitCode $exitCode + } + + darc gather-drop --non-shipping ` + --continue-on-error ` + --id $BarBuildId ` + --output-dir $DropLocation ` + --bar-uri $MaestroApiEndpoint ` + --password $MaestroApiAccessToken ` + --latest-location +} +catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + ExitWithExitCode 1 +} diff --git a/eng/common/post-build/nuget-validation.ps1 b/eng/common/post-build/nuget-validation.ps1 new file mode 100644 index 00000000000..78ed0d540f5 --- /dev/null +++ b/eng/common/post-build/nuget-validation.ps1 @@ -0,0 +1,25 @@ +# This script validates NuGet package metadata information using this +# tool: https://github.com/NuGet/NuGetGallery/tree/jver-verify/src/VerifyMicrosoftPackage + +param( + [Parameter(Mandatory=$true)][string] $PackagesPath, # Path to where the packages to be validated are + [Parameter(Mandatory=$true)][string] $ToolDestinationPath # Where the validation tool should be downloaded to +) + +. $PSScriptRoot\post-build-utils.ps1 + +try { + $url = "https://raw.githubusercontent.com/NuGet/NuGetGallery/jver-verify/src/VerifyMicrosoftPackage/verify.ps1" + + New-Item -ItemType "directory" -Path ${ToolDestinationPath} -Force + + Invoke-WebRequest $url -OutFile ${ToolDestinationPath}\verify.ps1 + + & ${ToolDestinationPath}\verify.ps1 ${PackagesPath}\*.nupkg +} +catch { + Write-PipelineTaskError "NuGet package validation failed. Please check error logs." + Write-Host $_ + Write-Host $_.ScriptStackTrace + ExitWithExitCode 1 +} diff --git a/eng/common/post-build/post-build-utils.ps1 b/eng/common/post-build/post-build-utils.ps1 new file mode 100644 index 00000000000..551ae113f89 --- /dev/null +++ b/eng/common/post-build/post-build-utils.ps1 @@ -0,0 +1,90 @@ +# Most of the functions in this file require the variables `MaestroApiEndPoint`, +# `MaestroApiVersion` and `MaestroApiAccessToken` to be globally available. + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2.0 + +# `tools.ps1` checks $ci to perform some actions. Since the post-build +# scripts don't necessarily execute in the same agent that run the +# build.ps1/sh script this variable isn't automatically set. +$ci = $true +. $PSScriptRoot\..\tools.ps1 + +function Create-MaestroApiRequestHeaders([string]$ContentType = "application/json") { + Validate-MaestroVars + + $headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' + $headers.Add('Accept', $ContentType) + $headers.Add('Authorization',"Bearer $MaestroApiAccessToken") + return $headers +} + +function Get-MaestroChannel([int]$ChannelId) { + Validate-MaestroVars + + $apiHeaders = Create-MaestroApiRequestHeaders + $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}?api-version=$MaestroApiVersion" + + $result = try { Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + return $result +} + +function Get-MaestroBuild([int]$BuildId) { + Validate-MaestroVars + + $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken + $apiEndpoint = "$MaestroApiEndPoint/api/builds/${BuildId}?api-version=$MaestroApiVersion" + + $result = try { return Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + return $result +} + +function Get-MaestroSubscriptions([string]$SourceRepository, [int]$ChannelId) { + Validate-MaestroVars + + $SourceRepository = [System.Web.HttpUtility]::UrlEncode($SourceRepository) + $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken + $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions?sourceRepository=$SourceRepository&channelId=$ChannelId&api-version=$MaestroApiVersion" + + $result = try { Invoke-WebRequest -Method Get -Uri $apiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + return $result +} + +function Trigger-Subscription([string]$SubscriptionId) { + Validate-MaestroVars + + $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken + $apiEndpoint = "$MaestroApiEndPoint/api/subscriptions/$SubscriptionId/trigger?api-version=$MaestroApiVersion" + Invoke-WebRequest -Uri $apiEndpoint -Headers $apiHeaders -Method Post | Out-Null +} + +function Assign-BuildToChannel([int]$BuildId, [int]$ChannelId) { + Validate-MaestroVars + + $apiHeaders = Create-MaestroApiRequestHeaders -AuthToken $MaestroApiAccessToken + $apiEndpoint = "$MaestroApiEndPoint/api/channels/${ChannelId}/builds/${BuildId}?api-version=$MaestroApiVersion" + Invoke-WebRequest -Method Post -Uri $apiEndpoint -Headers $apiHeaders | Out-Null +} + +function Validate-MaestroVars { + try { + Get-Variable MaestroApiEndPoint -Scope Global | Out-Null + Get-Variable MaestroApiVersion -Scope Global | Out-Null + Get-Variable MaestroApiAccessToken -Scope Global | Out-Null + + if (!($MaestroApiEndPoint -Match "^http[s]?://maestro-(int|prod).westus2.cloudapp.azure.com$")) { + Write-PipelineTaskError "MaestroApiEndPoint is not a valid Maestro URL. '$MaestroApiEndPoint'" + ExitWithExitCode 1 + } + + if (!($MaestroApiVersion -Match "^[0-9]{4}-[0-9]{2}-[0-9]{2}$")) { + Write-PipelineTaskError "MaestroApiVersion does not match a version string in the format yyyy-MM-DD. '$MaestroApiVersion'" + ExitWithExitCode 1 + } + } + catch { + Write-PipelineTaskError "Error: Variables `MaestroApiEndPoint`, `MaestroApiVersion` and `MaestroApiAccessToken` are required while using this script." + Write-Host $_ + ExitWithExitCode 1 + } +} diff --git a/eng/common/post-build/promote-build.ps1 b/eng/common/post-build/promote-build.ps1 new file mode 100644 index 00000000000..e5ae85f2517 --- /dev/null +++ b/eng/common/post-build/promote-build.ps1 @@ -0,0 +1,48 @@ +param( + [Parameter(Mandatory=$true)][int] $BuildId, + [Parameter(Mandatory=$true)][int] $ChannelId, + [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = "https://maestro-prod.westus2.cloudapp.azure.com", + [Parameter(Mandatory=$false)][string] $MaestroApiVersion = "2019-01-16" +) + +. $PSScriptRoot\post-build-utils.ps1 + +try { + # Check that the channel we are going to promote the build to exist + $channelInfo = Get-MaestroChannel -ChannelId $ChannelId + + if (!$channelInfo) { + Write-Host "Channel with BAR ID $ChannelId was not found in BAR!" + ExitWithExitCode 1 + } + + # Get info about which channels the build has already been promoted to + $buildInfo = Get-MaestroBuild -BuildId $BuildId + + if (!$buildInfo) { + Write-Host "Build with BAR ID $BuildId was not found in BAR!" + ExitWithExitCode 1 + } + + # Find whether the build is already assigned to the channel or not + if ($buildInfo.channels) { + foreach ($channel in $buildInfo.channels) { + if ($channel.Id -eq $ChannelId) { + Write-Host "The build with BAR ID $BuildId is already on channel $ChannelId!" + ExitWithExitCode 0 + } + } + } + + Write-Host "Promoting build '$BuildId' to channel '$ChannelId'." + + Assign-BuildToChannel -BuildId $BuildId -ChannelId $ChannelId + + Write-Host "done." +} +catch { + Write-Host "There was an error while trying to promote build '$BuildId' to channel '$ChannelId'" + Write-Host $_ + Write-Host $_.ScriptStackTrace +} diff --git a/eng/common/post-build/setup-maestro-vars.ps1 b/eng/common/post-build/setup-maestro-vars.ps1 new file mode 100644 index 00000000000..d7f64dc63cb --- /dev/null +++ b/eng/common/post-build/setup-maestro-vars.ps1 @@ -0,0 +1,26 @@ +param( + [Parameter(Mandatory=$true)][string] $ReleaseConfigsPath # Full path to ReleaseConfigs.txt asset +) + +. $PSScriptRoot\post-build-utils.ps1 + +try { + $Content = Get-Content $ReleaseConfigsPath + + $BarId = $Content | Select -Index 0 + + $Channels = "" + $Content | Select -Index 1 | ForEach-Object { $Channels += "$_ ," } + + $IsStableBuild = $Content | Select -Index 2 + + Write-PipelineSetVariable -Name 'BARBuildId' -Value $BarId + Write-PipelineSetVariable -Name 'InitialChannels' -Value "$Channels" + Write-PipelineSetVariable -Name 'IsStableBuild' -Value $IsStableBuild +} +catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + ExitWithExitCode 1 +} diff --git a/eng/common/post-build/sourcelink-validation.ps1 b/eng/common/post-build/sourcelink-validation.ps1 index 8abd684e9e5..41e01ae6e67 100644 --- a/eng/common/post-build/sourcelink-validation.ps1 +++ b/eng/common/post-build/sourcelink-validation.ps1 @@ -6,10 +6,7 @@ param( [Parameter(Mandatory=$true)][string] $SourcelinkCliVersion # Version of SourceLink CLI to use ) -$ErrorActionPreference = "Stop" -Set-StrictMode -Version 2.0 - -. $PSScriptRoot\..\tools.ps1 +. $PSScriptRoot\post-build-utils.ps1 # Cache/HashMap (File -> Exist flag) used to consult whether a file exist # in the repository at a specific commit point. This is populated by inserting @@ -200,21 +197,27 @@ function ValidateSourceLinkLinks { } } -function CheckExitCode ([string]$stage) { - $exitCode = $LASTEXITCODE - if ($exitCode -ne 0) { - Write-PipelineTaskError "Something failed while '$stage'. Check for errors above. Exiting now..." - ExitWithExitCode $exitCode +function InstallSourcelinkCli { + $sourcelinkCliPackageName = "sourcelink" + + $dotnetRoot = InitializeDotNetCli -install:$true + $dotnet = "$dotnetRoot\dotnet.exe" + $toolList = & "$dotnet" tool list --global + + if (($toolList -like "*$sourcelinkCliPackageName*") -and ($toolList -like "*$sourcelinkCliVersion*")) { + Write-Host "SourceLink CLI version $sourcelinkCliVersion is already installed." + } + else { + Write-Host "Installing SourceLink CLI version $sourcelinkCliVersion..." + Write-Host "You may need to restart your command window if this is the first dotnet tool you have installed." + & "$dotnet" tool install $sourcelinkCliPackageName --version $sourcelinkCliVersion --verbosity "minimal" --global } } try { - Write-Host "Installing SourceLink CLI..." - Get-Location - . $PSScriptRoot\sourcelink-cli-init.ps1 -sourcelinkCliVersion $SourcelinkCliVersion - CheckExitCode "Running sourcelink-cli-init" + InstallSourcelinkCli - Measure-Command { ValidateSourceLinkLinks } + ValidateSourceLinkLinks } catch { Write-Host $_ diff --git a/eng/common/post-build/symbols-validation.ps1 b/eng/common/post-build/symbols-validation.ps1 index 69456854e04..d5ec51b150f 100644 --- a/eng/common/post-build/symbols-validation.ps1 +++ b/eng/common/post-build/symbols-validation.ps1 @@ -4,10 +4,7 @@ param( [Parameter(Mandatory=$true)][string] $DotnetSymbolVersion # Version of dotnet symbol to use ) -$ErrorActionPreference = "Stop" -Set-StrictMode -Version 2.0 - -. $PSScriptRoot\..\tools.ps1 +. $PSScriptRoot\post-build-utils.ps1 Add-Type -AssemblyName System.IO.Compression.FileSystem @@ -162,19 +159,25 @@ function CheckSymbolsAvailable { } } -function CheckExitCode ([string]$stage) { - $exitCode = $LASTEXITCODE - if ($exitCode -ne 0) { - Write-PipelineTaskError "Something failed while '$stage'. Check for errors above. Exiting now..." - ExitWithExitCode $exitCode +function Installdotnetsymbol { + $dotnetsymbolPackageName = "dotnet-symbol" + + $dotnetRoot = InitializeDotNetCli -install:$true + $dotnet = "$dotnetRoot\dotnet.exe" + $toolList = & "$dotnet" tool list --global + + if (($toolList -like "*$dotnetsymbolPackageName*") -and ($toolList -like "*$dotnetsymbolVersion*")) { + Write-Host "dotnet-symbol version $dotnetsymbolVersion is already installed." + } + else { + Write-Host "Installing dotnet-symbol version $dotnetsymbolVersion..." + Write-Host "You may need to restart your command window if this is the first dotnet tool you have installed." + & "$dotnet" tool install $dotnetsymbolPackageName --version $dotnetsymbolVersion --verbosity "minimal" --global } } try { - Write-Host "Installing dotnet symbol ..." - Get-Location - . $PSScriptRoot\dotnetsymbol-init.ps1 -dotnetsymbolVersion $DotnetSymbolVersion - CheckExitCode "Running dotnetsymbol-init" + Installdotnetsymbol CheckSymbolsAvailable } diff --git a/eng/common/post-build/trigger-subscriptions.ps1 b/eng/common/post-build/trigger-subscriptions.ps1 new file mode 100644 index 00000000000..926d5b45513 --- /dev/null +++ b/eng/common/post-build/trigger-subscriptions.ps1 @@ -0,0 +1,57 @@ +param( + [Parameter(Mandatory=$true)][string] $SourceRepo, + [Parameter(Mandatory=$true)][int] $ChannelId, + [Parameter(Mandatory=$true)][string] $MaestroApiAccessToken, + [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = "https://maestro-prod.westus2.cloudapp.azure.com", + [Parameter(Mandatory=$false)][string] $MaestroApiVersion = "2019-01-16" +) + +. $PSScriptRoot\post-build-utils.ps1 + +# Get all the $SourceRepo subscriptions +$normalizedSourceRepo = $SourceRepo.Replace('dnceng@', '') +$subscriptions = Get-MaestroSubscriptions -SourceRepository $normalizedSourceRepo -ChannelId $ChannelId + +if (!$subscriptions) { + Write-Host "No subscriptions found for source repo '$normalizedSourceRepo' in channel '$ChannelId'" + ExitWithExitCode 0 +} + +$subscriptionsToTrigger = New-Object System.Collections.Generic.List[string] +$failedTriggeredSubscription = $false + +# Get all enabled subscriptions that need dependency flow on 'everyBuild' +foreach ($subscription in $subscriptions) { + if ($subscription.enabled -and $subscription.policy.updateFrequency -like 'everyBuild' -and $subscription.channel.id -eq $ChannelId) { + Write-Host "Should trigger this subscription: $subscription.id" + [void]$subscriptionsToTrigger.Add($subscription.id) + } +} + +foreach ($subscriptionToTrigger in $subscriptionsToTrigger) { + try { + Write-Host "Triggering subscription '$subscriptionToTrigger'." + + Trigger-Subscription -SubscriptionId $subscriptionToTrigger + + Write-Host "done." + } + catch + { + Write-Host "There was an error while triggering subscription '$subscriptionToTrigger'" + Write-Host $_ + Write-Host $_.ScriptStackTrace + $failedTriggeredSubscription = $true + } +} + +if ($subscriptionsToTrigger.Count -eq 0) { + Write-Host "No subscription matched source repo '$normalizedSourceRepo' and channel ID '$ChannelId'." +} +elseif ($failedTriggeredSubscription) { + Write-Host "At least one subscription failed to be triggered..." + ExitWithExitCode 1 +} +else { + Write-Host "All subscriptions were triggered successfully!" +} diff --git a/eng/common/sdl/execute-all-sdl-tools.ps1 b/eng/common/sdl/execute-all-sdl-tools.ps1 index 0635f26fb63..aab7589f2cc 100644 --- a/eng/common/sdl/execute-all-sdl-tools.ps1 +++ b/eng/common/sdl/execute-all-sdl-tools.ps1 @@ -22,7 +22,9 @@ Param( [string] $TsaCodebaseAdmin, # Optional: only needed if TsaOnboard is true; the aliases which are admins of the TSA codebase (e.g. DOMAIN\alias); TSA is the automated framework used to upload test results as bugs. [string] $TsaBugAreaPath, # Optional: only needed if TsaOnboard is true; the area path where TSA will file bugs in AzDO; TSA is the automated framework used to upload test results as bugs. [string] $TsaIterationPath, # Optional: only needed if TsaOnboard is true; the iteration path where TSA will file bugs in AzDO; TSA is the automated framework used to upload test results as bugs. - [string] $GuardianLoggerLevel="Standard" # Optional: the logger level for the Guardian CLI; options are Trace, Verbose, Standard, Warning, and Error + [string] $GuardianLoggerLevel="Standard", # Optional: the logger level for the Guardian CLI; options are Trace, Verbose, Standard, Warning, and Error + [string[]] $CrScanAdditionalRunConfigParams, # Optional: Additional Params to custom build a CredScan run config in the format @("xyz:abc","sdf:1") + [string[]] $PoliCheckAdditionalRunConfigParams # Optional: Additional Params to custom build a Policheck run config in the format @("xyz:abc","sdf:1") ) $ErrorActionPreference = "Stop" @@ -69,10 +71,10 @@ if ($TsaOnboard) { } if ($ArtifactToolsList -and $ArtifactToolsList.Count -gt 0) { - & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $ArtifactsDirectory -TargetDirectory $ArtifactsDirectory -GdnFolder $gdnFolder -ToolsList $ArtifactToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel + & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $ArtifactsDirectory -TargetDirectory $ArtifactsDirectory -GdnFolder $gdnFolder -ToolsList $ArtifactToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams } if ($SourceToolsList -and $SourceToolsList.Count -gt 0) { - & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $ArtifactsDirectory -TargetDirectory $SourceDirectory -GdnFolder $gdnFolder -ToolsList $SourceToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel + & $(Join-Path $PSScriptRoot "run-sdl.ps1") -GuardianCliLocation $guardianCliLocation -WorkingDirectory $ArtifactsDirectory -TargetDirectory $SourceDirectory -GdnFolder $gdnFolder -ToolsList $SourceToolsList -AzureDevOpsAccessToken $AzureDevOpsAccessToken -UpdateBaseline $UpdateBaseline -GuardianLoggerLevel $GuardianLoggerLevel -CrScanAdditionalRunConfigParams $CrScanAdditionalRunConfigParams -PoliCheckAdditionalRunConfigParams $PoliCheckAdditionalRunConfigParams } if ($UpdateBaseline) { diff --git a/eng/common/sdl/extract-artifact-packages.ps1 b/eng/common/sdl/extract-artifact-packages.ps1 index 0f6a6e49b92..1fdbb14329c 100644 --- a/eng/common/sdl/extract-artifact-packages.ps1 +++ b/eng/common/sdl/extract-artifact-packages.ps1 @@ -44,6 +44,10 @@ $ExtractPackage = { } } function ExtractArtifacts { + if (!(Test-Path $InputPath)) { + Write-Host "Input Path does not exist: $InputPath" + ExitWithExitCode 0 + } $Jobs = @() Get-ChildItem "$InputPath\*.nupkg" | ForEach-Object { diff --git a/eng/common/sdl/run-sdl.ps1 b/eng/common/sdl/run-sdl.ps1 index e6a86d03a21..d7b85644581 100644 --- a/eng/common/sdl/run-sdl.ps1 +++ b/eng/common/sdl/run-sdl.ps1 @@ -5,7 +5,9 @@ Param( [string] $GdnFolder, [string[]] $ToolsList, [string] $UpdateBaseline, - [string] $GuardianLoggerLevel="Standard" + [string] $GuardianLoggerLevel="Standard", + [string[]] $CrScanAdditionalRunConfigParams, + [string[]] $PoliCheckAdditionalRunConfigParams ) $ErrorActionPreference = "Stop" @@ -29,8 +31,8 @@ foreach ($tool in $ToolsList) { Write-Host $tool # We have to manually configure tools that run on source to look at the source directory only if ($tool -eq "credscan") { - Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" TargetDirectory : $TargetDirectory `"" - & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " TargetDirectory : $TargetDirectory " + Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" TargetDirectory : $TargetDirectory `" $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams})" + & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " TargetDirectory : $TargetDirectory " $(If ($CrScanAdditionalRunConfigParams) {$CrScanAdditionalRunConfigParams}) if ($LASTEXITCODE -ne 0) { Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE." exit $LASTEXITCODE @@ -38,8 +40,8 @@ foreach ($tool in $ToolsList) { $config = $True } if ($tool -eq "policheck") { - Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" Target : $TargetDirectory `"" - & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " Target : $TargetDirectory " + Write-Host "$GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args `" Target : $TargetDirectory `" $(If ($PoliCheckAdditionalRunConfigParams) {$PoliCheckAdditionalRunConfigParams})" + & $GuardianCliLocation configure --working-directory $WorkingDirectory --tool $tool --output-path $gdnConfigFile --logger-level $GuardianLoggerLevel --noninteractive --force --args " Target : $TargetDirectory " $(If ($PoliCheckAdditionalRunConfigParams) {$PoliCheckAdditionalRunConfigParams}) if ($LASTEXITCODE -ne 0) { Write-Host "Guardian configure for $tool failed with exit code $LASTEXITCODE." exit $LASTEXITCODE diff --git a/eng/common/templates/job/performance.yml b/eng/common/templates/job/performance.yml new file mode 100644 index 00000000000..ef809253d1a --- /dev/null +++ b/eng/common/templates/job/performance.yml @@ -0,0 +1,93 @@ +parameters: + steps: [] # optional -- any additional steps that need to happen before pulling down the performance repo and sending the performance benchmarks to helix (ie building your repo) + variables: [] # optional -- list of additional variables to send to the template + jobName: '' # required -- job name + displayName: '' # optional -- display name for the job. Will use jobName if not passed + pool: '' # required -- name of the Build pool + container: '' # required -- name of the container + extraSetupParameters: '' # optional -- extra arguments to pass to the setup script + frameworks: ['netcoreapp3.0'] # optional -- list of frameworks to run against + continueOnError: 'false' # optional -- determines whether to continue the build if the step errors + dependsOn: '' # optional -- dependencies of the job + timeoutInMinutes: 320 # optional -- timeout for the job + enableTelemetry: false # optional -- enable for telemetry + +jobs: +- template: ../jobs/jobs.yml + parameters: + dependsOn: ${{ parameters.dependsOn }} + enableTelemetry: ${{ parameters.enableTelemetry }} + enablePublishBuildArtifacts: true + continueOnError: ${{ parameters.continueOnError }} + + jobs: + - job: '${{ parameters.jobName }}' + + ${{ if ne(parameters.displayName, '') }}: + displayName: '${{ parameters.displayName }}' + ${{ if eq(parameters.displayName, '') }}: + displayName: '${{ parameters.jobName }}' + + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + + variables: + + - ${{ each variable in parameters.variables }}: + - ${{ if ne(variable.name, '') }}: + - name: ${{ variable.name }} + value: ${{ variable.value }} + - ${{ if ne(variable.group, '') }}: + - group: ${{ variable.group }} + + - IsInternal: '' + - HelixApiAccessToken: '' + - HelixPreCommand: '' + + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if eq(variables['Agent.Os'], 'Windows_NT') }}: + - HelixPreCommand: 'set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"' + - IsInternal: -Internal + - ${{ if ne(variables['Agent.Os'], 'Windows_NT') }}: + - HelixPreCommand: 'export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' + - IsInternal: --internal + - group: DotNet-HelixApi-Access + - group: dotnet-benchview + + workspace: + clean: all + pool: + ${{ parameters.pool }} + container: ${{ parameters.container }} + strategy: + matrix: + ${{ each framework in parameters.frameworks }}: + ${{ framework }}: + _Framework: ${{ framework }} + steps: + - checkout: self + clean: true + # Run all of the steps to setup repo + - ${{ each step in parameters.steps }}: + - ${{ step }} + - powershell: $(Build.SourcesDirectory)\eng\common\performance\performance-setup.ps1 $(IsInternal) -Framework $(_Framework) ${{ parameters.extraSetupParameters }} + displayName: Performance Setup (Windows) + condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + - script: $(Build.SourcesDirectory)/eng/common/performance/performance-setup.sh $(IsInternal) --framework $(_Framework) ${{ parameters.extraSetupParameters }} + displayName: Performance Setup (Unix) + condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + - script: $(Python) $(PerformanceDirectory)/scripts/ci_setup.py $(SetupArguments) + displayName: Run ci setup script + # Run perf testing in helix + - template: /eng/common/templates/steps/perf-send-to-helix.yml + parameters: + HelixSource: '$(HelixSourcePrefix)/$(Build.Repository.Name)/$(Build.SourceBranch)' # sources must start with pr/, official/, prodcon/, or agent/ + HelixType: 'test/performance/$(Kind)/$(_Framework)/$(Architecture)' + HelixAccessToken: $(HelixApiAccessToken) + HelixTargetQueues: $(Queue) + HelixPreCommands: $(HelixPreCommand) + Creator: $(Creator) + WorkItemTimeout: 4:00 # 4 hours + WorkItemDirectory: '$(WorkItemDirectory)' # WorkItemDirectory can not be empty, so we send it some docs to keep it happy + CorrelationPayloadDirectory: '$(PayloadDirectory)' # it gets checked out to a folder with shorter path than WorkItemDirectory so we can avoid file name too long exceptions \ No newline at end of file diff --git a/eng/common/templates/post-build/channels/internal-servicing.yml b/eng/common/templates/post-build/channels/internal-servicing.yml index 99cd59b1980..12fd2b4653d 100644 --- a/eng/common/templates/post-build/channels/internal-servicing.yml +++ b/eng/common/templates/post-build/channels/internal-servicing.yml @@ -36,12 +36,11 @@ stages: /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' /p:Configuration=Release - - job: + - job: publish_assets displayName: Publish Assets dependsOn: setupMaestroVars variables: - group: DotNet-Blob-Feed - - group: Publish-Build-Assets - group: AzureDevOps-Artifact-Feeds-Pats - name: BARBuildId value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] @@ -81,13 +80,14 @@ stages: /p:IsInternalBuild=$(IsInternalBuild) /p:RepositoryName=$(Build.Repository.Name) /p:CommitSha=$(Build.SourceVersion) + /p:AzureStorageAccountName=$(ProxyBackedFeedsAccountName) + /p:AzureStorageAccountKey=$(dotnetfeed-storage-access-key-1) + /p:AzureDevOpsFeedsBaseUrl=$(dotnetfeed-internal-private-feed-url) + /p:StaticInternalFeed=$(dotnetfeed-internal-nonstable-feed-url) /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe - /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' - /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' - /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' /p:BARBuildId=$(BARBuildId) - /p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com' - /p:BuildAssetRegistryToken='$(MaestroAccessToken)' + /p:MaestroApiEndpoint='$(MaestroApiEndPoint)' + /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)' /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' /p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts' /p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts' @@ -111,7 +111,10 @@ stages: -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw) enabled: false - + - template: ../trigger-subscription.yml + parameters: + ChannelId: ${{ variables.InternalServicing_30_Channel_Id }} + - stage: IS_PublishValidation displayName: Publish Validation variables: @@ -139,29 +142,6 @@ stages: filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1 arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion) - - job: - displayName: Gather Drop - dependsOn: setupMaestroVars - variables: - BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.InternalServicing_30_Channel_Id) - pool: - vmImage: 'windows-2019' - steps: - - task: PowerShell@2 - displayName: Setup Darc CLI - inputs: - targetType: filePath - filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1' - - - task: PowerShell@2 - displayName: Run Darc gather-drop - inputs: - targetType: inline - script: | - darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location - enabled: false - - template: ../promote-build.yml parameters: ChannelId: ${{ variables.InternalServicing_30_Channel_Id }} diff --git a/eng/common/templates/post-build/channels/public-dev-release.yml b/eng/common/templates/post-build/channels/public-dev-release.yml index dfbc246826b..b0f085b1420 100644 --- a/eng/common/templates/post-build/channels/public-dev-release.yml +++ b/eng/common/templates/post-build/channels/public-dev-release.yml @@ -41,7 +41,6 @@ stages: dependsOn: setupMaestroVars variables: - group: DotNet-Blob-Feed - - group: Publish-Build-Assets - group: AzureDevOps-Artifact-Feeds-Pats - name: BARBuildId value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] @@ -77,6 +76,7 @@ stages: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet /p:ChannelId=$(PublicDevRelease_30_Channel_Id) + /p:ArtifactsCategory=$(_DotNetArtifactsCategory) /p:IsStableBuild=$(IsStableBuild) /p:IsInternalBuild=$(IsInternalBuild) /p:RepositoryName=$(Build.Repository.Name) @@ -86,8 +86,8 @@ stages: /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' /p:BARBuildId=$(BARBuildId) - /p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com' - /p:BuildAssetRegistryToken='$(MaestroAccessToken)' + /p:MaestroApiEndpoint='$(MaestroApiEndPoint)' + /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)' /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/' @@ -139,24 +139,10 @@ stages: filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1 arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion) - - job: - displayName: Gather Drop - dependsOn: setupMaestroVars - variables: - BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicDevRelease_30_Channel_Id) - pool: - vmImage: 'windows-2019' - steps: - - task: PowerShell@2 - displayName: Setup Darc CLI - inputs: - targetType: filePath - filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1' + - template: ../darc-gather-drop.yml + parameters: + ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }} - - task: PowerShell@2 - displayName: Run Darc gather-drop - inputs: - targetType: inline - script: | - darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location + - template: ../promote-build.yml + parameters: + ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }} diff --git a/eng/common/templates/post-build/channels/public-release.yml b/eng/common/templates/post-build/channels/public-release.yml index f23eb3f541a..4c63fb43f0c 100644 --- a/eng/common/templates/post-build/channels/public-release.yml +++ b/eng/common/templates/post-build/channels/public-release.yml @@ -36,12 +36,11 @@ stages: /p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/' /p:Configuration=Release - - job: + - job: publish_assets displayName: Publish Assets dependsOn: setupMaestroVars variables: - group: DotNet-Blob-Feed - - group: Publish-Build-Assets - group: AzureDevOps-Artifact-Feeds-Pats - name: BARBuildId value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] @@ -81,13 +80,14 @@ stages: /p:IsInternalBuild=$(IsInternalBuild) /p:RepositoryName=$(Build.Repository.Name) /p:CommitSha=$(Build.SourceVersion) - /p:NugetPath=$(Agent.BuildDirectory)/Nuget/NuGet.exe - /p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' - /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' - /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' + /p:AzureStorageAccountName=$(ProxyBackedFeedsAccountName) + /p:AzureStorageAccountKey=$(dotnetfeed-storage-access-key-1) + /p:AzureDevOpsFeedsBaseUrl=$(dotnetfeed-internal-private-feed-url) + /p:StaticInternalFeed=$(dotnetfeed-internal-nonstable-feed-url) + /p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe /p:BARBuildId=$(BARBuildId) - /p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com' - /p:BuildAssetRegistryToken='$(MaestroAccessToken)' + /p:MaestroApiEndpoint='$(MaestroApiEndPoint)' + /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)' /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' /p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts' /p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts' @@ -111,6 +111,9 @@ stages: -PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw) enabled: false + - template: ../trigger-subscription.yml + parameters: + ChannelId: ${{ variables.PublicRelease_30_Channel_Id }} - stage: PubRel_PublishValidation displayName: Publish Validation @@ -139,29 +142,6 @@ stages: filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1 arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion) - - job: - displayName: Gather Drop - dependsOn: setupMaestroVars - variables: - BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicRelease_30_Channel_Id) - pool: - vmImage: 'windows-2019' - steps: - - task: PowerShell@2 - displayName: Setup Darc CLI - inputs: - targetType: filePath - filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1' - - - task: PowerShell@2 - displayName: Run Darc gather-drop - inputs: - targetType: inline - script: | - darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location - enabled: false - - template: ../promote-build.yml parameters: ChannelId: ${{ variables.PublicRelease_30_Channel_Id }} diff --git a/eng/common/templates/post-build/channels/public-validation-release.yml b/eng/common/templates/post-build/channels/public-validation-release.yml index 0ef68c2b01b..1089ac5fa6b 100644 --- a/eng/common/templates/post-build/channels/public-validation-release.yml +++ b/eng/common/templates/post-build/channels/public-validation-release.yml @@ -12,7 +12,6 @@ stages: dependsOn: setupMaestroVars variables: - group: DotNet-Blob-Feed - - group: Publish-Build-Assets - group: AzureDevOps-Artifact-Feeds-Pats - name: BARBuildId value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] @@ -48,6 +47,7 @@ stages: filePath: eng\common\sdk-task.ps1 arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet /p:ChannelId=$(PublicValidationRelease_30_Channel_Id) + /p:ArtifactsCategory=$(_DotNetValidationArtifactsCategory) /p:IsStableBuild=$(IsStableBuild) /p:IsInternalBuild=$(IsInternalBuild) /p:RepositoryName=$(Build.Repository.Name) @@ -57,13 +57,13 @@ stages: /p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)' /p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)' /p:BARBuildId=$(BARBuildId) - /p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com' - /p:BuildAssetRegistryToken='$(MaestroAccessToken)' + /p:MaestroApiEndpoint='$(MaestroApiEndPoint)' + /p:BuildAssetRegistryToken='$(MaestroApiAccessToken)' /p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/' /p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts' /p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts' /p:Configuration=Release - + - task: NuGetCommand@2 displayName: Publish Packages to AzDO Feed condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com') @@ -90,26 +90,10 @@ stages: jobs: - template: ../setup-maestro-vars.yml - - job: - displayName: Gather Drop - dependsOn: setupMaestroVars - condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicValidationRelease_30_Channel_Id) - variables: - - name: BARBuildId - value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - - group: Publish-Build-Assets - pool: - vmImage: 'windows-2019' - steps: - - task: PowerShell@2 - displayName: Setup Darc CLI - inputs: - targetType: filePath - filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1' + - template: ../darc-gather-drop.yml + parameters: + ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }} - - task: PowerShell@2 - displayName: Run Darc gather-drop - inputs: - targetType: inline - script: | - darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com --password $(MaestroAccessToken) --latest-location + - template: ../promote-build.yml + parameters: + ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }} diff --git a/eng/common/templates/post-build/common-variables.yml b/eng/common/templates/post-build/common-variables.yml index 82834673520..bd0bc5e4daa 100644 --- a/eng/common/templates/post-build/common-variables.yml +++ b/eng/common/templates/post-build/common-variables.yml @@ -1,18 +1,39 @@ variables: + - group: Publish-Build-Assets + # .NET Core 3 Dev - PublicDevRelease_30_Channel_Id: 3 + - name: PublicDevRelease_30_Channel_Id + value: 3 # .NET Tools - Validation - PublicValidationRelease_30_Channel_Id: 9 + - name: PublicValidationRelease_30_Channel_Id + value: 9 # .NET Core 3.0 Internal Servicing - InternalServicing_30_Channel_Id: 184 + - name: InternalServicing_30_Channel_Id + value: 184 # .NET Core 3.0 Release - PublicRelease_30_Channel_Id: 19 + - name: PublicRelease_30_Channel_Id + value: 19 # Whether the build is internal or not - IsInternalBuild: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} + - name: IsInternalBuild + value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} + + # Storage account name for proxy-backed feeds + - name: ProxyBackedFeedsAccountName + value: dotnetfeed + + # Default Maestro++ API Endpoint and API Version + - name: MaestroApiEndPoint + value: "https://maestro-prod.westus2.cloudapp.azure.com" + - name: MaestroApiAccessToken + value: $(MaestroAccessToken) + - name: MaestroApiVersion + value: "2019-01-16" - SourceLinkCLIVersion: 3.0.0 - SymbolToolVersion: 1.0.1 + - name: SourceLinkCLIVersion + value: 3.0.0 + - name: SymbolToolVersion + value: 1.0.1 diff --git a/eng/common/templates/post-build/darc-gather-drop.yml b/eng/common/templates/post-build/darc-gather-drop.yml new file mode 100644 index 00000000000..f4e3bfcf5cd --- /dev/null +++ b/eng/common/templates/post-build/darc-gather-drop.yml @@ -0,0 +1,23 @@ +parameters: + ChannelId: 0 + +jobs: +- job: gatherDrop + displayName: Gather Drop + dependsOn: setupMaestroVars + condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], ${{ parameters.ChannelId }}) + variables: + - name: BARBuildId + value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] + pool: + vmImage: 'windows-2019' + steps: + - task: PowerShell@2 + displayName: Darc gather-drop + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/darc-gather-drop.ps1 + arguments: -BarBuildId $(BARBuildId) + -DropLocation $(Agent.BuildDirectory)/Temp/Drop/ + -MaestroApiAccessToken $(MaestroApiAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index 3d7e6776e62..0872db4ed94 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -2,15 +2,38 @@ parameters: enableSourceLinkValidation: true enableSigningValidation: true enableSymbolValidation: true + enableNugetValidation: true SDLValidationParameters: enable: false params: '' + # Which stages should finish execution before post-build stages start + dependsOn: [build] + stages: - stage: validate - dependsOn: build + dependsOn: ${{ parameters.dependsOn }} displayName: Validate jobs: + - ${{ if eq(parameters.enableNugetValidation, 'true') }}: + - job: + displayName: NuGet Validation + pool: + vmImage: 'windows-2019' + steps: + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: current + artifactName: PackageArtifacts + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ + -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ + - ${{ if eq(parameters.enableSigningValidation, 'true') }}: - job: displayName: Signing Validation diff --git a/eng/common/templates/post-build/promote-build.yml b/eng/common/templates/post-build/promote-build.yml index 57241bab88f..9387c583b31 100644 --- a/eng/common/templates/post-build/promote-build.yml +++ b/eng/common/templates/post-build/promote-build.yml @@ -11,17 +11,15 @@ jobs: value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ] - name: ChannelId value: ${{ parameters.ChannelId }} - - group: Publish-Build-Assets pool: vmImage: 'windows-2019' steps: - task: PowerShell@2 displayName: Add Build to Channel inputs: - targetType: inline - script: | - $headers = @{ - "Accept" = "application/json" - "Authorization" = "Bearer $(MaestroAccessToken)" - } - Invoke-RestMethod -Method Post -Headers $headers -Uri https://maestro-prod.westus2.cloudapp.azure.com/api/channels/$(ChannelId)/builds/$(BARBuildId)?api-version=2019-01-16 + filePath: $(Build.SourcesDirectory)/eng/common/post-build/promote-build.ps1 + arguments: -BuildId $(BARBuildId) + -ChannelId $(ChannelId) + -MaestroApiAccessToken $(MaestroApiAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates/post-build/setup-maestro-vars.yml b/eng/common/templates/post-build/setup-maestro-vars.yml index f6120dc1e1c..56242b068e1 100644 --- a/eng/common/templates/post-build/setup-maestro-vars.yml +++ b/eng/common/templates/post-build/setup-maestro-vars.yml @@ -14,22 +14,5 @@ jobs: name: setReleaseVars displayName: Set Release Configs Vars inputs: - targetType: inline - script: | - # This is needed to make Write-PipelineSetVariable works in this context - $ci = $true - - . "$(Build.SourcesDirectory)/eng/common/tools.ps1" - - $Content = Get-Content "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt" - - $BarId = $Content | Select -Index 0 - - $Channels = "" - $Content | Select -Index 1 | ForEach-Object { $Channels += "$_ ," } - - $IsStableBuild = $Content | Select -Index 2 - - Write-PipelineSetVariable -Name 'BARBuildId' -Value $BarId - Write-PipelineSetVariable -Name 'InitialChannels' -Value "$Channels" - Write-PipelineSetVariable -Name 'IsStableBuild' -Value $IsStableBuild + filePath: $(Build.SourcesDirectory)/eng/common/post-build/setup-maestro-vars.ps1 + arguments: -ReleaseConfigsPath '$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt' diff --git a/eng/common/templates/post-build/trigger-subscription.yml b/eng/common/templates/post-build/trigger-subscription.yml new file mode 100644 index 00000000000..da669030daf --- /dev/null +++ b/eng/common/templates/post-build/trigger-subscription.yml @@ -0,0 +1,13 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Triggering subscriptions + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 + arguments: -SourceRepo $(Build.Repository.Uri) + -ChannelId ${{ parameters.ChannelId }} + -MaestroApiAccessToken $(MaestroAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates/steps/perf-send-to-helix.yml b/eng/common/templates/steps/perf-send-to-helix.yml new file mode 100644 index 00000000000..b3ea9acf1f1 --- /dev/null +++ b/eng/common/templates/steps/perf-send-to-helix.yml @@ -0,0 +1,66 @@ +# Please remember to update the documentation if you make changes to these parameters! +parameters: + HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ + HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' + HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number + HelixTargetQueues: '' # required -- semicolon delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues + HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group + HelixPreCommands: '' # optional -- commands to run before Helix work item execution + HelixPostCommands: '' # optional -- commands to run after Helix work item execution + WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects + CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload + IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion + DotNetCliPackageType: '' # optional -- either 'sdk' or 'runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json + DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json + EnableXUnitReporter: false # optional -- true enables XUnit result reporting to Mission Control + WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." + Creator: '' # optional -- if the build is external, use this to specify who is sending the job + DisplayNamePrefix: 'Send job to Helix' # optional -- rename the beginning of the displayName of the steps in AzDO + condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() + continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false + +steps: + - powershell: $(Build.SourcesDirectory)\eng\common\msbuild.ps1 $(Build.SourcesDirectory)\eng\common\performance\perfhelixpublish.proj /restore /t:Test /bl:$(Build.SourcesDirectory)\artifacts\log\$env:BuildConfig\SendToHelix.binlog + displayName: ${{ parameters.DisplayNamePrefix }} (Windows) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/performance/perfhelixpublish.proj /restore /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog + displayName: ${{ parameters.DisplayNamePrefix }} (Unix) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 60741f03901..8fe2b11ad21 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -84,7 +84,7 @@ function Exec-Process([string]$command, [string]$commandArgs) { return $global:LASTEXITCODE = $process.ExitCode } finally { - # If we didn't finish then an error occured or the user hit ctrl-c. Either + # If we didn't finish then an error occurred or the user hit ctrl-c. Either # way kill the process if (-not $finished) { $process.Kill() @@ -147,7 +147,7 @@ function InitializeDotNetCli([bool]$install) { # It also ensures that VS msbuild will use the downloaded sdk targets. $env:PATH = "$dotnetRoot;$env:PATH" - # Make Sure that our bootstrapped dotnet cli is avaliable in future steps of the Azure Pipelines build + # Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build Write-PipelinePrependPath -Path $dotnetRoot Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0' Write-PipelineSetVariable -Name 'DOTNET_SKIP_FIRST_TIME_EXPERIENCE' -Value '1' @@ -169,7 +169,7 @@ function InstallDotNetSdk([string] $dotnetRoot, [string] $version, [string] $arc InstallDotNet $dotnetRoot $version $architecture } -function InstallDotNet([string] $dotnetRoot, [string] $version, [string] $architecture = "", [string] $runtime = "", [bool] $skipNonVersionedFiles = $false) { $installScript = GetDotNetInstallScript $dotnetRoot +function InstallDotNet([string] $dotnetRoot, [string] $version, [string] $architecture = "", [string] $runtime = "", [bool] $skipNonVersionedFiles = $false) { $installScript = GetDotNetInstallScript $dotnetRoot $installParameters = @{ Version = $version diff --git a/eng/common/tools.sh b/eng/common/tools.sh old mode 100644 new mode 100755 index 70d92cf85aa..738bb5669da --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -77,7 +77,7 @@ function ReadGlobalVersion { local pattern="\"$key\" *: *\"(.*)\"" if [[ ! $line =~ $pattern ]]; then - Write-PipelineTelemetryError -category 'InitializeTools' "Error: Cannot find \"$key\" in $global_json_file" + Write-PipelineTelemetryError -category 'InitializeToolset' "Error: Cannot find \"$key\" in $global_json_file" ExitWithExitCode 1 fi @@ -146,14 +146,10 @@ function InitializeDotNetCli { # Add dotnet to PATH. This prevents any bare invocation of dotnet in custom # build steps from using anything other than what we've downloaded. - export PATH="$dotnet_root:$PATH" + Write-PipelinePrependPath -path "$dotnet_root" - if [[ $ci == true ]]; then - # Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build - echo "##vso[task.prependpath]$dotnet_root" - echo "##vso[task.setvariable variable=DOTNET_MULTILEVEL_LOOKUP]0" - echo "##vso[task.setvariable variable=DOTNET_SKIP_FIRST_TIME_EXPERIENCE]1" - fi + Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0" + Write-PipelineSetVariable -name "DOTNET_SKIP_FIRST_TIME_EXPERIENCE" -value "1" # return value _InitializeDotNetCli="$dotnet_root" @@ -249,7 +245,7 @@ function InitializeNativeTools() { then local nativeArgs="" if [[ "$ci" == true ]]; then - nativeArgs="-InstallDirectory $tools_dir" + nativeArgs="--installDirectory $tools_dir" fi "$_script_dir/init-tools-native.sh" $nativeArgs fi @@ -387,7 +383,8 @@ mkdir -p "$toolset_dir" mkdir -p "$temp_dir" mkdir -p "$log_dir" -if [[ $ci == true ]]; then - export TEMP="$temp_dir" - export TMP="$temp_dir" -fi +Write-PipelineSetVariable -name "Artifacts" -value "$artifacts_dir" +Write-PipelineSetVariable -name "Artifacts.Toolset" -value "$toolset_dir" +Write-PipelineSetVariable -name "Artifacts.Log" -value "$log_dir" +Write-PipelineSetVariable -name "Temp" -value "$temp_dir" +Write-PipelineSetVariable -name "TMP" -value "$temp_dir" diff --git a/eng/configure-toolset.ps1 b/eng/configure-toolset.ps1 index eae6468189c..bb0244b3841 100644 --- a/eng/configure-toolset.ps1 +++ b/eng/configure-toolset.ps1 @@ -26,4 +26,4 @@ if ($ci) { # Always generate binary logs $binaryLog = $true $DoNotAbortNativeToolsInstallationOnFailure = $true - +$DoNotDisplayNativeToolsInstallationWarnings =$true diff --git a/eng/pipeline.yml b/eng/pipeline.yml index f63502e41f0..ab7baa07b54 100644 --- a/eng/pipeline.yml +++ b/eng/pipeline.yml @@ -4,10 +4,6 @@ # parameters: - # Needed because agent pool can't be read from a user-defined variable (Azure DevOps limitation) - # Defaults to dotnet-internal-vs2019-preview - agentPool: dotnet-internal-vs2019-preview - # Needed because runAsPublic is used in template expressions, which can't read from user-defined variables # Defaults to true runAsPublic: true @@ -27,7 +23,15 @@ jobs: jobs: - job: Windows_NT timeoutInMinutes: 120 # how long to run the job before automatically cancelling; see https://github.com/dotnet/wpf/issues/952 - pool: ${{ parameters.agentPool }} + pool: + # For public or PR jobs, use the hosted pool. For internal jobs use the internal pool. + # Will eventually change this to two BYOC pools. + ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: + name: NetCorePublic-Pool + queue: BuildPool.Windows.10.Amd64.VS2019.Pre.Open + ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + name: NetCoreInternal-Pool + queue: BuildPool.Windows.10.Amd64.VS2019.Pre variables: # needed for signing - name: _TeamName @@ -50,6 +54,8 @@ jobs: value: x86 - name: _PlatformArgs value: /p:Platform=$(_Platform) + - name: _PublicBuildPipeline # We will run Helix tests when building in the open, but do not repeat when building and publishing again using the internal build-pipeline + value: true - name: _TestHelixAgentPool value: 'Windows.10.Amd64.ClientRS5.Open' # Preferred:'Windows.10.Amd64.Open%3bWindows.7.Amd64.Open%3bWindows.10.Amd64.ClientRS5.Open'; See https://github.com/dotnet/wpf/issues/952 - name: _HelixStagingDir @@ -60,8 +66,7 @@ jobs: value: '' - name: _HelixCreator value: ${{ parameters.repoName }} - - name: _HelixPublicBuildPipeline # Run Helix tests when building in the open, do not repeat when building and publishign again using the internal build-pipeline - value: true + # Override some values if we're building internally - ${{ if eq(parameters.runAsPublic, 'false') }}: @@ -93,6 +98,8 @@ jobs: /p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat) - name: _OfficialBuildIdArgs value: /p:OfficialBuildId=$(BUILD.BUILDNUMBER) + - name: _PublicBuildPipeline + value: false - name: _HelixSource value: official/${{ parameters.repoName }}/$(Build.SourceBranch) - name: _HelixToken @@ -101,8 +108,7 @@ jobs: value: '' #if _HelixToken is set, Creator must be empty - name: _TestHelixAgentPool value: 'Windows.10.Amd64.ClientRS5' # Preferred: 'Windows.10.Amd64%3bWindows.7.Amd64%3bWindows.10.Amd64.ClientRS5' - - name: _HelixPublicBuildPipeline - value: false + strategy: matrix: Build_Debug_x86: @@ -140,6 +146,12 @@ jobs: $(_OfficialBuildIdArgs) $(_PlatformArgs) displayName: Windows Build / Publish + # This condition should be kept in sync with the condition for 'Run DRTs' step + # When building on a regular pipeline (!_HelixPipeline), build as usual + # When building on a Helix pipeline, only build Release configs + # (!_HelixPipeline) || + # (_HelixPipeline && _PublicBuildPipeline && _ContinuousIntegrationTestsEnabled && _BuildConfig == Release) + condition: or(ne(variables['_HelixPipeline'], 'true'), and(eq(variables['_HelixPipeline'], 'true') ,eq(variables['_BuildConfig'], 'Release'), eq(variables['_PublicBuildPipeline'], 'true'), eq(variables['_ContinuousIntegrationTestsEnabled'], 'true'))) # Run DRTs - powershell: eng\common\cibuild.cmd @@ -157,4 +169,10 @@ jobs: HelixAccessToken: $(_HelixToken) # only defined for internal CI Creator: $(_HelixCreator) SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(succeeded(), eq(variables['_BuildConfig'], 'Release'), eq(variables['_HelixPublicBuildPipeline'], 'true')) # on helix machine (with real signing) when running on the public build pipeline + # This condition should be kept in sync with the condition for cibuild.cmd step with displayName: "Windows Build / Publish" + # Only run ... + # ...When building on a Helix pipeline, only build Release configs + # + # (_HelixPipeline && _PublicBuildPipeline && _ContinuousIntegrationTestsEnabled && _BuildConfig == Release) + # + condition: and(succeeded(), eq(variables['_HelixPipeline'], 'true') ,eq(variables['_BuildConfig'], 'Release'), eq(variables['_PublicBuildPipeline'], 'true'), eq(variables['_ContinuousIntegrationTestsEnabled'], 'true')) diff --git a/global.json b/global.json index f4dfe1d1a41..6ff6583ece5 100644 --- a/global.json +++ b/global.json @@ -12,13 +12,13 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19326.23", - "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19326.23" + "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19378.1", + "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19378.1" }, "native-tools": { "strawberry-perl": "5.28.1.1-1", "net-framework-48-ref-assemblies": "0.0.0.1", "dotnet-api-docs_netcoreapp3.0": "0.0.0.1", - "msvcurt-c1xx": "0.0.0.4" + "msvcurt-c1xx": "0.0.0.6" } } diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfApplication-CSharp/.template.config/template.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfApplication-CSharp/.template.config/template.json index 0a16e0681e6..7de4edc5be9 100644 --- a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfApplication-CSharp/.template.config/template.json +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfApplication-CSharp/.template.config/template.json @@ -59,6 +59,10 @@ { "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", "path": "MainWindow.xaml.cs" + }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "path": "MainWindow.xaml" } ], "defaultName": "WpfApp1", @@ -74,11 +78,11 @@ }, { "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", - "description": "Opens MainWindow.xaml.cs in the editor", + "description": "Opens MainWindow.xaml in the editor", "manualInstructions": [ ], "actionId": "84C0DA21-51C8-4541-9940-6CA19AF04EE6", "args": { - "files": "1" + "files": "1;2" }, "continueOnError": true } diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfApplication-VisualBasic/.template.config/template.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfApplication-VisualBasic/.template.config/template.json index 32591b70599..d0697fd107c 100644 --- a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfApplication-VisualBasic/.template.config/template.json +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfApplication-VisualBasic/.template.config/template.json @@ -59,6 +59,10 @@ { "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", "path": "MainWindow.xaml.vb" + }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "path": "MainWindow.xaml" } ], "defaultName": "WpfApp1", @@ -74,11 +78,11 @@ }, { "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", - "description": "Opens MainWindow.xaml.vb in the editor", + "description": "Opens MainWindow.xaml in the editor", "manualInstructions": [ ], "actionId": "84C0DA21-51C8-4541-9940-6CA19AF04EE6", "args": { - "files": "1" + "files": "1;2" }, "continueOnError": true } diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/.template.config/dotnetcli.host.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/.template.config/dotnetcli.host.json new file mode 100644 index 00000000000..22ab4a3929f --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/.template.config/dotnetcli.host.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json.schemastore.org/dotnetcli.host", + "symbolInfo": { + "TargetFrameworkOverride": { + "isHidden": "true", + "longName": "target-framework-override", + "shortName": "" + }, + "Framework": { + "longName": "framework" + }, + "skipRestore": { + "longName": "no-restore", + "shortName": "" + }, + "langVersion": { + "longName": "langVersion", + "shortName": "" + } + }, + "usageExamples": [ + "" + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/.template.config/template.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/.template.config/template.json new file mode 100644 index 00000000000..59493288a3e --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/.template.config/template.json @@ -0,0 +1,86 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "Microsoft", + "classifications": ["Common", "WPF"], + "name": "WPF Class library", + "generatorVersions": "[1.0.0.0-*)", + "description": "A project for creating a class library that targets a .NET Core WPF Application", + "groupIdentity": "Microsoft.Common.WPF.Library", + "precedence": "3000", + "identity": "Microsoft.Common.WPF.Library.CSharp.3.0", + "shortName": "wpflib", + "tags": { + "language": "C#", + "type": "project" + }, + "sourceName": "Company.ClassLibrary1", + "preferNameDirectory": true, + "symbols": { + "TargetFrameworkOverride": { + "type": "parameter", + "description": "Overrides the target framework", + "replaces": "TargetFrameworkOverride", + "datatype": "string", + "defaultValue": "" + }, + "Framework": { + "type": "parameter", + "description": "The target framework for the project.", + "datatype": "choice", + "choices": [ + { + "choice": "netcoreapp3.0", + "description": "Target netcoreapp3.0" + } + ], + "replaces": "netcoreapp3.0", + "defaultValue": "netcoreapp3.0" + }, + "langVersion": { + "type": "parameter", + "datatype": "text", + "description": "Sets langVersion in the created project file", + "defaultValue": "", + "replaces": "$(ProjectLanguageVersion)" + }, + "HostIdentifier": { + "type": "bind", + "binding": "HostIdentifier" + }, + "skipRestore": { + "type": "parameter", + "datatype": "bool", + "description": "If specified, skips the automatic restore of the project on create.", + "defaultValue": "false" + } + }, + "primaryOutputs": [ + { "path": "Company.ClassLibrary1.csproj" }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "path": "Class1.cs" + } + ], + "defaultName": "WpfLibrary1", + "postActions": [ + { + "condition": "(!skipRestore)", + "description": "Restore NuGet packages required by this project.", + "manualInstructions": [ + { "text": "Run 'dotnet restore'" } + ], + "actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025", + "continueOnError": true + }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "description": "Opens Class1.cs in the editor", + "manualInstructions": [ ], + "actionId": "84C0DA21-51C8-4541-9940-6CA19AF04EE6", + "args": { + "files": "1" + }, + "continueOnError": true + } + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/Class1.cs b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/Class1.cs new file mode 100644 index 00000000000..d9f25017aee --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/Class1.cs @@ -0,0 +1,8 @@ +using System; + +namespace Company.ClassLibrary1 +{ + public class Class1 + { + } +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/Company.ClassLibrary1.csproj b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/Company.ClassLibrary1.csproj new file mode 100644 index 00000000000..65ea6278ce5 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-CSharp/Company.ClassLibrary1.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp3.0 + TargetFrameworkOverride + Company.ClassLibrary1 + $(ProjectLanguageVersion) + true + + + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/.template.config/dotnetcli.host.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/.template.config/dotnetcli.host.json new file mode 100644 index 00000000000..22ab4a3929f --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/.template.config/dotnetcli.host.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json.schemastore.org/dotnetcli.host", + "symbolInfo": { + "TargetFrameworkOverride": { + "isHidden": "true", + "longName": "target-framework-override", + "shortName": "" + }, + "Framework": { + "longName": "framework" + }, + "skipRestore": { + "longName": "no-restore", + "shortName": "" + }, + "langVersion": { + "longName": "langVersion", + "shortName": "" + } + }, + "usageExamples": [ + "" + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/.template.config/template.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/.template.config/template.json new file mode 100644 index 00000000000..db146b70b98 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/.template.config/template.json @@ -0,0 +1,86 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "Microsoft", + "classifications": ["Common", "WPF"], + "name": "WPF Class library", + "generatorVersions": "[1.0.0.0-*)", + "description": "A project for creating a class library that targets a .NET Core WPF Application", + "groupIdentity": "Microsoft.Common.WPF.Library", + "precedence": "3000", + "identity": "Microsoft.Common.WPF.Library.VisualBasic.3.0", + "shortName": "wpflib", + "tags": { + "language": "VB", + "type": "project" + }, + "sourceName": "Company.ClassLibrary1", + "preferNameDirectory": true, + "symbols": { + "TargetFrameworkOverride": { + "type": "parameter", + "description": "Overrides the target framework", + "replaces": "TargetFrameworkOverride", + "datatype": "string", + "defaultValue": "" + }, + "Framework": { + "type": "parameter", + "description": "The target framework for the project.", + "datatype": "choice", + "choices": [ + { + "choice": "netcoreapp3.0", + "description": "Target netcoreapp3.0" + } + ], + "replaces": "netcoreapp3.0", + "defaultValue": "netcoreapp3.0" + }, + "langVersion": { + "type": "parameter", + "datatype": "text", + "description": "Sets langVersion in the created project file", + "defaultValue": "", + "replaces": "$(ProjectLanguageVersion)" + }, + "HostIdentifier": { + "type": "bind", + "binding": "HostIdentifier" + }, + "skipRestore": { + "type": "parameter", + "datatype": "bool", + "description": "If specified, skips the automatic restore of the project on create.", + "defaultValue": "false" + } + }, + "primaryOutputs": [ + { "path": "Company.ClassLibrary1.csproj" }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "path": "Class1.vb" + } + ], + "defaultName": "WpfLibrary1", + "postActions": [ + { + "condition": "(!skipRestore)", + "description": "Restore NuGet packages required by this project.", + "manualInstructions": [ + { "text": "Run 'dotnet restore'" } + ], + "actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025", + "continueOnError": true + }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "description": "Opens Class1.cs in the editor", + "manualInstructions": [ ], + "actionId": "84C0DA21-51C8-4541-9940-6CA19AF04EE6", + "args": { + "files": "1" + }, + "continueOnError": true + } + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/Class1.vb b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/Class1.vb new file mode 100644 index 00000000000..701656126aa --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/Class1.vb @@ -0,0 +1,3 @@ +Public Class Class1 + +End Class diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/Company.ClassLibrary1.vbproj b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/Company.ClassLibrary1.vbproj new file mode 100644 index 00000000000..5222ae5dcde --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfClassLibrary-VisualBasic/Company.ClassLibrary1.vbproj @@ -0,0 +1,12 @@ + + + + Company.ClassLibrary1 + netcoreapp3.0 + TargetFrameworkOverride + Company.ClassLibrary1 + $(ProjectLanguageVersion) + true + + + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/.template.config/dotnetcli.host.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/.template.config/dotnetcli.host.json new file mode 100644 index 00000000000..22ab4a3929f --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/.template.config/dotnetcli.host.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json.schemastore.org/dotnetcli.host", + "symbolInfo": { + "TargetFrameworkOverride": { + "isHidden": "true", + "longName": "target-framework-override", + "shortName": "" + }, + "Framework": { + "longName": "framework" + }, + "skipRestore": { + "longName": "no-restore", + "shortName": "" + }, + "langVersion": { + "longName": "langVersion", + "shortName": "" + } + }, + "usageExamples": [ + "" + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/.template.config/template.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/.template.config/template.json new file mode 100644 index 00000000000..e0fbadfac7a --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/.template.config/template.json @@ -0,0 +1,86 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "Microsoft", + "classifications": ["Common", "WPF"], + "name": "WPF Custom Control Library", + "generatorVersions": "[1.0.0.0-*)", + "description": "A project for creating a custom control library for .NET Core WPF Applications", + "groupIdentity": "Microsoft.Common.WPF.CustomControl", + "precedence": "3000", + "identity": "Microsoft.Common.WPF.CustomControl.CSharp.3.0", + "shortName": "wpfcustomcontrollib", + "tags": { + "language": "C#", + "type": "project" + }, + "sourceName": "Company.WpfCustomControlLibrary", + "preferNameDirectory": true, + "symbols": { + "TargetFrameworkOverride": { + "type": "parameter", + "description": "Overrides the target framework", + "replaces": "TargetFrameworkOverride", + "datatype": "string", + "defaultValue": "" + }, + "Framework": { + "type": "parameter", + "description": "The target framework for the project.", + "datatype": "choice", + "choices": [ + { + "choice": "netcoreapp3.0", + "description": "Target netcoreapp3.0" + } + ], + "replaces": "netcoreapp3.0", + "defaultValue": "netcoreapp3.0" + }, + "langVersion": { + "type": "parameter", + "datatype": "text", + "description": "Sets langVersion in the created project file", + "defaultValue": "", + "replaces": "$(ProjectLanguageVersion)" + }, + "HostIdentifier": { + "type": "bind", + "binding": "HostIdentifier" + }, + "skipRestore": { + "type": "parameter", + "datatype": "bool", + "description": "If specified, skips the automatic restore of the project on create.", + "defaultValue": "false" + } + }, + "primaryOutputs": [ + { "path": "Company.WpfCustomControlLibrary.csproj" }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "path": "CustomControl1.cs" + } + ], + "defaultName": "WpfCustomControlLibrary1", + "postActions": [ + { + "condition": "(!skipRestore)", + "description": "Restore NuGet packages required by this project.", + "manualInstructions": [ + { "text": "Run 'dotnet restore'" } + ], + "actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025", + "continueOnError": true + }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "description": "Opens CustomControl1.cs in the editor", + "manualInstructions": [ ], + "actionId": "84C0DA21-51C8-4541-9940-6CA19AF04EE6", + "args": { + "files": "1" + }, + "continueOnError": true + } + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/AssemblyInfo.cs b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/AssemblyInfo.cs new file mode 100644 index 00000000000..3c50569420d --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly:ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/Company.WpfCustomControlLibrary.csproj b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/Company.WpfCustomControlLibrary.csproj new file mode 100644 index 00000000000..e01c8a1a755 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/Company.WpfCustomControlLibrary.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp3.0 + TargetFrameworkOverride + Company.WpfCustomControlLibrary + $(ProjectLanguageVersion) + true + + + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/CustomControl1.cs b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/CustomControl1.cs new file mode 100644 index 00000000000..68361700126 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/CustomControl1.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Company.WpfCustomControlLibrary +{ + /// + /// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file. + /// + /// Step 1a) Using this custom control in a XAML file that exists in the current project. + /// Add this XmlNamespace attribute to the root element of the markup file where it is + /// to be used: + /// + /// xmlns:MyNamespace="clr-namespace:Company.WpfCustomControlLibrary" + /// + /// + /// Step 1b) Using this custom control in a XAML file that exists in a different project. + /// Add this XmlNamespace attribute to the root element of the markup file where it is + /// to be used: + /// + /// xmlns:MyNamespace="clr-namespace:Company.WpfCustomControlLibrary;assembly=Company.WpfCustomControlLibrary" + /// + /// You will also need to add a project reference from the project where the XAML file lives + /// to this project and Rebuild to avoid compilation errors: + /// + /// Right click on the target project in the Solution Explorer and + /// "Add Reference"->"Projects"->[Select this project] + /// + /// + /// Step 2) + /// Go ahead and use your control in the XAML file. + /// + /// + /// + /// + public class CustomControl1 : Control + { + static CustomControl1() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1))); + } + } +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/Themes/Generic.xaml b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/Themes/Generic.xaml new file mode 100644 index 00000000000..35c5325ad87 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-CSharp/Themes/Generic.xaml @@ -0,0 +1,17 @@ + + + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/.template.config/dotnetcli.host.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/.template.config/dotnetcli.host.json new file mode 100644 index 00000000000..22ab4a3929f --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/.template.config/dotnetcli.host.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json.schemastore.org/dotnetcli.host", + "symbolInfo": { + "TargetFrameworkOverride": { + "isHidden": "true", + "longName": "target-framework-override", + "shortName": "" + }, + "Framework": { + "longName": "framework" + }, + "skipRestore": { + "longName": "no-restore", + "shortName": "" + }, + "langVersion": { + "longName": "langVersion", + "shortName": "" + } + }, + "usageExamples": [ + "" + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/.template.config/template.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/.template.config/template.json new file mode 100644 index 00000000000..a9d1c4b8a0b --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/.template.config/template.json @@ -0,0 +1,86 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "Microsoft", + "classifications": ["Common", "WPF"], + "name": "WPF Custom Control Library", + "generatorVersions": "[1.0.0.0-*)", + "description": "A project for creating a custom control library for .NET Core WPF Applications", + "groupIdentity": "Microsoft.Common.WPF.CustomControl", + "precedence": "3000", + "identity": "Microsoft.Common.WPF.CustomControl.VisualBasic.3.0", + "shortName": "wpfcustomcontrollib", + "tags": { + "language": "VB", + "type": "project" + }, + "sourceName": "Company.WpfCustomControlLibrary", + "preferNameDirectory": true, + "symbols": { + "TargetFrameworkOverride": { + "type": "parameter", + "description": "Overrides the target framework", + "replaces": "TargetFrameworkOverride", + "datatype": "string", + "defaultValue": "" + }, + "Framework": { + "type": "parameter", + "description": "The target framework for the project.", + "datatype": "choice", + "choices": [ + { + "choice": "netcoreapp3.0", + "description": "Target netcoreapp3.0" + } + ], + "replaces": "netcoreapp3.0", + "defaultValue": "netcoreapp3.0" + }, + "langVersion": { + "type": "parameter", + "datatype": "text", + "description": "Sets langVersion in the created project file", + "defaultValue": "", + "replaces": "$(ProjectLanguageVersion)" + }, + "HostIdentifier": { + "type": "bind", + "binding": "HostIdentifier" + }, + "skipRestore": { + "type": "parameter", + "datatype": "bool", + "description": "If specified, skips the automatic restore of the project on create.", + "defaultValue": "false" + } + }, + "primaryOutputs": [ + { "path": "Company.WpfCustomControlLibrary.vbproj" }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "path": "CustomControl1.vb" + } + ], + "defaultName": "WpfCustomControlLibrary1", + "postActions": [ + { + "condition": "(!skipRestore)", + "description": "Restore NuGet packages required by this project.", + "manualInstructions": [ + { "text": "Run 'dotnet restore'" } + ], + "actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025", + "continueOnError": true + }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "description": "Opens CustomControl1.vb in the editor", + "manualInstructions": [ ], + "actionId": "84C0DA21-51C8-4541-9940-6CA19AF04EE6", + "args": { + "files": "1" + }, + "continueOnError": true + } + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/AssemblyInfo.vb b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/AssemblyInfo.vb new file mode 100644 index 00000000000..91a0a58fb04 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/AssemblyInfo.vb @@ -0,0 +1,11 @@ +Imports System.Windows + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/Company.WpfCustomControlLibrary.vbproj b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/Company.WpfCustomControlLibrary.vbproj new file mode 100644 index 00000000000..c8e6eb5a00b --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/Company.WpfCustomControlLibrary.vbproj @@ -0,0 +1,23 @@ + + + + netcoreapp3.0 + TargetFrameworkOverride + Company.WpfCustomControlLibrary + $(ProjectLanguageVersion) + true + + + + + + + + + + + + + + + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/CustomControl1.vb b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/CustomControl1.vb new file mode 100644 index 00000000000..54b7e34239e --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/CustomControl1.vb @@ -0,0 +1,18 @@ +Public Class CustomControl1 + Inherits Control + + ''' To use this custom control in a XAML file in another project, complete the following steps: + ''' + ''' 1. Add a reference to this project + ''' 2. Add the following line to the root element of the XAML file where you wish to use this control: + ''' xmlns:MyNamespace="clr-namespace:Company.WpfCustomControlLibrary;assembly=Company.WpfCustomControlLibrary" + ''' 2. Use the control in the XAML file: + ''' + + Shared Sub New() + 'This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class. + 'This style is defined in Themes\Generic.xaml + DefaultStyleKeyProperty.OverrideMetadata(GetType(CustomControl1), New FrameworkPropertyMetadata(GetType(CustomControl1))) + End Sub + +End Class diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/Themes/Generic.xaml b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/Themes/Generic.xaml new file mode 100644 index 00000000000..35c5325ad87 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfCustomControlLibrary-VisualBasic/Themes/Generic.xaml @@ -0,0 +1,17 @@ + + + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/.template.config/dotnetcli.host.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/.template.config/dotnetcli.host.json new file mode 100644 index 00000000000..22ab4a3929f --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/.template.config/dotnetcli.host.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json.schemastore.org/dotnetcli.host", + "symbolInfo": { + "TargetFrameworkOverride": { + "isHidden": "true", + "longName": "target-framework-override", + "shortName": "" + }, + "Framework": { + "longName": "framework" + }, + "skipRestore": { + "longName": "no-restore", + "shortName": "" + }, + "langVersion": { + "longName": "langVersion", + "shortName": "" + } + }, + "usageExamples": [ + "" + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/.template.config/template.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/.template.config/template.json new file mode 100644 index 00000000000..bba6d5bafd4 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/.template.config/template.json @@ -0,0 +1,90 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "Microsoft", + "classifications": ["Common", "WPF"], + "name": "WPF User Control Library", + "generatorVersions": "[1.0.0.0-*)", + "description": "A project for creating a user control library for .NET Core WPF Applications", + "groupIdentity": "Microsoft.Common.WPF.Control", + "precedence": "3000", + "identity": "Microsoft.Common.WPF.Control.CSharp.3.0", + "shortName": "wpfusercontrollib", + "tags": { + "language": "C#", + "type": "project" + }, + "sourceName": "Company.WpfControlLibrary", + "preferNameDirectory": true, + "symbols": { + "TargetFrameworkOverride": { + "type": "parameter", + "description": "Overrides the target framework", + "replaces": "TargetFrameworkOverride", + "datatype": "string", + "defaultValue": "" + }, + "Framework": { + "type": "parameter", + "description": "The target framework for the project.", + "datatype": "choice", + "choices": [ + { + "choice": "netcoreapp3.0", + "description": "Target netcoreapp3.0" + } + ], + "replaces": "netcoreapp3.0", + "defaultValue": "netcoreapp3.0" + }, + "langVersion": { + "type": "parameter", + "datatype": "text", + "description": "Sets langVersion in the created project file", + "defaultValue": "", + "replaces": "$(ProjectLanguageVersion)" + }, + "HostIdentifier": { + "type": "bind", + "binding": "HostIdentifier" + }, + "skipRestore": { + "type": "parameter", + "datatype": "bool", + "description": "If specified, skips the automatic restore of the project on create.", + "defaultValue": "false" + } + }, + "primaryOutputs": [ + { "path": "Company.WpfControlLibrary.csproj" }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "path": "UserControl1.xaml.cs" + }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "path": "UserControl1.xaml" + } + ], + "defaultName": "WpfControlLibrary1", + "postActions": [ + { + "condition": "(!skipRestore)", + "description": "Restore NuGet packages required by this project.", + "manualInstructions": [ + { "text": "Run 'dotnet restore'" } + ], + "actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025", + "continueOnError": true + }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "description": "Opens UserControl1.xaml in the editor", + "manualInstructions": [ ], + "actionId": "84C0DA21-51C8-4541-9940-6CA19AF04EE6", + "args": { + "files": "1;2" + }, + "continueOnError": true + } + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/AssemblyInfo.cs b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/AssemblyInfo.cs new file mode 100644 index 00000000000..3c50569420d --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly:ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/Company.WpfControlLibrary.csproj b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/Company.WpfControlLibrary.csproj new file mode 100644 index 00000000000..fc46449e179 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/Company.WpfControlLibrary.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp3.0 + TargetFrameworkOverride + Company.WpfControlLibrary + $(ProjectLanguageVersion) + true + + + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/UserControl1.xaml b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/UserControl1.xaml new file mode 100644 index 00000000000..0525fb85a32 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/UserControl1.xaml @@ -0,0 +1,12 @@ + + + + + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/UserControl1.xaml.cs b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/UserControl1.xaml.cs new file mode 100644 index 00000000000..ed07b7ab973 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-CSharp/UserControl1.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Company.WpfControlLibrary +{ + /// + /// Interaction logic for UserControl1.xaml + /// + public partial class UserControl1 : UserControl + { + public UserControl1() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/.template.config/dotnetcli.host.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/.template.config/dotnetcli.host.json new file mode 100644 index 00000000000..22ab4a3929f --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/.template.config/dotnetcli.host.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json.schemastore.org/dotnetcli.host", + "symbolInfo": { + "TargetFrameworkOverride": { + "isHidden": "true", + "longName": "target-framework-override", + "shortName": "" + }, + "Framework": { + "longName": "framework" + }, + "skipRestore": { + "longName": "no-restore", + "shortName": "" + }, + "langVersion": { + "longName": "langVersion", + "shortName": "" + } + }, + "usageExamples": [ + "" + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/.template.config/template.json b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/.template.config/template.json new file mode 100644 index 00000000000..b1553d1f87c --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/.template.config/template.json @@ -0,0 +1,90 @@ +{ + "$schema": "http://json.schemastore.org/template", + "author": "Microsoft", + "classifications": ["Common", "WPF"], + "name": "WPF User Control Library", + "generatorVersions": "[1.0.0.0-*)", + "description": "A project for creating a user control library for .NET Core WPF Applications", + "groupIdentity": "Microsoft.Common.WPF.Control", + "precedence": "3000", + "identity": "Microsoft.Common.WPF.Control.VisualBasic.3.0", + "shortName": "wpfusercontrollib", + "tags": { + "language": "VB", + "type": "project" + }, + "sourceName": "Company.WpfControlLibrary", + "preferNameDirectory": true, + "symbols": { + "TargetFrameworkOverride": { + "type": "parameter", + "description": "Overrides the target framework", + "replaces": "TargetFrameworkOverride", + "datatype": "string", + "defaultValue": "" + }, + "Framework": { + "type": "parameter", + "description": "The target framework for the project.", + "datatype": "choice", + "choices": [ + { + "choice": "netcoreapp3.0", + "description": "Target netcoreapp3.0" + } + ], + "replaces": "netcoreapp3.0", + "defaultValue": "netcoreapp3.0" + }, + "langVersion": { + "type": "parameter", + "datatype": "text", + "description": "Sets langVersion in the created project file", + "defaultValue": "", + "replaces": "$(ProjectLanguageVersion)" + }, + "HostIdentifier": { + "type": "bind", + "binding": "HostIdentifier" + }, + "skipRestore": { + "type": "parameter", + "datatype": "bool", + "description": "If specified, skips the automatic restore of the project on create.", + "defaultValue": "false" + } + }, + "primaryOutputs": [ + { "path": "Company.WpfControlLibrary.vbproj" }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "path": "UserControl1.xaml.vb" + }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "path": "UserControl1.xaml" + } + ], + "defaultName": "WpfControlLibrary1", + "postActions": [ + { + "condition": "(!skipRestore)", + "description": "Restore NuGet packages required by this project.", + "manualInstructions": [ + { "text": "Run 'dotnet restore'" } + ], + "actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025", + "continueOnError": true + }, + { + "condition": "(HostIdentifier != \"dotnetcli\" && HostIdentifier != \"dotnetcli-preview\")", + "description": "Opens UserControl1.xaml in the editor", + "manualInstructions": [ ], + "actionId": "84C0DA21-51C8-4541-9940-6CA19AF04EE6", + "args": { + "files": "1;2" + }, + "continueOnError": true + } + ] +} diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/AssemblyInfo.vb b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/AssemblyInfo.vb new file mode 100644 index 00000000000..91a0a58fb04 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/AssemblyInfo.vb @@ -0,0 +1,11 @@ +Imports System.Windows + +'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found. +'1st parameter: where theme specific resource dictionaries are located +'(used if a resource is not found in the page, +' or application resource dictionaries) + +'2nd parameter: where the generic resource dictionary is located +'(used if a resource is not found in the page, +'app, and any theme specific resource dictionaries) + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/Company.WpfControlLibrary.vbproj b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/Company.WpfControlLibrary.vbproj new file mode 100644 index 00000000000..e90867c207e --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/Company.WpfControlLibrary.vbproj @@ -0,0 +1,23 @@ + + + + netcoreapp3.0 + TargetFrameworkOverride + Company.WpfControlLibrary + $(ProjectLanguageVersion) + true + + + + + + + + + + + + + + + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/UserControl1.xaml b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/UserControl1.xaml new file mode 100644 index 00000000000..1fa88dea680 --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/UserControl1.xaml @@ -0,0 +1,12 @@ + + + + + diff --git a/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/UserControl1.xaml.vb b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/UserControl1.xaml.vb new file mode 100644 index 00000000000..29eef617e8d --- /dev/null +++ b/packaging/Microsoft.Dotnet.Wpf.ProjectTemplates/content/WpfUserControlLibrary-VisualBasic/UserControl1.xaml.vb @@ -0,0 +1,2 @@ +Public Class UserControl1 +End Class \ No newline at end of file diff --git a/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.props b/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.props index 985437424fe..923c2d9bdf3 100644 --- a/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.props +++ b/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.props @@ -1,6 +1,8 @@ <_MicrosoftNetSdkWindowsDesktop>true + true + true diff --git a/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.targets b/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.targets index 8beb86feab2..69b72c766d3 100644 --- a/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.targets +++ b/packaging/Microsoft.NET.Sdk.WindowsDesktop/targets/Microsoft.NET.Sdk.WindowsDesktop.targets @@ -25,7 +25,7 @@ DefaultItemsOfThisTypeEnabled="$(EnableDefaultPageItems)" PropertyNameToDisableDefaultItems="EnableDefaultPageItems" MoreInformationLink="$(DefaultItemsMoreInformationLink)" - ContinueOnError="$(CheckForDuplicateItemsContinueOnError)"> + ContinueOnError="$(ContinueOnError)"> diff --git a/src/Microsoft.DotNet.Wpf/src/Common/Graphics/wgx_core_types.cs b/src/Microsoft.DotNet.Wpf/src/Common/Graphics/wgx_core_types.cs index 3ed7983f254..0e703452127 100644 --- a/src/Microsoft.DotNet.Wpf/src/Common/Graphics/wgx_core_types.cs +++ b/src/Microsoft.DotNet.Wpf/src/Common/Graphics/wgx_core_types.cs @@ -454,6 +454,15 @@ internal struct MilColorF internal float g; internal float b; internal float a; + + public override int GetHashCode() + { + return a.GetHashCode() ^ r.GetHashCode() ^ g.GetHashCode() ^ b.GetHashCode(); + } + public override bool Equals(object obj) + { + return base.Equals(obj); + } }; /// diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskFileService.cs b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskFileService.cs index 48b3288c583..6bf2edd2637 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskFileService.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/Tasks/TaskFileService.cs @@ -125,7 +125,7 @@ public Stream GetContent(string srcFile) if (String.IsNullOrEmpty(srcFile)) { - throw new ArgumentNullException("srcFile"); + throw new ArgumentNullException(nameof(srcFile)); } if (HostFileManager != null) @@ -217,7 +217,7 @@ public DateTime GetLastChangeTime(string srcFile) if (String.IsNullOrEmpty(srcFile)) { - throw new ArgumentNullException("srcFile"); + throw new ArgumentNullException(nameof(srcFile)); } if (IsFileInHostManager(srcFile)) @@ -243,7 +243,7 @@ public bool Exists(string fileName) if (fileName == null) { - throw new ArgumentNullException("fileName"); + throw new ArgumentNullException(nameof(fileName)); } if (HostFileManager != null) @@ -265,7 +265,7 @@ public void Delete(string fileName) { if (fileName == null) { - throw new ArgumentNullException("fileName"); + throw new ArgumentNullException(nameof(fileName)); } if (IsFileInHostManager(fileName)) @@ -287,12 +287,12 @@ public void WriteFile(byte[] contentArray, string destinationFile) { if (String.IsNullOrEmpty(destinationFile)) { - throw new ArgumentNullException("destinationFile"); + throw new ArgumentNullException(nameof(destinationFile)); } if (contentArray == null) { - throw new ArgumentNullException("contentArray"); + throw new ArgumentNullException(nameof(contentArray)); } UTF8Encoding utf8Encoding = new UTF8Encoding(); @@ -331,12 +331,12 @@ public void WriteGeneratedCodeFile(byte[] contentArray, string destinationFileBa { if (String.IsNullOrEmpty(destinationFileBaseName)) { - throw new ArgumentNullException("destinationFileBaseName"); + throw new ArgumentNullException(nameof(destinationFileBaseName)); } if (contentArray == null) { - throw new ArgumentNullException("contentArray"); + throw new ArgumentNullException(nameof(contentArray)); } string buildFile = destinationFileBaseName + generatedExtension + languageSourceExtension; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.targets b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.targets index 5496449671b..e69dc43047d 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.targets +++ b/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft.WinFx.targets @@ -573,7 +573,10 @@ - + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/ILLinkTrim.xml b/src/Microsoft.DotNet.Wpf/src/PresentationCore/ILLinkTrim.xml new file mode 100644 index 00000000000..a488f34ce05 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/ILLinkTrim.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/CoreAppContextSwitches.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/CoreAppContextSwitches.cs index 69fa8116692..2202f636325 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/CoreAppContextSwitches.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/CoreAppContextSwitches.cs @@ -337,25 +337,6 @@ public static bool AllowExternalProcessToBlockAccessToTemporaryFiles #endregion - #region EnableLegacyDangerousClipboardDeserializationMode - - internal const string EnableLegacyDangerousClipboardDeserializationModeSwitchName = "Switch.System.Windows.EnableLegacyDangerousClipboardDeserializationMode"; - private static int _enableLegacyDangerousClipboardDeserializationMode; - public static bool EnableLegacyDangerousClipboardDeserializationMode - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - /// - /// Malicious managed objects could be placed in the clipboard lying about its format, - /// to fix this OleConverter now restricts object deserialization in some cases. - /// When this switch is enabled behavior falls back to deserializing without restriction. - /// - return LocalAppContext.GetCachedSwitchValue(EnableLegacyDangerousClipboardDeserializationModeSwitchName, ref _enableLegacyDangerousClipboardDeserializationMode); - } - } - - #endregion } #pragma warning restore 436 } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj b/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj index 1e14b2e0eb7..c01546b7fe3 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/PresentationCore.csproj @@ -1448,6 +1448,29 @@ false ColorProfiles + + + + false + $(AssemblyName).xml + - - - - - @@ -408,7 +402,6 @@ - @@ -507,7 +500,6 @@ - @@ -1427,6 +1419,7 @@ + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/Strings.resx b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/Strings.resx index 34bee49cf74..37dc5a6fbc8 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/Strings.resx +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/Strings.resx @@ -1027,10 +1027,12 @@ Too many files selected. Select fewer files and try again. - '{0}' does not exist.\r\nDo you want to create it? + '{0}' does not exist. +Do you want to create it? - '{0}' does not exist.\r\nVerify that the file name is correct. + '{0}' does not exist. +Verify that the file name is correct. '{0}' is not a valid file name. @@ -1042,7 +1044,8 @@ Filter index is not valid. - '{0}' already exists.\r\nDo you want to replace it? + '{0}' already exists. +Do you want to replace it? Cannot subclass a file dialog because sufficient memory is not available. diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.cs.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.cs.xlf index 9ae812bbd24..c5808961d95 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.cs.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.cs.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - Prvek {0} neexistuje.\r\nChcete ho vytvořit? + '{0}' does not exist. +Do you want to create it? + Prvek {0} neexistuje. +Chcete ho vytvořit? - '{0}' does not exist.\r\nVerify that the file name is correct. - Prvek {0} neexistuje.\r\nOvěřte, zda je správný název souboru. + '{0}' does not exist. +Verify that the file name is correct. + Prvek {0} neexistuje. +Ověřte, zda je správný název souboru. @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - Prvek {0} již existuje.\r\nChcete ho nahradit? + '{0}' already exists. +Do you want to replace it? + Prvek {0} již existuje. +Chcete ho nahradit? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.de.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.de.xlf index 2cc42dab48f..399c5bb71a8 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.de.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.de.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - "{0}" ist nicht vorhanden.\r\nMöchten Sie das Element erstellen? + '{0}' does not exist. +Do you want to create it? + "{0}" ist nicht vorhanden. +Möchten Sie das Element erstellen? - '{0}' does not exist.\r\nVerify that the file name is correct. - "{0}" ist nicht vorhanden.\r\nÜberprüfen Sie den Dateinamen. + '{0}' does not exist. +Verify that the file name is correct. + "{0}" ist nicht vorhanden. +Überprüfen Sie den Dateinamen. @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - "{0}" ist bereits vorhanden.\r\nMöchten Sie das Element ersetzen? + '{0}' already exists. +Do you want to replace it? + "{0}" ist bereits vorhanden. +Möchten Sie das Element ersetzen? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.es.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.es.xlf index fb26bbd85ad..0a01f2d29c3 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.es.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.es.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - "{0}" no existe.\r\n¿Desea crearlo? + '{0}' does not exist. +Do you want to create it? + "{0}" no existe. +¿Desea crearlo? - '{0}' does not exist.\r\nVerify that the file name is correct. - "{0}" no existe.\r\nCompruebe que el nombre de archivo sea correcto. + '{0}' does not exist. +Verify that the file name is correct. + "{0}" no existe. +Compruebe que el nombre de archivo sea correcto. @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - {0} ya existe.\r\n¿Desea reemplazarlo? + '{0}' already exists. +Do you want to replace it? + {0} ya existe. +¿Desea reemplazarlo? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.fr.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.fr.xlf index 4923ec13524..d60dd880866 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.fr.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.fr.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - '{0}' n'existe pas.\r\nVoulez-vous le créer ? + '{0}' does not exist. +Do you want to create it? + '{0}' n'existe pas. +Voulez-vous le créer ? - '{0}' does not exist.\r\nVerify that the file name is correct. - '{0}' n'existe pas.\r\nVérifiez que le nom de fichier est correct. + '{0}' does not exist. +Verify that the file name is correct. + '{0}' n'existe pas. +Vérifiez que le nom de fichier est correct. @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - '{0}' existe déjà.\r\nVoulez-vous le remplacer ? + '{0}' already exists. +Do you want to replace it? + '{0}' existe déjà. +Voulez-vous le remplacer ? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.it.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.it.xlf index b1da8dcfe78..ce85950c276 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.it.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.it.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - '{0}' non esiste.\r\nCrearlo? + '{0}' does not exist. +Do you want to create it? + '{0}' non esiste. +Crearlo? - '{0}' does not exist.\r\nVerify that the file name is correct. - '{0}' non esiste.\r\nVerificare che il nome file sia corretto. + '{0}' does not exist. +Verify that the file name is correct. + '{0}' non esiste. +Verificare che il nome file sia corretto. @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - '{0}' già esistente.\r\nSostituirlo? + '{0}' already exists. +Do you want to replace it? + '{0}' già esistente. +Sostituirlo? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ja.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ja.xlf index 8b54d5578ed..004a4084c03 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ja.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ja.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - '{0}' が存在しません。\r\n作成しますか? + '{0}' does not exist. +Do you want to create it? + '{0}' が存在しません。 +作成しますか? - '{0}' does not exist.\r\nVerify that the file name is correct. - '{0}' は存在しません。\r\nファイル名が正しいことをご確認ください。 + '{0}' does not exist. +Verify that the file name is correct. + '{0}' は存在しません。 +ファイル名が正しいことをご確認ください。 @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - '{0}' は既に存在します。\r\n置き換えますか? + '{0}' already exists. +Do you want to replace it? + '{0}' は既に存在します。 +置き換えますか? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ko.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ko.xlf index 7c331c41751..ed6f68dbbce 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ko.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ko.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - '{0}'이(가) 없습니다.\r\n만드시겠습니까? + '{0}' does not exist. +Do you want to create it? + '{0}'이(가) 없습니다. +만드시겠습니까? - '{0}' does not exist.\r\nVerify that the file name is correct. - '{0}'이(가) 없습니다.\r\n파일 이름이 올바른지 확인하세요. + '{0}' does not exist. +Verify that the file name is correct. + '{0}'이(가) 없습니다. +파일 이름이 올바른지 확인하세요. @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - ’{0}'이(가) 이미 있습니다.\r\n바꾸시겠습니까? + '{0}' already exists. +Do you want to replace it? + ’{0}'이(가) 이미 있습니다. +바꾸시겠습니까? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.pl.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.pl.xlf index 56b352a899a..c177ae3d797 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.pl.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.pl.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - Element „{0}” nie istnieje.\r\nCzy chcesz go utworzyć? + '{0}' does not exist. +Do you want to create it? + Element „{0}” nie istnieje. +Czy chcesz go utworzyć? - '{0}' does not exist.\r\nVerify that the file name is correct. - Element „{0}” nie istnieje.\r\nSprawdź, czy nazwa pliku jest prawidłowa. + '{0}' does not exist. +Verify that the file name is correct. + Element „{0}” nie istnieje. +Sprawdź, czy nazwa pliku jest prawidłowa. @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - Element „{0}” już istnieje.\r\nCzy chcesz go zastąpić? + '{0}' already exists. +Do you want to replace it? + Element „{0}” już istnieje. +Czy chcesz go zastąpić? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.pt-BR.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.pt-BR.xlf index 0d8f5085af5..6ee7e68d22b 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.pt-BR.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.pt-BR.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - '{0}' não existe.\r\nDeseja criá-lo? + '{0}' does not exist. +Do you want to create it? + '{0}' não existe. +Deseja criá-lo? - '{0}' does not exist.\r\nVerify that the file name is correct. - '{0}' não existe.\r\nVerifique se o nome de arquivo está correto. + '{0}' does not exist. +Verify that the file name is correct. + '{0}' não existe. +Verifique se o nome de arquivo está correto. @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - '{0}' já existe.\r\nDeseja substituí-lo? + '{0}' already exists. +Do you want to replace it? + '{0}' já existe. +Deseja substituí-lo? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ru.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ru.xlf index 7395bfeb60a..347a18bb8d0 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ru.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ru.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - "{0}" не существует.\r\nВы хотите создать его? + '{0}' does not exist. +Do you want to create it? + "{0}" не существует. +Вы хотите создать его? - '{0}' does not exist.\r\nVerify that the file name is correct. - "{0}" не существует.\r\nПроверьте имя файла. + '{0}' does not exist. +Verify that the file name is correct. + "{0}" не существует. +Проверьте имя файла. @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - "{0}" уже существует.\r\nВы хотите заменить его? + '{0}' already exists. +Do you want to replace it? + "{0}" уже существует. +Вы хотите заменить его? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.tr.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.tr.xlf index 5a5e038db94..43050226b59 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.tr.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.tr.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - '{0}' yok.\r\nOluşturmak istiyor musunuz? + '{0}' does not exist. +Do you want to create it? + '{0}' yok. +Oluşturmak istiyor musunuz? - '{0}' does not exist.\r\nVerify that the file name is correct. - '{0}' yok.\r\nDosya adının doğru olduğunu kontrol edin. + '{0}' does not exist. +Verify that the file name is correct. + '{0}' yok. +Dosya adının doğru olduğunu kontrol edin. @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - '{0}' zaten var.\r\nDeğiştirmek istiyor musunuz? + '{0}' already exists. +Do you want to replace it? + '{0}' zaten var. +Değiştirmek istiyor musunuz? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.zh-Hans.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.zh-Hans.xlf index d31c37bba92..0c5e886b44c 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.zh-Hans.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - “{0}”不存在。\r\n是否创建? + '{0}' does not exist. +Do you want to create it? + “{0}”不存在。 +是否创建? - '{0}' does not exist.\r\nVerify that the file name is correct. - “{0}”不存在。\r\n请验证文件名是否正确。 + '{0}' does not exist. +Verify that the file name is correct. + “{0}”不存在。 +请验证文件名是否正确。 @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - “{0}”已存在。\r\n是否替换它? + '{0}' already exists. +Do you want to replace it? + “{0}”已存在。 +是否替换它? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.zh-Hant.xlf b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.zh-Hant.xlf index 02a9024ef3d..b9f6f16c0be 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.zh-Hant.xlf @@ -1613,13 +1613,17 @@ - '{0}' does not exist.\r\nDo you want to create it? - '{0}' 不存在。\r\n要建立嗎? + '{0}' does not exist. +Do you want to create it? + '{0}' 不存在。 +要建立嗎? - '{0}' does not exist.\r\nVerify that the file name is correct. - '{0}' 不存在。\r\n請確認檔案名稱正確。 + '{0}' does not exist. +Verify that the file name is correct. + '{0}' 不存在。 +請確認檔案名稱正確。 @@ -1638,8 +1642,10 @@ - '{0}' already exists.\r\nDo you want to replace it? - '{0}' 已存在。\r\n要取代掉嗎? + '{0}' already exists. +Do you want to replace it? + '{0}' 已存在。 +要取代掉嗎? @@ -6469,4 +6475,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs index 7964f5d4455..0593bbdb3c4 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Application.cs @@ -445,7 +445,7 @@ public static void LoadComponent(Object component, Uri resourceLocator) // if not, this is a first time regular load of the component. PackagePart part = GetResourceOrContentPart(resourceLocator); ContentType contentType = new ContentType(part.ContentType); - stream = part.GetStream(); + stream = part.GetSeekableStream(); bCloseStream = true; // @@ -509,7 +509,7 @@ internal static object LoadComponent(Uri resourceLocator, bool bSkipJournaledPro PackagePart part = GetResourceOrContentPart(packUri); ContentType contentType = new ContentType(part.ContentType); - Stream stream = part.GetStream(); + Stream stream = part.GetSeekableStream(); ParserContext pc = new ParserContext(); pc.BaseUri = packUri; @@ -623,7 +623,7 @@ public static StreamResourceInfo GetResourceStream(Uri uriResource) } ResourcePart part = GetResourceOrContentPart(uriResource) as ResourcePart; - return (part == null) ? null : new StreamResourceInfo(part.GetStream(), part.ContentType); + return (part == null) ? null : new StreamResourceInfo(part.GetSeekableStream(), part.ContentType); } /// @@ -656,7 +656,7 @@ public static StreamResourceInfo GetContentStream(Uri uriContent) } ContentFilePart part = GetResourceOrContentPart(uriContent) as ContentFilePart; - return (part == null) ? null : new StreamResourceInfo(part.GetStream(), part.ContentType); + return (part == null) ? null : new StreamResourceInfo(part.GetSeekableStream(), part.ContentType); } /// @@ -714,7 +714,7 @@ public static StreamResourceInfo GetRemoteStream(Uri uriRemote) { try { - stream = sooPart.GetStream(); + stream = sooPart.GetSeekableStream(); if (stream == null) { diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ComboBoxAutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ComboBoxAutomationPeer.cs index 8476bfb2e6f..7b426dca759 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ComboBoxAutomationPeer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ComboBoxAutomationPeer.cs @@ -51,16 +51,20 @@ override protected string GetClassNameCore() override public object GetPattern(PatternInterface pattern) { object iface = null; + ComboBox owner = (ComboBox)Owner; if (pattern == PatternInterface.Value) { - ComboBox owner = (ComboBox)Owner; if (owner.IsEditable) iface = this; } else if(pattern == PatternInterface.ExpandCollapse) { iface = this; } + else if (pattern == PatternInterface.Scroll && !owner.IsDropDownOpen) + { + iface = this; + } else { iface = base.GetPattern(pattern); diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/GroupItemAutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/GroupItemAutomationPeer.cs index 6d551508d15..e205f79c15f 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/GroupItemAutomationPeer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/GroupItemAutomationPeer.cs @@ -130,14 +130,7 @@ protected override List GetChildrenCore() ItemsControlAutomationPeer itemsControlAP = itemsControl.CreateAutomationPeer() as ItemsControlAutomationPeer; if (itemsControlAP != null) { - Panel itemsHost = owner.ItemsHost; - - if (itemsHost == null) - return null; - - IList childItems = itemsHost.Children; - List children = new List(childItems.Count); - ItemPeersStorage addedChildren = new ItemPeersStorage(); + List children = new List(); bool useNetFx472CompatibleAccessibilityFeatures = AccessibilitySwitches.UseNetFx472CompatibleAccessibilityFeatures; if (!useNetFx472CompatibleAccessibilityFeatures && owner.Expander != null) @@ -152,6 +145,24 @@ protected override List GetChildrenCore() _expanderPeer.GetChildren(); } } + Panel itemsHost = owner.ItemsHost; + + if (itemsHost == null) + { + if (_expanderPeer == null) + { + return null; + } + else + { + children.Add(_expanderPeer); + return children; + } + } + + IList childItems = itemsHost.Children; + ItemPeersStorage addedChildren = new ItemPeersStorage(); + foreach (UIElement child in childItems) { diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/RootBrowserWindowAutomationPeer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/RootBrowserWindowAutomationPeer.cs deleted file mode 100644 index 8199f50524f..00000000000 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/RootBrowserWindowAutomationPeer.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using MS.Internal.AppModel; - -namespace System.Windows.Automation.Peers -{ - - /// - internal class RootBrowserWindowAutomationPeer : WindowAutomationPeer - { - /// - public RootBrowserWindowAutomationPeer(RootBrowserWindow owner): base(owner) - {} - - /// - override protected string GetClassNameCore() - { - return "RootBrowserWindow"; - } - - } -} - - - diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Condition.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Condition.cs index 4a322a6931f..73371a4cebd 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Condition.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Condition.cs @@ -50,12 +50,12 @@ public Condition( DependencyProperty conditionProperty, object conditionValue ) /// public Condition( DependencyProperty conditionProperty, object conditionValue, string sourceName ) { - if( conditionProperty == null ) + if(conditionProperty == null) { - throw new ArgumentNullException("conditionProperty"); + throw new ArgumentNullException(nameof(conditionProperty)); } - if( !conditionProperty.IsValidValue( conditionValue ) ) + if(!conditionProperty.IsValidValue(conditionValue)) { throw new ArgumentException(SR.Get(SRID.InvalidPropertyValue, conditionValue, conditionProperty.Name)); } @@ -71,9 +71,9 @@ public Condition( DependencyProperty conditionProperty, object conditionValue, s /// public Condition( BindingBase binding, object conditionValue ) { - if( binding == null ) + if(binding == null) { - throw new ArgumentNullException("binding"); + throw new ArgumentNullException(nameof(binding)); } Binding = binding; @@ -118,7 +118,7 @@ public BindingBase Binding throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "Condition")); } - if( _property != null ) + if(_property != null) { throw new InvalidOperationException(SR.Get(SRID.ConditionCannotUseBothPropertyAndBinding)); } @@ -147,7 +147,7 @@ public object Value value.GetType().Name)); } - if( value is Expression ) + if(value is Expression) { throw new ArgumentException(SR.Get(SRID.ConditionValueOfExpressionNotSupported)); } @@ -171,7 +171,7 @@ public string SourceName } set { - if( _sealed ) + if(_sealed) { throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "Condition")); } @@ -271,11 +271,11 @@ public static void ReceiveMarkupExtension(object targetObject, XamlSetMarkupExte { if (targetObject == null) { - throw new ArgumentNullException("targetObject"); + throw new ArgumentNullException(nameof(targetObject)); } if (eventArgs == null) { - throw new ArgumentNullException("eventArgs"); + throw new ArgumentNullException(nameof(eventArgs)); } Condition condition = targetObject as Condition; @@ -292,11 +292,11 @@ public static void ReceiveTypeConverter(object targetObject, XamlSetTypeConverte Condition condition = targetObject as Condition; if (condition == null) { - throw new ArgumentNullException("targetObject"); + throw new ArgumentNullException(nameof(targetObject)); } if (eventArgs == null) { - throw new ArgumentNullException("eventArgs"); + throw new ArgumentNullException(nameof(eventArgs)); } if (eventArgs.Member.Name == "Property") diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Canvas.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Canvas.cs index 44b18d2b3d3..5f64b580c68 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Canvas.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Canvas.cs @@ -81,7 +81,7 @@ public Canvas() : base() [AttachedPropertyBrowsableForChildren()] public static double GetLeft(UIElement element) { - if (element == null) { throw new ArgumentNullException("element"); } + if (element == null) { throw new ArgumentNullException(nameof(element)); } return (double)element.GetValue(LeftProperty); } @@ -93,7 +93,7 @@ public static double GetLeft(UIElement element) /// public static void SetLeft(UIElement element, double length) { - if (element == null) { throw new ArgumentNullException("element"); } + if (element == null) { throw new ArgumentNullException(nameof(element)); } element.SetValue(LeftProperty, length); } @@ -107,7 +107,7 @@ public static void SetLeft(UIElement element, double length) [AttachedPropertyBrowsableForChildren()] public static double GetTop(UIElement element) { - if (element == null) { throw new ArgumentNullException("element"); } + if (element == null) { throw new ArgumentNullException(nameof(element)); } return (double)element.GetValue(TopProperty); } @@ -119,7 +119,7 @@ public static double GetTop(UIElement element) /// public static void SetTop(UIElement element, double length) { - if (element == null) { throw new ArgumentNullException("element"); } + if (element == null) { throw new ArgumentNullException(nameof(element)); } element.SetValue(TopProperty, length); } @@ -133,7 +133,7 @@ public static void SetTop(UIElement element, double length) [AttachedPropertyBrowsableForChildren()] public static double GetRight(UIElement element) { - if (element == null) { throw new ArgumentNullException("element"); } + if (element == null) { throw new ArgumentNullException(nameof(element)); } return (double)element.GetValue(RightProperty); } @@ -145,7 +145,7 @@ public static double GetRight(UIElement element) /// public static void SetRight(UIElement element, double length) { - if (element == null) { throw new ArgumentNullException("element"); } + if (element == null) { throw new ArgumentNullException(nameof(element)); } element.SetValue(RightProperty, length); } @@ -159,7 +159,7 @@ public static void SetRight(UIElement element, double length) [AttachedPropertyBrowsableForChildren()] public static double GetBottom(UIElement element) { - if (element == null) { throw new ArgumentNullException("element"); } + if (element == null) { throw new ArgumentNullException(nameof(element)); } return (double)element.GetValue(BottomProperty); } @@ -171,7 +171,7 @@ public static double GetBottom(UIElement element) /// public static void SetBottom(UIElement element, double length) { - if (element == null) { throw new ArgumentNullException("element"); } + if (element == null) { throw new ArgumentNullException(nameof(element)); } element.SetValue(BottomProperty, length); } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DataGridClipboardHelper.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DataGridClipboardHelper.cs index f3ec67ce172..cce1cf20382 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DataGridClipboardHelper.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/DataGridClipboardHelper.cs @@ -9,6 +9,7 @@ using System.IO; using System.Text; using System.Windows; +using MS.Internal.Text; namespace System.Windows.Controls { @@ -84,7 +85,7 @@ internal static void GetClipboardContentForHtml(StringBuilder content) // There are characters in Asian languages which require more than 2 bytes for encoding into UTF-8 // Marshal.SystemDefaultCharSize is 2 and would not be appropriate in all cases. We have to explicitly calculate the number of bytes. byte[] sourceBytes = Encoding.Unicode.GetBytes(content.ToString()); - byte[] destinationBytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, sourceBytes); + byte[] destinationBytes = InternalEncoding.Convert(Encoding.Unicode, Encoding.UTF8, sourceBytes); int bytecountEndOfFragment = bytecountPrefixContext + destinationBytes.Length; int bytecountEndOfHtml = bytecountEndOfFragment + bytecountSuffixContext; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/XmlNamespaceMappingCollection.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/XmlNamespaceMappingCollection.cs index 6174f185f4e..f55c3a15384 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/XmlNamespaceMappingCollection.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/XmlNamespaceMappingCollection.cs @@ -72,7 +72,7 @@ void IAddChild.AddText(string text) protected virtual void AddText(string text) { if (text == null) - throw new ArgumentNullException("text"); + throw new ArgumentNullException(nameof(text)); XamlSerializerUtil.ThrowIfNonWhiteSpaceInAddText(text, this); } @@ -88,10 +88,10 @@ protected virtual void AddText(string text) public void Add(XmlNamespaceMapping mapping) { if (mapping == null) - throw new ArgumentNullException("mapping"); + throw new ArgumentNullException(nameof(mapping)); if (mapping.Uri == null) - throw new ArgumentException(SR.Get(SRID.RequiresXmlNamespaceMappingUri), "mapping"); + throw new ArgumentException(SR.Get(SRID.RequiresXmlNamespaceMappingUri), nameof(mapping)); // BUG 983685: change this to take Uri when AddNamespace is fixed to use Uri instead of String. // SECURITY: this workaround (passing the original string) defeats the security benefits of using Uri. @@ -123,10 +123,10 @@ public void Clear() public bool Contains(XmlNamespaceMapping mapping) { if (mapping == null) - throw new ArgumentNullException("mapping"); + throw new ArgumentNullException(nameof(mapping)); if (mapping.Uri == null) - throw new ArgumentException(SR.Get(SRID.RequiresXmlNamespaceMappingUri), "mapping"); + throw new ArgumentException(SR.Get(SRID.RequiresXmlNamespaceMappingUri), nameof(mapping)); return (this.LookupNamespace(mapping.Prefix) == mapping.Uri.OriginalString); } @@ -137,14 +137,14 @@ public bool Contains(XmlNamespaceMapping mapping) public void CopyTo(XmlNamespaceMapping[] array, int arrayIndex) { if (array == null) - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); int i = arrayIndex; int maxLength = array.Length; foreach (XmlNamespaceMapping mapping in this) { if (i >= maxLength) - throw new ArgumentException(SR.Get(SRID.Collection_CopyTo_NumberOfElementsExceedsArrayLength, "arrayIndex", "array")); + throw new ArgumentException(SR.Get(SRID.Collection_CopyTo_NumberOfElementsExceedsArrayLength, nameof(arrayIndex), nameof(array))); array[i] = mapping; ++ i; } @@ -160,10 +160,10 @@ public void CopyTo(XmlNamespaceMapping[] array, int arrayIndex) public bool Remove(XmlNamespaceMapping mapping) { if (mapping == null) - throw new ArgumentNullException("mapping"); + throw new ArgumentNullException(nameof(mapping)); if (mapping.Uri == null) - throw new ArgumentException(SR.Get(SRID.RequiresXmlNamespaceMappingUri), "mapping"); + throw new ArgumentException(SR.Get(SRID.RequiresXmlNamespaceMappingUri), nameof(mapping)); if (Contains(mapping)) { diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/DocumentStructures/SemanticBasicElement.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/DocumentStructures/SemanticBasicElement.cs index f4607f446e6..905cc4ef8f4 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/DocumentStructures/SemanticBasicElement.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/DocumentStructures/SemanticBasicElement.cs @@ -67,7 +67,7 @@ public void Add(BlockElement element) { if (element == null) { - throw new ArgumentNullException("element"); + throw new ArgumentNullException(nameof(element)); } ((IAddChild) this).AddChild(element); } @@ -116,7 +116,7 @@ public void Add(NamedElement element) { if (element == null) { - throw new ArgumentNullException("element"); + throw new ArgumentNullException(nameof(element)); } ((IAddChild) this).AddChild(element); } @@ -176,7 +176,7 @@ public void Add(NamedElement element) { if (element == null) { - throw new ArgumentNullException("element"); + throw new ArgumentNullException(nameof(element)); } ((IAddChild) this).AddChild(element); } @@ -209,7 +209,7 @@ public void Add(ListItemStructure listItem) { if (listItem == null) { - throw new ArgumentNullException("listItem"); + throw new ArgumentNullException(nameof(listItem)); } ((IAddChild) this).AddChild(listItem); } @@ -222,7 +222,7 @@ void IAddChild.AddChild(object value) return; } - throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, value.GetType(), typeof(ListItemStructure)), "value"); + throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, value.GetType(), typeof(ListItemStructure)), nameof(value)); } void IAddChild.AddText(string text) { } @@ -254,7 +254,7 @@ public void Add(BlockElement element) { if (element == null) { - throw new ArgumentNullException("element"); + throw new ArgumentNullException(nameof(element)); } ((IAddChild) this).AddChild(element); } @@ -311,7 +311,7 @@ public void Add(TableRowGroupStructure tableRowGroup) { if (tableRowGroup == null) { - throw new ArgumentNullException("tableRowGroup"); + throw new ArgumentNullException(nameof(tableRowGroup)); } ((IAddChild) this).AddChild(tableRowGroup); } @@ -356,7 +356,7 @@ public void Add(TableRowStructure tableRow) { if (tableRow == null) { - throw new ArgumentNullException("tableRow"); + throw new ArgumentNullException(nameof(tableRow)); } ((IAddChild) this).AddChild(tableRow); } @@ -368,7 +368,7 @@ void IAddChild.AddChild(object value) _elementList.Add((TableRowStructure)value); return; } - throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, value.GetType(), typeof(TableRowStructure)), "value"); + throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, value.GetType(), typeof(TableRowStructure)), nameof(value)); } void IAddChild.AddText(string text) { } @@ -402,7 +402,7 @@ public void Add(TableCellStructure tableCell) { if (tableCell == null) { - throw new ArgumentNullException("tableCell"); + throw new ArgumentNullException(nameof(tableCell)); } ((IAddChild) this).AddChild(tableCell); } @@ -414,7 +414,7 @@ void IAddChild.AddChild(object value) _elementList.Add((TableCellStructure)value); return; } - throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, value.GetType(), typeof(TableCellStructure)), "value"); + throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, value.GetType(), typeof(TableCellStructure)), nameof(value)); } void IAddChild.AddText(string text) { } @@ -449,7 +449,7 @@ public void Add(BlockElement element) { if (element == null) { - throw new ArgumentNullException("element"); + throw new ArgumentNullException(nameof(element)); } ((IAddChild) this).AddChild(element); } @@ -462,7 +462,7 @@ void IAddChild.AddChild(object value) return; } throw new ArgumentException(SR.Get(SRID.DocumentStructureUnexpectedParameterType4, value.GetType(), - typeof(ParagraphStructure), typeof(TableStructure), typeof(ListStructure), typeof(FigureStructure)), "value"); + typeof(ParagraphStructure), typeof(TableStructure), typeof(ListStructure), typeof(FigureStructure)), nameof(value)); } void IAddChild.AddText(string text) { } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FixedPage.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FixedPage.cs index ac580a2350f..d831d8a2feb 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FixedPage.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FixedPage.cs @@ -614,10 +614,7 @@ internal static Uri GetLinkUri(IInputElement element, Uri inputUri) DependencyObject dpo = element as DependencyObject; Debug.Assert(dpo != null, "GetLinkUri shouldn't be called for non-DependencyObjects."); - if (inputUri != null && - (inputUri.Scheme == PackUriHelper.UriSchemePack && !String.IsNullOrEmpty(inputUri.Fragment))) - // We want to allow navigation to pack:// Uris as we may get these from automation, but we - // wouldn't support this if an actual Uri were given as a pack:// Uri + if (inputUri != null) { // // First remove the fragment, this is to prevent escape in file URI case, for example, diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FrameworkTextComposition.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FrameworkTextComposition.cs index f12ce478998..a1bd4e8f778 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FrameworkTextComposition.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FrameworkTextComposition.cs @@ -60,9 +60,6 @@ internal FrameworkTextComposition(InputManager inputManager, IInputElement sourc /// We finalize Cicero's composition and TextStore will automatically /// generate the proper TextComposition events. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public override void Complete() { _pendingComplete = true; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/NLGSpellerInterop.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/NLGSpellerInterop.cs index 0b3f38258ce..2b4ac76b2f6 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/NLGSpellerInterop.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/NLGSpellerInterop.cs @@ -314,9 +314,6 @@ internal override object LoadDictionary(string lexiconFilePath) /// which we created and filled with data from pack Uri locations specified by user. /// These 'trusted' files are placed under . /// - /// Explicitely specified file locations we will passed to ILexicon APIs without asserting - /// Security permissions, so it would pass in FullTrust and fail in PartialTrust. - /// /// Files specified in are wrapped in FileIOPermission.Assert(), /// providing read access to trusted files under , i.e. additionally /// we're making sure that specified trusted locations are under the trusted Folder. diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/RtfToXamlLexer.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/RtfToXamlLexer.cs index f166dff15d1..5c0ef9a8a48 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/RtfToXamlLexer.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/RtfToXamlLexer.cs @@ -10,7 +10,8 @@ using System.Diagnostics; using System.Globalization; using System.Text; -using System.IO; // Stream +using System.IO; // Stream +using MS.Internal.Text; namespace System.Windows.Documents { @@ -35,7 +36,7 @@ internal RtfToXamlLexer(byte[] rtfBytes) _rtfBytes = rtfBytes; _currentCodePage = CultureInfo.CurrentCulture.TextInfo.ANSICodePage; - _currentEncoding = Encoding.GetEncoding(_currentCodePage); + _currentEncoding = InternalEncoding.GetEncoding(_currentCodePage); } #endregion Constructors @@ -300,7 +301,7 @@ internal int CodePage if (_currentCodePage != value) { _currentCodePage = value; - _currentEncoding = Encoding.GetEncoding(_currentCodePage); + _currentEncoding = InternalEncoding.GetEncoding(_currentCodePage); } } } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/RtfToXamlReader.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/RtfToXamlReader.cs index 102fadd38e2..2b000132d13 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/RtfToXamlReader.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/RtfToXamlReader.cs @@ -14,6 +14,7 @@ using System.Windows.Media; // Color using Microsoft.Win32; // Registry for font substitutes using MS.Internal; // Invariant +using MS.Internal.Text; namespace System.Windows.Documents @@ -3444,7 +3445,7 @@ internal void ComputePreferredCodePage() for (int i = 0; i < CodePageList.Length; i++) { - Encoding e = Encoding.GetEncoding(CodePageList[i]); + Encoding e = InternalEncoding.GetEncoding(CodePageList[i]); int cb = e.GetBytes(Name, 0, Name.Length, rgBytes, 0); int cch = e.GetChars(rgBytes, 0, cb, rgChars, 0); @@ -8844,7 +8845,7 @@ private void ConvertSymbolCharValueToText(DocumentNode dn, int nChar, EncodeType if (nChar < 0xFFFF) { // NB: How to interpret this numeric value as Shift-JIS? - Encoding ec = Encoding.GetEncoding(932); + Encoding ec = InternalEncoding.GetEncoding(932); int nChars = nChar > 256 ? 2 : 1; byte[] ba = new byte[2]; if (nChars == 1) diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/SpellerInteropBase.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/SpellerInteropBase.cs index 6f171f43b3b..56f926de50c 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/SpellerInteropBase.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/SpellerInteropBase.cs @@ -175,9 +175,6 @@ internal abstract int EnumTextSegments(char[] text, int count, /// which we created and filled with data from pack Uri locations specified by user. /// These 'trusted' files are placed under . /// - /// Explicitly specified file locations will be passed to COM APIs without asserting - /// Security permissions, so it would pass in FullTrust and fail in PartialTrust. - /// /// Files specified in are wrapped in FileIOPermission.Assert(), /// providing read access to trusted files under , i.e. additionally /// we're making sure that specified trusted locations are under the trusted Folder. diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextEditorCopyPaste.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextEditorCopyPaste.cs index c619adef732..bd3cf4c9af7 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextEditorCopyPaste.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextEditorCopyPaste.cs @@ -923,8 +923,7 @@ private static bool PasteXaml(TextEditor This, string pasteXaml) try { // Parse the fragment into a separate subtree - bool useRestrictiveXamlReader = !Clipboard.UseLegacyDangerousClipboardDeserializationMode(); - object xamlObject = XamlReader.Load(new XmlTextReader(new System.IO.StringReader(pasteXaml)), useRestrictiveXamlReader); + object xamlObject = XamlReader.Load(new XmlTextReader(new System.IO.StringReader(pasteXaml)), useRestrictiveXamlReader: true); TextElement flowContent = xamlObject as TextElement; success = flowContent == null ? false : PasteTextElement(This, flowContent); diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/WpfPayload.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/WpfPayload.cs index 40a69e8a890..79e924c6788 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/WpfPayload.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/WpfPayload.cs @@ -21,6 +21,7 @@ namespace System.Windows.Documents { using MS.Internal; // Invariant + using MS.Internal.IO.Packaging; using System; using System.Xml; using System.Windows.Markup; // TypeConvertContext, ParserContext @@ -221,7 +222,7 @@ internal static string SaveRange(ITextRange range, ref Stream stream, bool useFl PackagePart xamlEntryPart = wpfPayload.CreateWpfEntryPart(); // Write the part's content - Stream xamlPartStream = xamlEntryPart.GetStream(); + Stream xamlPartStream = xamlEntryPart.GetSeekableStream(); using (xamlPartStream) { StreamWriter xamlPartWriter = new StreamWriter(xamlPartStream); @@ -261,7 +262,7 @@ internal static MemoryStream SaveImage(BitmapSource bitmapSource, string imageCo PackagePart xamlEntryPart = wpfPayload.CreateWpfEntryPart(); // Write the part's content - Stream xamlPartStream = xamlEntryPart.GetStream(); + Stream xamlPartStream = xamlEntryPart.GetSeekableStream(); using (xamlPartStream) { StreamWriter xamlPartWriter = new StreamWriter(xamlPartStream); @@ -334,8 +335,8 @@ internal static object LoadElement(Stream stream) // Uniqueness is required to make sure that cached images are not mixed up. int newWpfPayoutCount = Interlocked.Increment(ref _wpfPayloadCount); Uri payloadUri = new Uri("payload://wpf" + newWpfPayoutCount, UriKind.Absolute); - Uri entryPartUri = PackUriHelper.Create(payloadUri, xamlEntryPart.Uri); // gives an absolute uri of the entry part - Uri packageUri = PackUriHelper.GetPackageUri(entryPartUri); // extracts package uri from combined package+part uri + Uri entryPartUri = System.IO.Packaging.PackUriHelper.Create(payloadUri, xamlEntryPart.Uri); // gives an absolute uri of the entry part + Uri packageUri = System.IO.Packaging.PackUriHelper.GetPackageUri(entryPartUri); // extracts package uri from combined package+part uri PackageStore.AddPackage(packageUri, wpfPayload.Package); // Register the package // Set this temporary uri as a base uri for xaml parser @@ -343,8 +344,7 @@ internal static object LoadElement(Stream stream) parserContext.BaseUri = entryPartUri; // Call xaml parser - bool useRestrictiveXamlReader = !Clipboard.UseLegacyDangerousClipboardDeserializationMode(); - xamlObject = XamlReader.Load(xamlEntryPart.GetStream(), parserContext, useRestrictiveXamlReader); + xamlObject = XamlReader.Load(xamlEntryPart.GetSeekableStream(), parserContext, useRestrictiveXamlReader: true); // Remove the temporary uri from the PackageStore PackageStore.RemovePackage(packageUri); @@ -484,7 +484,7 @@ private void CreateImagePart(PackagePart sourcePart, BitmapSource imageSource, s bitmapEncoder.Frames.Add(BitmapFrame.Create(imageSource)); // Save encoded image data into the image part in the package - Stream imageStream = imagePart.GetStream(); + Stream imageStream = imagePart.GetSeekableStream(); using (imageStream) { bitmapEncoder.Save(imageStream); @@ -692,7 +692,7 @@ internal Stream CreateXamlStream() PackagePart part = this.CreateWpfEntryPart(); // Return a stream opened for writing an image data - return part.GetStream(); + return part.GetSeekableStream(); } internal Stream CreateImageStream(int imageCount, string contentType, out string imagePartUriString) @@ -714,7 +714,7 @@ internal Stream CreateImageStream(int imageCount, string contentType, out string imagePartUriString = GetImageReference(imagePartUriString); // Return a stream opened for writing an image data - return imagePart.GetStream(); + return imagePart.GetSeekableStream(); } internal Stream GetImageStream(string imageSourceString) @@ -723,7 +723,7 @@ internal Stream GetImageStream(string imageSourceString) imageSourceString = imageSourceString.Substring(1); // cut the leading dot out Uri imagePartUri = new Uri(XamlPayloadDirectory + imageSourceString, UriKind.Relative); PackagePart imagePart = _package.GetPart(imagePartUri); - return imagePart.GetStream(); + return imagePart.GetSeekableStream(); } // ------------------------------------------------------------- diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XamlToRtfWriter.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XamlToRtfWriter.cs index c7c6447751a..f1238c48fa2 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XamlToRtfWriter.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/XamlToRtfWriter.cs @@ -13,6 +13,7 @@ using System.Globalization; using System.IO; using MS.Internal.Globalization; +using MS.Internal.Text; #if WindowsMetaFile // GetWinMetaFileBits using System.Runtime.InteropServices; @@ -2018,18 +2019,13 @@ private void WriteImage(DocumentNode documentNode) // Read the image binary data from WpfPayLoad that contains Xaml and Images. // Xaml content have the image source like as "./Image1.png" so that we can // query the image from the container of WpfPayLoad with the image source name. - Stream imageStream = _wpfPayload.GetImageStream(documentNode.FormatState.ImageSource); - - // Get image type to be added to rtf content - RtfImageFormat imageFormat = GetImageFormatFromImageSourceName(documentNode.FormatState.ImageSource); - - // Write the shape image like as "\pngblip" or "\jpegblip" rtf control. We wrap the stream that comes - // from the package because we require the stream to be seekable. - Debug.Assert(!imageStream.CanSeek); - using (var seekableStream = new MemoryStream((int)imageStream.Length)) + using (Stream imageStream = _wpfPayload.GetImageStream(documentNode.FormatState.ImageSource)) { - imageStream.CopyTo(seekableStream); - WriteShapeImage(documentNode, seekableStream, imageFormat); + // Get image type to be added to rtf content + RtfImageFormat imageFormat = GetImageFormatFromImageSourceName(documentNode.FormatState.ImageSource); + + // Write the shape image like as "\pngblip" or "\jpegblip" rtf control. + WriteShapeImage(documentNode, imageStream, imageFormat); } #if WindowsMetaFile @@ -2206,7 +2202,7 @@ private string ConvertToImageHexDataString(byte[] imageBytes) } // Return the image hex data string that is the default image data type on Rtf - return Encoding.GetEncoding(XamlRtfConverter.RtfCodePage).GetString(imageHexBytes); + return InternalEncoding.GetEncoding(XamlRtfConverter.RtfCodePage).GetString(imageHexBytes); } #endif // WindowsMetaFile @@ -2227,7 +2223,7 @@ private string ConvertToImageHexDataString(Stream imageStream) } // Return the image hex data string that is the default image data type on Rtf - return Encoding.GetEncoding(XamlRtfConverter.RtfCodePage).GetString(imageHexBytes); + return InternalEncoding.GetEncoding(XamlRtfConverter.RtfCodePage).GetString(imageHexBytes); } // Get the image type from image source name @@ -4023,7 +4019,7 @@ private static void AppendRtfUnicodeChar(StringBuilder sb, char c, int cp, ref E { if (e == null) { - e = Encoding.GetEncoding(cp); + e = InternalEncoding.GetEncoding(cp); } int cb = e.GetBytes(new char[] { c }, 0, 1, rgAnsi, 0); int cch = e.GetChars(rgAnsi, 0, cb, rgChar, 0); diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkContentElement.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkContentElement.cs index 540514dab5c..c49f4b1f165 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkContentElement.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkContentElement.cs @@ -18,7 +18,6 @@ using System.Collections; using System.Diagnostics; using System.Security; -using System.Security.Permissions; using System.Windows.Controls; using System.Windows.Diagnostics; using System.Windows.Media; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkElement.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkElement.cs index 92a399aa122..1066e2efac8 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkElement.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Generated/FrameworkElement.cs @@ -18,7 +18,6 @@ using System.Collections; using System.Diagnostics; using System.Security; -using System.Security.Permissions; using System.Windows.Controls; using System.Windows.Diagnostics; using System.Windows.Media; diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/SharedStream.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/SharedStream.cs index ab9ca967275..2664092c9a2 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/SharedStream.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/Baml2006/SharedStream.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +using System; using System.IO; using System.ComponentModel; @@ -26,7 +26,7 @@ public SharedStream(Stream baseStream) { if (baseStream == null) { - throw new ArgumentNullException("baseStream"); + throw new ArgumentNullException(nameof(baseStream)); } Initialize(baseStream, 0, baseStream.Length); @@ -42,7 +42,7 @@ public SharedStream(Stream baseStream, long offset, long length) { if (baseStream == null) { - throw new ArgumentNullException("baseStream"); + throw new ArgumentNullException(nameof(baseStream)); } Initialize(baseStream, offset, length); @@ -57,12 +57,12 @@ private void Initialize(Stream baseStream, long offset, long length) if (offset < 0) { - throw new ArgumentOutOfRangeException("offset"); + throw new ArgumentOutOfRangeException(nameof(offset)); } if (length < 0) { - throw new ArgumentOutOfRangeException("length"); + throw new ArgumentOutOfRangeException(nameof(length)); } SharedStream subStream = baseStream as SharedStream; @@ -146,7 +146,7 @@ public override long Position { if (value < 0 || value >= _length) { - throw new ArgumentOutOfRangeException("value", value, string.Empty); + throw new ArgumentOutOfRangeException(nameof(value), value, string.Empty); } _position = value; @@ -178,17 +178,17 @@ public override int Read(byte[] buffer, int offset, int count) { if (buffer == null) { - throw new ArgumentNullException("buffer"); + throw new ArgumentNullException(nameof(buffer)); } if (offset < 0 || offset >= buffer.Length) { - throw new ArgumentOutOfRangeException("offset"); + throw new ArgumentOutOfRangeException(nameof(offset)); } if ((offset + count) > buffer.Length) { - throw new ArgumentOutOfRangeException("count"); + throw new ArgumentOutOfRangeException(nameof(count)); } CheckDisposed(); @@ -213,15 +213,15 @@ public override void Write(byte[] buffer, int offset, int count) #else if(buffer == null) { - throw new ArgumentNullException("buffer"); + throw new ArgumentNullException(nameof(buffer)); } if(offset < 0 || offset >= buffer.Length) { - throw new ArgumentOutOfRangeException("offset"); + throw new ArgumentOutOfRangeException(nameof(offset)); } if((offset + count) > buffer.Length) { - throw new ArgumentOutOfRangeException("count"); + throw new ArgumentOutOfRangeException(nameof(count)); } CheckDisposed(); @@ -254,12 +254,12 @@ public override long Seek(long offset, SeekOrigin origin) break; default: - throw new InvalidEnumArgumentException("origin", (int)origin, typeof(SeekOrigin)); + throw new InvalidEnumArgumentException(nameof(origin), (int)origin, typeof(SeekOrigin)); } if (newPosition < 0 || newPosition >= _length) { - throw new ArgumentOutOfRangeException("offset", offset, string.Empty); + throw new ArgumentOutOfRangeException(nameof(offset), offset, string.Empty); } CheckDisposed(); diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReader.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReader.cs index b2d45b4b1fa..0e76c83d435 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReader.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlReader.cs @@ -79,7 +79,7 @@ public static object Load(Stream stream) { if (stream == null) { - throw new ArgumentNullException("stream"); + throw new ArgumentNullException(nameof(stream)); } return Load(stream, null); @@ -95,7 +95,7 @@ public static object Load(XmlReader reader) { if (reader == null) { - throw new ArgumentNullException("reader"); + throw new ArgumentNullException(nameof(reader)); } return Load(reader, null, XamlParseMode.Synchronous); @@ -112,7 +112,7 @@ public static object Load(Stream stream, ParserContext parserContext) { if (stream == null) { - throw new ArgumentNullException("stream"); + throw new ArgumentNullException(nameof(stream)); } if (parserContext == null) { @@ -134,9 +134,9 @@ public static object Load(Stream stream, ParserContext parserContext) /// public object LoadAsync(Stream stream) { - if (null == stream) + if (stream == null) { - throw new ArgumentNullException("stream"); + throw new ArgumentNullException(nameof(stream)); } _stream = stream; @@ -161,9 +161,9 @@ public object LoadAsync(Stream stream) /// public object LoadAsync(XmlReader reader) { - if (null == reader) + if (reader == null) { - throw new ArgumentNullException("reader"); + throw new ArgumentNullException(nameof(reader)); } return LoadAsync(reader, null); @@ -182,9 +182,9 @@ public object LoadAsync(XmlReader reader) /// public object LoadAsync(Stream stream, ParserContext parserContext) { - if (null == stream) + if (stream == null) { - throw new ArgumentNullException("stream"); + throw new ArgumentNullException(nameof(stream)); } _stream = stream; @@ -220,7 +220,7 @@ private object LoadAsync(XmlReader reader, ParserContext parserContext) { if (reader == null) { - throw new ArgumentNullException("reader"); + throw new ArgumentNullException(nameof(reader)); } if (parserContext == null) @@ -682,7 +682,7 @@ internal static object Load(Stream stream, ParserContext parserContext, bool use { if (stream == null) { - throw new ArgumentNullException("stream"); + throw new ArgumentNullException(nameof(stream)); } if (parserContext == null) { @@ -705,7 +705,7 @@ internal static object Load(XmlReader reader, bool useRestrictiveXamlReader = fa { if (reader == null) { - throw new ArgumentNullException("reader"); + throw new ArgumentNullException(nameof(reader)); } return Load(reader, null, XamlParseMode.Synchronous, useRestrictiveXamlReader); @@ -879,7 +879,7 @@ public static object Load(System.Xaml.XamlReader reader) { if (reader == null) { - throw new ArgumentNullException("reader"); + throw new ArgumentNullException(nameof(reader)); } object root = null; try diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlWriter.cs b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlWriter.cs index 58b1d50346e..4ddff384efd 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlWriter.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlWriter.cs @@ -54,7 +54,7 @@ public static string Save(object obj) // Validate input arguments if (obj == null) { - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); } // Create TextWriter @@ -92,11 +92,11 @@ public static void Save(object obj, TextWriter writer) // Validate input arguments if (obj == null) { - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); } if (writer == null) { - throw new ArgumentNullException("writer"); + throw new ArgumentNullException(nameof(writer)); } // Create XmlTextWriter @@ -123,11 +123,11 @@ public static void Save(object obj, Stream stream) // Validate input arguments if (obj == null) { - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); } if (stream == null) { - throw new ArgumentNullException("stream"); + throw new ArgumentNullException(nameof(stream)); } // Create XmlTextWriter @@ -156,11 +156,11 @@ public static void Save(object obj, XmlWriter xmlWriter) // Validate input arguments if (obj == null) { - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); } if (xmlWriter == null) { - throw new ArgumentNullException("xmlWriter"); + throw new ArgumentNullException(nameof(xmlWriter)); } try @@ -192,11 +192,11 @@ public static void Save(object obj, XamlDesignerSerializationManager manager) // Validate input arguments if (obj == null) { - throw new ArgumentNullException("obj"); + throw new ArgumentNullException(nameof(obj)); } if (manager == null) { - throw new ArgumentNullException("manager"); + throw new ArgumentNullException(nameof(manager)); } MarkupWriter.SaveAsXml(manager.XmlWriter, obj, manager); diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/ILLinkTrim.xml b/src/Microsoft.DotNet.Wpf/src/ReachFramework/ILLinkTrim.xml new file mode 100644 index 00000000000..b5957362218 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/ILLinkTrim.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsDocument.cs b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsDocument.cs index 3eca3c41df0..8b19df2ba8f 100644 --- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsDocument.cs +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsDocument.cs @@ -325,26 +325,28 @@ public ReadOnlyCollection Signatures foreach( PackagePart part in xmlPartList ) { - Stream stream = part.GetStream(FileMode.Open, FileAccess.Read ); - // - // An empty stream contains not version extensibility thus is valid - // We do create empty parts for print tickets - // - if( stream.Length == 0 ) - continue; - try + using (Stream stream = part.GetStream(FileMode.Open, FileAccess.Read)) { - if( StreamContainsVersionExtensiblity(stream) ) + // + // An empty stream contains not version extensibility thus is valid + // We do create empty parts for print tickets + // + if (stream.Length == 0) + continue; + try + { + if (StreamContainsVersionExtensiblity(stream)) + { + isSignable = false; + break; + } + } + catch (XmlException) { isSignable = false; break; } } - catch( XmlException ) - { - isSignable = false; - break; - } } return isSignable; } diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsFixedDocumentReaderWriter.cs b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsFixedDocumentReaderWriter.cs index 4396796c292..33983f1afb8 100644 --- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsFixedDocumentReaderWriter.cs +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsFixedDocumentReaderWriter.cs @@ -950,23 +950,25 @@ IList linkTargetStream void ParsePages() { - Stream stream = _metroPart.GetStream(FileMode.Open); - // - // If the stream is empty there are no pages to parse - // - if( stream.Length > 0 ) + using (Stream stream = _metroPart.GetStream(FileMode.Open)) { - XmlTextReader reader = new XmlTextReader(stream); - - while( reader.Read() ) + // + // If the stream is empty there are no pages to parse + // + if (stream.Length > 0) { - if( reader.NodeType == XmlNodeType.Element && reader.Name == XpsS0Markup.PageContent) + XmlTextReader reader = new XmlTextReader(stream); + + while (reader.Read()) { - string attribute = reader.GetAttribute(XmlTags.Source); - if( attribute != null ) + if (reader.NodeType == XmlNodeType.Element && reader.Name == XpsS0Markup.PageContent) { - Uri relativeUri = new Uri(attribute, UriKind.Relative); - AddPageToCache(PackUriHelper.ResolvePartUri( Uri, relativeUri)); + string attribute = reader.GetAttribute(XmlTags.Source); + if (attribute != null) + { + Uri relativeUri = new Uri(attribute, UriKind.Relative); + AddPageToCache(PackUriHelper.ResolvePartUri(Uri, relativeUri)); + } } } } @@ -1074,14 +1076,16 @@ IList linkTargetStream Collection sigDefCollection ) { - XmlTextReader reader = new XmlTextReader( sigDefPart.GetStream(FileMode.Open) ); - while( reader.Read() ) + using (XmlTextReader reader = new XmlTextReader(sigDefPart.GetStream(FileMode.Open))) { - if( reader.NodeType == XmlNodeType.Element && - reader.Name == XpsS0Markup.SignatureDefinitions - ) + while (reader.Read()) { - ParseSignatureDefinitions( reader, sigDefCollection ); + if (reader.NodeType == XmlNodeType.Element && + reader.Name == XpsS0Markup.SignatureDefinitions + ) + { + ParseSignatureDefinitions(reader, sigDefCollection); + } } } } @@ -1124,21 +1128,20 @@ Collection sigDefCollection { sigDefPart = CurrentXpsManager.AddSignatureDefinitionPart( _metroPart ); } - Stream stream = sigDefPart.GetStream(FileMode.Create); - XmlTextWriter writer = new XmlTextWriter( - stream, - System.Text.Encoding.UTF8 - ); - writer.WriteStartDocument(); - writer.WriteStartElement( XpsS0Markup.SignatureDefinitions, - XpsS0Markup.SignatureDefinitionNamespace); - foreach( XpsSignatureDefinition sigDef in _signatureDefinitions ) + + using (Stream stream = sigDefPart.GetStream(FileMode.Create)) + using (XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.UTF8)) { - sigDef.WriteXML( writer ); + writer.WriteStartDocument(); + writer.WriteStartElement(XpsS0Markup.SignatureDefinitions, + XpsS0Markup.SignatureDefinitionNamespace); + foreach (XpsSignatureDefinition sigDef in _signatureDefinitions) + { + sigDef.WriteXML(writer); + } + writer.WriteEndElement(); } - writer.WriteEndElement(); - writer.Close(); - stream.Close(); + _sigCollectionDirty = false; } diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsFixedDocumentSequenceReaderWriter.cs b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsFixedDocumentSequenceReaderWriter.cs index 272c2738042..0786fe03150 100644 --- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsFixedDocumentSequenceReaderWriter.cs +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/Packaging/XpsFixedDocumentSequenceReaderWriter.cs @@ -546,28 +546,31 @@ Uri partUri void ParseDocuments() { - Stream stream = _metroPart.GetStream(FileMode.Open); - // - // If the stream is empty there are no documents to parse - // - if( stream.Length > 0 ) - { - XmlTextReader reader = new XmlTextReader(stream); - - while( reader.Read() ) - { - if( reader.NodeType == XmlNodeType.Element && reader.Name == XpsS0Markup.DocumentReference) - { - string attribute = reader.GetAttribute(XmlTags.Source); - if( attribute != null ) - { - Uri relativeUri = new Uri(attribute, UriKind.Relative); - //This routine properly adds DocumentReaderWriter to the _documentCache - AddDocumentToCache(PackUriHelper.ResolvePartUri( Uri, relativeUri)); - } - } - } - } + using (Stream stream = _metroPart.GetStream(FileMode.Open)) + { + // + // If the stream is empty there are no documents to parse + // + if (stream.Length > 0) + { + XmlTextReader reader = new XmlTextReader(stream); + + while (reader.Read()) + { + if (reader.NodeType == XmlNodeType.Element && reader.Name == XpsS0Markup.DocumentReference) + { + string attribute = reader.GetAttribute(XmlTags.Source); + if (attribute != null) + { + Uri relativeUri = new Uri(attribute, UriKind.Relative); + //This routine properly adds DocumentReaderWriter to the _documentCache + AddDocumentToCache(PackUriHelper.ResolvePartUri(Uri, relativeUri)); + } + } + } + } + } + } /// diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/PrintConfig/PTConverter.cs b/src/Microsoft.DotNet.Wpf/src/ReachFramework/PrintConfig/PTConverter.cs index b1508fd00c0..65bc696c792 100644 --- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/PrintConfig/PTConverter.cs +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/PrintConfig/PTConverter.cs @@ -80,14 +80,14 @@ public PrintTicketConverter(string deviceName, int clientPrintSchemaVersion) // Check input argument if (deviceName == null) { - throw new ArgumentNullException("deviceName"); + throw new ArgumentNullException(nameof(deviceName)); } // Check if we can support the schema version client has requested if ((clientPrintSchemaVersion > MaxPrintSchemaVersion) || (clientPrintSchemaVersion <= 0)) { - throw new ArgumentOutOfRangeException("clientPrintSchemaVersion"); + throw new ArgumentOutOfRangeException(nameof(clientPrintSchemaVersion)); } // Instantiate the provider object this converter instance will use. @@ -254,7 +254,7 @@ internal static PrintTicket InternalConvertDevModeToPrintTicket(PTProviderBase p // validate devMode parameter if (devMode == null) { - throw new ArgumentNullException("devMode"); + throw new ArgumentNullException(nameof(devMode)); } // validate sope parameter @@ -262,7 +262,7 @@ internal static PrintTicket InternalConvertDevModeToPrintTicket(PTProviderBase p (scope != PrintTicketScope.DocumentScope) && (scope != PrintTicketScope.JobScope)) { - throw new ArgumentOutOfRangeException("scope"); + throw new ArgumentOutOfRangeException(nameof(scope)); } MemoryStream ptStream = provider.ConvertDevModeToPrintTicket(devMode, scope); @@ -275,25 +275,25 @@ internal static byte[] InternalConvertPrintTicketToDevMode(PTProviderBase provid BaseDevModeType baseType, PrintTicketScope scope) { - // Input PrinTicket can't be null + // Input PrinTicket can't be null. if (printTicket == null) { - throw new ArgumentNullException("printTicket"); + throw new ArgumentNullException(nameof(printTicket)); } - // validate the base type value + // Validate the base type value. if ((baseType != BaseDevModeType.UserDefault) && (baseType != BaseDevModeType.PrinterDefault)) { - throw new ArgumentOutOfRangeException("baseType"); + throw new ArgumentOutOfRangeException(nameof(baseType)); } - // validate scope value + // Validate scope value. if ((scope != PrintTicketScope.PageScope) && (scope != PrintTicketScope.DocumentScope) && (scope != PrintTicketScope.JobScope)) { - throw new ArgumentOutOfRangeException("scope"); + throw new ArgumentOutOfRangeException(nameof(scope)); } MemoryStream ptStream = printTicket.GetXmlStream(); diff --git a/src/Microsoft.DotNet.Wpf/src/ReachFramework/ReachFramework.csproj b/src/Microsoft.DotNet.Wpf/src/ReachFramework/ReachFramework.csproj index c56f253f181..c2301de6145 100644 --- a/src/Microsoft.DotNet.Wpf/src/ReachFramework/ReachFramework.csproj +++ b/src/Microsoft.DotNet.Wpf/src/ReachFramework/ReachFramework.csproj @@ -21,6 +21,29 @@ System.Printing.resources System.Printing.resources + + + + false + $(AssemblyName).xml + diff --git a/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/IO/Packaging/PackagePartExtensions.cs b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/IO/Packaging/PackagePartExtensions.cs new file mode 100644 index 00000000000..fa371aa3589 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/IO/Packaging/PackagePartExtensions.cs @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using MS.Internal.WindowsBase; +using System.IO; +using System.IO.Packaging; + +namespace MS.Internal.IO.Packaging +{ + /// + /// Extensions to provide wrappers for functionality that no longer exists in System.IO.Packaging.PackagePart + /// + [FriendAccessAllowed] + internal static class PackagePartExtensions + { + /// + /// Gets a seekable stream from the PackagePart. + /// for details. + /// + /// + /// A seekable stream representing the data in the PackagePart. + internal static Stream GetSeekableStream(this PackagePart packPart) + { + return GetSeekableStream(packPart, FileMode.OpenOrCreate, packPart.Package.FileOpenAccess); + } + + /// + /// Gets a seekable stream from the PackagePart. + /// for details. + /// + /// + /// The FileMode to open the PackagePart + /// A seekable stream representing the data in the PackagePart. + internal static Stream GetSeekableStream(this PackagePart packPart, FileMode mode) + { + return GetSeekableStream(packPart, mode, packPart.Package.FileOpenAccess); + } + + /// + /// Gets a seekable stream from the PackagePart. + /// + /// + /// In .NET Core 3.0, System.IO.Packaging was removed, in part, from WPF. WPF now uses the implementation + /// contained in System.IO.Packaging.dll. This implementation has distinct differences from the .NET Framework + /// WPF implementation. One such difference is that the returned by calls + /// when the is opened read-only is not a seekable stream. This breaks several assumptions in WPF + /// and causes crashes when various parts of the code-base call into or . + /// + /// To fix this, we read the entire into a , allowing callers to fully seek the stream. + /// This is, generally, what would be the case in .NET Framework. + /// + /// Note that if the stream returned is seekable (the was opened write or read-write) then we just pass the resulting + /// stream back as we're already guaranteed it meets our needs. + /// + /// + /// The FileMode to open the PackagePart + /// The FileAccess used to open the PackagePart + /// A seekable stream representing the data in the PackagePart. + internal static Stream GetSeekableStream(this PackagePart packPart, FileMode mode, FileAccess access) + { + var packStream = packPart.GetStream(mode, access); + + // If the stream returned is seekable it meets all requirements and can be used directly. + if (packStream.CanSeek) + { + return packStream; + } + + // Non-seekable streams need to be copied out into memory so they are seekable. + using (packStream) + { + var seekableStream = new MemoryStream((int)packStream.Length); + + packStream.CopyTo(seekableStream); + + // Reset the stream to the beginning. If this is not done, attempts to read the stream + // from the current position will fail. E.G. XAML/XML parsing. + seekableStream.Position = 0; + + return seekableStream; + } + } + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/IO/Packaging/PackagingUtilities.cs b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/IO/Packaging/PackagingUtilities.cs index d030be45606..d7e5bad4189 100644 --- a/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/IO/Packaging/PackagingUtilities.cs +++ b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/IO/Packaging/PackagingUtilities.cs @@ -626,7 +626,7 @@ protected override void Dispose(bool disposing) //------------------------------------------------------ private string _path; private ReliableIsolatedStorageFileFolder _folder; - private bool _disposed; + private bool _disposed; } @@ -820,9 +820,9 @@ void CheckDisposed() // //------------------------------------------------------ private static IsolatedStorageFile _file; - private static bool _userHasProfile; - private int _refCount; // number of outstanding "streams" - private bool _disposed; + private static bool _userHasProfile; + private int _refCount; // number of outstanding "streams" + private bool _disposed; } //------------------------------------------------------ @@ -835,7 +835,7 @@ void CheckDisposed() /// /// See PS 1468964 for details. private static Object _isoStoreSyncObject = new Object(); - private static Object _isolatedStorageFileLock = new Object(); + private static Object _isolatedStorageFileLock = new Object(); private static ReliableIsolatedStorageFileFolder _defaultFile; private const string XmlNamespace = "xmlns"; private const string _encodingAttribute = "encoding"; diff --git a/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/Text/InternalEncoding.cs b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/Text/InternalEncoding.cs new file mode 100644 index 00000000000..02dc17dc181 --- /dev/null +++ b/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/Text/InternalEncoding.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text; + +namespace MS.Internal.Text +{ + /// + /// We use encodings that are not provided by default in core. + /// This class makes sure that we register extra providers that are required before use. + /// + internal static class InternalEncoding + { + + static InternalEncoding() + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + } + + internal static Encoding GetEncoding(int codepage) + { + return Encoding.GetEncoding(codepage); + } + + internal static byte[] Convert(System.Text.Encoding srcEncoding, System.Text.Encoding dstEncoding, byte[] bytes) + { + return Encoding.Convert(srcEncoding, dstEncoding, bytes); + } + } +} diff --git a/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/Ink/KnownIds.cs b/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/Ink/KnownIds.cs index b05962985a7..ace6cb79ff1 100644 --- a/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/Ink/KnownIds.cs +++ b/src/Microsoft.DotNet.Wpf/src/Shared/System/Windows/Ink/KnownIds.cs @@ -296,7 +296,6 @@ internal static class KnownIds internal static string ConvertToString (Guid id) { - // Assert Reflection permissions shouldn't be required since we are only accessing public members if (null == PublicMemberInfo) { PublicMemberInfo = typeof(KnownIds).FindMembers(System.Reflection.MemberTypes.Field, diff --git a/src/Microsoft.DotNet.Wpf/src/System.Xaml/System.Xaml.csproj b/src/Microsoft.DotNet.Wpf/src/System.Xaml/System.Xaml.csproj index 3ccca354fd9..cf991d26a39 100644 --- a/src/Microsoft.DotNet.Wpf/src/System.Xaml/System.Xaml.csproj +++ b/src/Microsoft.DotNet.Wpf/src/System.Xaml/System.Xaml.csproj @@ -121,6 +121,7 @@ + diff --git a/src/Microsoft.DotNet.Wpf/src/System.Xaml/ref/System.Xaml-ref.csproj b/src/Microsoft.DotNet.Wpf/src/System.Xaml/ref/System.Xaml-ref.csproj index b068208c3e1..637e4ca0dc2 100644 --- a/src/Microsoft.DotNet.Wpf/src/System.Xaml/ref/System.Xaml-ref.csproj +++ b/src/Microsoft.DotNet.Wpf/src/System.Xaml/ref/System.Xaml-ref.csproj @@ -50,5 +50,6 @@ + diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/Automation.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/Automation.cs index 89a02dfce20..8bd06637cf8 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/Automation.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/Automation.cs @@ -71,11 +71,6 @@ public static class Automation /// element to compare /// true if el1 and el2 refer to the same underlying UI /// Both el1 and el1 must be non-null - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static bool Compare(AutomationElement el1, AutomationElement el2) { return Misc.Compare(el1, el2); @@ -89,11 +84,6 @@ public static bool Compare(AutomationElement el1, AutomationElement el2) /// true if runtimeId1 and runtimeId2 refer to the same underlying UI /// Both runtimeId1 and runtimeId2 must be non-null. Can be /// used to compare RuntimeIds from elements. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static bool Compare(int[] runtimeId1, int[] runtimeId2) { return Misc.Compare(runtimeId1, runtimeId2); @@ -138,11 +128,6 @@ public static string PatternName( AutomationPattern pattern ) /// Element on which to listen for control pattern or custom events. /// Specifies whether to listen to property changes events on the specified element, and/or its ancestors and children. /// Delegate to call when the specified event occurs. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static void AddAutomationEventHandler( AutomationEvent eventId, AutomationElement element, @@ -215,11 +200,6 @@ AutomationEventHandler eventHandler /// a UIAccess or custom event identifier. /// Element to remove listener for /// The handler object that was passed to AddEventListener - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static void RemoveAutomationEventHandler( AutomationEvent eventId, AutomationElement element, @@ -243,11 +223,6 @@ AutomationEventHandler eventHandler /// Specifies whether to listen to property changes events on the specified element, and/or its ancestors and children. /// Callback object to call when a specified property change occurs. /// Params array of properties to listen for changes in. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static void AddAutomationPropertyChangedEventHandler( AutomationElement element, // reference element for listening to the event TreeScope scope, // scope to listen to @@ -281,11 +256,6 @@ public static void AddAutomationPropertyChangedEventHandler( /// /// Element to remove listener for /// The handler object that was passed to AutomationPropertyChangedEventHandler - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static void RemoveAutomationPropertyChangedEventHandler( AutomationElement element, // reference element being listened to AutomationPropertyChangedEventHandler eventHandler // callback object (used as cookie here) @@ -304,11 +274,6 @@ public static void RemoveAutomationPropertyChangedEventHandler( /// Element on which to listen for structure change events. /// Specifies whether to listen to property changes events on the specified element, and/or its ancestors and children. /// Delegate to call when a structure change event occurs. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static void AddStructureChangedEventHandler(AutomationElement element, TreeScope scope, StructureChangedEventHandler eventHandler) { Misc.ValidateArgumentNonNull(element, "element"); @@ -325,11 +290,6 @@ public static void AddStructureChangedEventHandler(AutomationElement element, Tr /// /// Element to remove listener for /// The handler object that was passed to AddStructureChangedListener - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static void RemoveStructureChangedEventHandler(AutomationElement element, StructureChangedEventHandler eventHandler) { Misc.ValidateArgumentNonNull(element, "element"); @@ -343,11 +303,6 @@ public static void RemoveStructureChangedEventHandler(AutomationElement element, /// Called by a client to add a listener for focus changed events. /// /// Delegate to call when a focus change event occurs. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static void AddAutomationFocusChangedEventHandler( AutomationFocusChangedEventHandler eventHandler ) @@ -366,11 +321,6 @@ AutomationFocusChangedEventHandler eventHandler /// Called by a client to remove a listener for focus changed events. /// /// The handler object that was passed to AddAutomationFocusChangedListener - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static void RemoveAutomationFocusChangedEventHandler( AutomationFocusChangedEventHandler eventHandler ) @@ -384,11 +334,6 @@ AutomationFocusChangedEventHandler eventHandler /// /// Called by a client to remove all listeners that the client has added. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static void RemoveAllEventHandlers() { // Remove the client-side listener for for this event diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/AutomationElement.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/AutomationElement.cs index 365d15830e5..2ddf30f61c9 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/AutomationElement.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/AutomationElement.cs @@ -370,11 +370,6 @@ public override int GetHashCode() /// These identifies are only guaranteed to be unique on a given desktop. /// Identifiers may be recycled over time. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int[] GetRuntimeId() { if (_runtimeId != null) @@ -408,11 +403,6 @@ public int[] GetRuntimeId() /// /// point in screen coordinates /// element at specified point - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static AutomationElement FromPoint(Point pt) { return DrillForPointOrFocus(true, pt, CacheRequest.CurrentUiaCacheRequest); @@ -423,11 +413,6 @@ public static AutomationElement FromPoint(Point pt) /// /// Handle of window to get element for /// element representing root node of specified window - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static AutomationElement FromHandle(IntPtr hwnd) { Misc.ValidateArgument(hwnd != IntPtr.Zero, SRID.HwndMustBeNonNULL); @@ -481,11 +466,6 @@ public static AutomationElement FromLocalProvider(IRawElementProviderSimple loca /// a cross-process performance hit. To access values in this AutomationElement's /// cache, use GetCachedPropertyValue instead. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public object GetCurrentPropertyValue(AutomationProperty property) { return GetCurrentPropertyValue(property, false); @@ -504,11 +484,6 @@ public object GetCurrentPropertyValue(AutomationProperty property) /// a cross-process performance hit. To access values in this AutomationElement's /// cache, use GetCachedPropertyValue instead. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public object GetCurrentPropertyValue(AutomationProperty property, bool ignoreDefaultValue) { Misc.ValidateArgumentNonNull(property, "property"); @@ -564,11 +539,6 @@ public object GetCurrentPropertyValue(AutomationProperty property, bool ignoreDe /// a cross-process performance hit. To access patterns in this AutomationElement's /// cache, use GetCachedPattern instead. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public object GetCurrentPattern(AutomationPattern pattern) { object retObject; @@ -596,11 +566,6 @@ public object GetCurrentPattern(AutomationPattern pattern) /// a cross-process performance hit. To access patterns in this AutomationElement's /// cache, use GetCachedPattern instead. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool TryGetCurrentPattern(AutomationPattern pattern, out object patternObject) { patternObject = null; @@ -645,11 +610,6 @@ public bool TryGetCurrentPattern(AutomationPattern pattern, out object patternOb /// support the AutomationElement.NameProperty, calling GetCachedPropertyValue /// for that property will return an empty string. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public object GetCachedPropertyValue(AutomationProperty property) { return GetCachedPropertyValue(property, false); @@ -674,11 +634,6 @@ public object GetCachedPropertyValue(AutomationProperty property) /// When ignoreDefaultValue is true, the value AutomationElement.NotSupported will /// be returned instead. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public object GetCachedPropertyValue(AutomationProperty property, bool ignoreDefaultValue) { Misc.ValidateArgumentNonNull(property, "property"); @@ -707,11 +662,6 @@ public object GetCachedPropertyValue(AutomationProperty property, bool ignoreDef /// /// This API gets the pattern from the cache. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public object GetCachedPattern(AutomationPattern pattern) { object patternObject; @@ -731,11 +681,6 @@ public object GetCachedPattern(AutomationPattern pattern) /// /// This API gets the pattern from the cache. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool TryGetCachedPattern(AutomationPattern pattern, out object patternObject) { patternObject = null; @@ -843,11 +788,6 @@ public AutomationElementCollection FindAll(TreeScope scope, Condition condition) /// currently support or which have null or empty values. Use GetPropertyValue to determine /// whether a property is currently supported and to determine what its current value is. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationProperty [ ] GetSupportedProperties() { CheckElement(); @@ -878,11 +818,6 @@ public AutomationProperty [ ] GetSupportedProperties() /// Get the interfaces that this object supports /// /// An array of AutomationPatterns that represent the supported interfaces - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationPattern [ ] GetSupportedPatterns() { CheckElement(); @@ -903,11 +838,6 @@ public AutomationPattern [ ] GetSupportedPatterns() /// /// Request to set focus to this element /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void SetFocus() { CheckElement(); @@ -929,11 +859,6 @@ public void SetFocus() /// /// A point that can be used ba a client to click on this LogicalElement /// true if there is point that is clickable - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool TryGetClickablePoint( out Point pt ) { // initialize point here so if we return false its initialized @@ -983,11 +908,6 @@ public bool TryGetClickablePoint( out Point pt ) /// /// A point that can be used by a client to click on this LogicalElement /// If there is not clickable point for this element - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public Point GetClickablePoint() { Point pt; @@ -1011,11 +931,6 @@ public Point GetClickablePoint() /// Get root element for current desktop /// /// root element for current desktop - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static AutomationElement RootElement { get @@ -1035,11 +950,6 @@ public static AutomationElement RootElement /// /// Return the currently focused element /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public static AutomationElement FocusedElement { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/DockPattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/DockPattern.cs index 058ef2b24fe..3ee347226e5 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/DockPattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/DockPattern.cs @@ -65,11 +65,6 @@ private DockPattern(AutomationElement el, SafePatternHandle hPattern, bool cache /// /// Moves the window to be docked at the requested location. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void SetDockPosition( DockPosition dockPosition ) { UiaCoreApi.DockPattern_SetDockPosition(_hPattern, dockPosition); @@ -200,11 +195,6 @@ internal DockPatternInformation(AutomationElement el, bool useCache) #region Public Properties /// Returns whether the DockPosition is Top, Left, Bottom, Right, Fill, or None. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public DockPosition DockPosition { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ExpandCollapsePattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ExpandCollapsePattern.cs index 5c33f8e1c04..1e0dd2b7039 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ExpandCollapsePattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ExpandCollapsePattern.cs @@ -63,11 +63,6 @@ private ExpandCollapsePattern(AutomationElement el, SafePatternHandle hPattern, /// /// Blocking method that returns after the element has been expanded /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void Expand() { UiaCoreApi.ExpandCollapsePattern_Expand(_hPattern); @@ -76,11 +71,6 @@ public void Expand() /// /// Blocking method that returns after the element has been collapsed /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void Collapse() { UiaCoreApi.ExpandCollapsePattern_Collapse(_hPattern); @@ -220,11 +210,6 @@ internal ExpandCollapsePatternInformation( AutomationElement el, bool useCache ) #region Public Properties ///indicates an element's current Collapsed or Expanded state - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public ExpandCollapseState ExpandCollapseState { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/GridItemPattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/GridItemPattern.cs index b1f3f215671..ec6c25af7db 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/GridItemPattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/GridItemPattern.cs @@ -213,11 +213,6 @@ internal GridItemPatternInformation(AutomationElement el, bool useCache) /// /// the row number of the element. This is zero based. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int Row { get @@ -229,11 +224,6 @@ public int Row /// /// the column number of the element. This is zero based. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int Column { get @@ -246,11 +236,6 @@ public int Column /// count of how many rows the element spans /// -- non merged cells should always return 1 /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int RowSpan { get @@ -263,11 +248,6 @@ public int RowSpan /// count of how many columns the element spans /// -- non merged cells should always return 1 /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int ColumnSpan { get @@ -279,11 +259,6 @@ public int ColumnSpan /// /// The logical element that supports the GripPattern for this Item /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationElement ContainingGrid { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/GridPattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/GridPattern.cs index 6833926b589..3f9741cab1c 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/GridPattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/GridPattern.cs @@ -68,11 +68,6 @@ internal GridPattern(AutomationElement el, SafePatternHandle hPattern, bool cach /// /// Row of item to get /// Column of item to get - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationElement GetItem(int row, int column) { SafeNodeHandle hNode = UiaCoreApi.GridPattern_GetItem(_hPattern, row, column); @@ -214,11 +209,6 @@ internal GridPatternInformation(AutomationElement el, bool useCache) /// /// number of rows in the grid /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int RowCount { get @@ -230,11 +220,6 @@ public int RowCount /// /// number of columns in the grid /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int ColumnCount { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/InvokePattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/InvokePattern.cs index fcf2b00ec39..0fee765f0fd 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/InvokePattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/InvokePattern.cs @@ -74,11 +74,6 @@ private InvokePattern(AutomationElement el, SafePatternHandle hPattern) /// There is no way to determine what happened, when it happend, or whether /// anything happened at all. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void Invoke() { UiaCoreApi.InvokePattern_Invoke(_hPattern); diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/MultipleViewPattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/MultipleViewPattern.cs index a8d6197d63b..2e95afd4081 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/MultipleViewPattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/MultipleViewPattern.cs @@ -71,11 +71,6 @@ private MultipleViewPattern(AutomationElement el, SafePatternHandle hPattern, bo /// be the same across instances. /// /// Return a localized, human readable string in the application's current UI language. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public string GetViewName( int viewId ) { return UiaCoreApi.MultipleViewPattern_GetViewName(_hPattern, viewId); @@ -84,11 +79,6 @@ public string GetViewName( int viewId ) /// /// Change the current view using an ID returned from GetSupportedViews() /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void SetCurrentView( int viewId ) { UiaCoreApi.MultipleViewPattern_SetCurrentView(_hPattern, viewId); @@ -226,11 +216,6 @@ internal MultipleViewPatternInformation(AutomationElement el, bool useCache) #region Public Properties /// The view ID corresponding to the control's current state. This ID is control-specific - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int CurrentView { get @@ -240,11 +225,6 @@ public int CurrentView } /// Returns an array of ints representing the full set of views available in this control. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int [] GetSupportedViews() { return (int [])_el.GetPatternPropertyValue(SupportedViewsProperty, _useCache); diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/RangeValuePattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/RangeValuePattern.cs index 745899e18a3..84a5e02754f 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/RangeValuePattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/RangeValuePattern.cs @@ -85,11 +85,6 @@ private RangeValuePattern( AutomationElement el, SafePatternHandle hPattern, boo /// Request to set the value that this UI element is representing /// /// Value to set the UI to, as a double - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void SetValue(double value) { // Test the Enabled state prior to the more general Read-Only state. @@ -241,11 +236,6 @@ internal RangeValuePatternInformation(AutomationElement el, bool useCache) #region Public Properties ///Value of a value control - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public double Value { get @@ -276,11 +266,6 @@ public double Value ///Indicates that the value can only be read, not modified. ///returns True if the control is read-only - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool IsReadOnly { get @@ -290,11 +275,6 @@ public bool IsReadOnly } ///maximum value - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public double Maximum { get @@ -324,11 +304,6 @@ public double Maximum } ///minimum value - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public double Minimum { get @@ -362,11 +337,6 @@ public double Minimum /// Gets a value to be added to or subtracted from the Value property /// when the element is moved a large distance. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public double LargeChange { get @@ -399,11 +369,6 @@ public double LargeChange /// Gets a value to be added to or subtracted from the Value property /// when the element is moved a small distance. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public double SmallChange { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ScrollPattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ScrollPattern.cs index 498197c8dc6..3ea3c16c3a9 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ScrollPattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ScrollPattern.cs @@ -87,11 +87,6 @@ private ScrollPattern(AutomationElement el, SafePatternHandle hPattern, bool cac /// vertically provides simple panning support. /// Amount to scroll by horizontally /// Amount to scroll by vertically - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void SetScrollPercent( double horizontalPercent, double verticalPercent ) { UiaCoreApi.ScrollPattern_SetScrollPercent(_hPattern, horizontalPercent, verticalPercent); @@ -105,11 +100,6 @@ public void SetScrollPercent( double horizontalPercent, double verticalPercent ) /// /// amount to scroll by horizontally /// amount to scroll by vertically - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void Scroll( ScrollAmount horizontalAmount, ScrollAmount verticalAmount ) { UiaCoreApi.ScrollPattern_Scroll(_hPattern, horizontalAmount, verticalAmount); @@ -119,11 +109,6 @@ public void Scroll( ScrollAmount horizontalAmount, ScrollAmount verticalAmount ) /// Request to scroll horizontally by the specified amount /// /// Amount to scroll by - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void ScrollHorizontal( ScrollAmount amount ) { UiaCoreApi.ScrollPattern_Scroll(_hPattern, amount, ScrollAmount.NoAmount); @@ -133,11 +118,6 @@ public void ScrollHorizontal( ScrollAmount amount ) /// Request to scroll vertically by the specified amount /// /// Amount to scroll by - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void ScrollVertical( ScrollAmount amount ) { UiaCoreApi.ScrollPattern_Scroll(_hPattern, ScrollAmount.NoAmount, amount); @@ -278,11 +258,6 @@ internal ScrollPatternInformation(AutomationElement el, bool useCache) /// /// Get the current horizontal scroll position /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public double HorizontalScrollPercent { get @@ -294,11 +269,6 @@ public double HorizontalScrollPercent /// /// Get the current vertical scroll position /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public double VerticalScrollPercent { get @@ -310,11 +280,6 @@ public double VerticalScrollPercent /// /// Equal to the horizontal percentage of the entire control that is currently viewable. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public double HorizontalViewSize { get @@ -326,11 +291,6 @@ public double HorizontalViewSize /// /// Equal to the horizontal percentage of the entire control that is currently viewable. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public double VerticalViewSize { get @@ -342,11 +302,6 @@ public double VerticalViewSize /// /// True if control can scroll horizontally /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool HorizontallyScrollable { get @@ -358,11 +313,6 @@ public bool HorizontallyScrollable /// /// True if control can scroll vertically /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool VerticallyScrollable { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/SelectionItemPattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/SelectionItemPattern.cs index d77abe3c670..e620ea87ac3 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/SelectionItemPattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/SelectionItemPattern.cs @@ -86,11 +86,6 @@ private SelectionItemPattern(AutomationElement el, SafePatternHandle hPattern, b /// Sets the current element as the selection /// This clears the selection from other elements in the container /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void Select() { UiaCoreApi.SelectionItemPattern_Select(_hPattern); @@ -98,11 +93,6 @@ public void Select() /// /// Adds current element to selection /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void AddToSelection() { UiaCoreApi.SelectionItemPattern_AddToSelection(_hPattern); @@ -111,11 +101,6 @@ public void AddToSelection() /// /// Removes current element from selection /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void RemoveFromSelection() { UiaCoreApi.SelectionItemPattern_RemoveFromSelection(_hPattern); @@ -258,11 +243,6 @@ internal SelectionItemPatternInformation(AutomationElement el, bool useCache) /// Check whether an element is selected /// /// returns true if the element is selected - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool IsSelected { get @@ -275,11 +255,6 @@ public bool IsSelected /// The logical element that supports the SelectionPattern for this Item /// /// returns an AutomationElement - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationElement SelectionContainer { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/SelectionPattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/SelectionPattern.cs index aca7299040c..28f5477b5bb 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/SelectionPattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/SelectionPattern.cs @@ -215,11 +215,6 @@ internal SelectionPatternInformation(AutomationElement el, bool useCache) /// Get the currently selected elements /// /// An AutomationElement array containing the currently selected elements - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationElement[] GetSelection() { return (AutomationElement[])_el.GetPatternPropertyValue(SelectionProperty, _useCache); @@ -240,11 +235,6 @@ public AutomationElement[] GetSelection() /// /// Boolean indicating whether the control allows more than one element to be selected /// If this is false, then the control is a single-select ccntrol - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool CanSelectMultiple { get @@ -258,11 +248,6 @@ public bool CanSelectMultiple /// /// Boolean indicating whether the control requires at least one element to be selected /// If this is false, then the control allows all elements to be unselected - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool IsSelectionRequired { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TableItemPattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TableItemPattern.cs index b6f30f75418..587b4c45ecd 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TableItemPattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TableItemPattern.cs @@ -201,11 +201,6 @@ internal TableItemPatternInformation(AutomationElement el, bool useCache) /// /// the row number of the element. This is zero based. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int Row { get @@ -217,11 +212,6 @@ public int Row /// /// the column number of the element. This is zero based. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int Column { get @@ -234,11 +224,6 @@ public int Column /// count of how many rows the element spans /// -- non merged cells should always return 1 /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int RowSpan { get @@ -251,11 +236,6 @@ public int RowSpan /// count of how many columns the element spans /// -- non merged cells should always return 1 /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int ColumnSpan { get @@ -267,11 +247,6 @@ public int ColumnSpan /// /// The logical element that supports the GripPattern for this Item /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationElement ContainingGrid { get @@ -281,22 +256,12 @@ public AutomationElement ContainingGrid } /// Collection of all row headers for this cell - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationElement[] GetRowHeaderItems() { return (AutomationElement[])_el.GetPatternPropertyValue(RowHeaderItemsProperty, _useCache); } /// Collection of all column headers for this cell - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationElement[] GetColumnHeaderItems() { return (AutomationElement[])_el.GetPatternPropertyValue(ColumnHeaderItemsProperty, _useCache); diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TablePattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TablePattern.cs index 658e1dac9d9..48688624335 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TablePattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TablePattern.cs @@ -189,22 +189,12 @@ internal TablePatternInformation(AutomationElement el, bool useCache) #region Public Properties /// Collection of all row headers for this table - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationElement[] GetRowHeaders() { return (AutomationElement[])_el.GetPatternPropertyValue(RowHeadersProperty, _useCache); } /// Collection of all column headers for this table - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public AutomationElement[] GetColumnHeaders() { return (AutomationElement[])_el.GetPatternPropertyValue(ColumnHeadersProperty, _useCache); @@ -213,11 +203,6 @@ public AutomationElement[] GetColumnHeaders() /// /// number of rows in the grid /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int RowCount { get @@ -229,11 +214,6 @@ public int RowCount /// /// number of columns in the grid /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public int ColumnCount { get @@ -243,11 +223,6 @@ public int ColumnCount } /// Indicates if the data is best presented by row or column - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public RowOrColumnMajor RowOrColumnMajor { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TogglePattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TogglePattern.cs index 8de35ef96ce..279a445e3c1 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TogglePattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TogglePattern.cs @@ -65,11 +65,6 @@ private TogglePattern(AutomationElement el, SafePatternHandle hPattern, bool cac /// /// Request to change the state that this UI element is currently representing /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void Toggle() { UiaCoreApi.TogglePattern_Toggle(_hPattern); @@ -209,11 +204,6 @@ internal TogglePatternInformation(AutomationElement el, bool useCache) #region Public Properties /// Value of a toggleable control, as a ToggleState enum - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public ToggleState ToggleState { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TransformPattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TransformPattern.cs index 41ec0d96499..d3e2ebd741d 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TransformPattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/TransformPattern.cs @@ -75,11 +75,6 @@ private TransformPattern(AutomationElement el, SafePatternHandle hPattern, bool /// /// absolute on-screen position of the top left corner /// absolute on-screen position of the top left corner - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void Move( double x, double y ) { UiaCoreApi.TransformPattern_Move(_hPattern, x, y); @@ -93,10 +88,6 @@ public void Move( double x, double y ) /// /// The requested width of the window. /// The requested height of the window. - /// - /// This API does not work inside the secure execution environment. - /// - /// public void Resize( double width, double height ) { UiaCoreApi.TransformPattern_Resize(_hPattern, width, height); @@ -107,10 +98,6 @@ public void Resize( double width, double height ) /// /// The requested degrees to rotate the element. A positive number rotates clockwise /// a negative number rotates counter clockwise - /// - /// This API does not work inside the secure execution environment. - /// - /// public void Rotate( double degrees ) { UiaCoreApi.TransformPattern_Rotate(_hPattern, degrees); @@ -251,11 +238,6 @@ internal TransformPatternInformation(AutomationElement el, bool useCache) #region Public Properties /// Returns true if the element can be moved otherwise returns false. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool CanMove { get @@ -265,11 +247,6 @@ public bool CanMove } /// Returns true if the element can be resized otherwise returns false. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool CanResize { get @@ -279,11 +256,6 @@ public bool CanResize } /// Returns true if the element can be rotated otherwise returns false. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool CanRotate { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ValuePattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ValuePattern.cs index e38ade436a7..39090b33724 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ValuePattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ValuePattern.cs @@ -70,11 +70,6 @@ internal ValuePattern(AutomationElement el, SafePatternHandle hPattern, bool cac /// Request to set the value that this UI element is representing /// /// Value to set the UI to, the provider is responsible for converting from a string into the appropriate data type - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void SetValue( string value ) { Misc.ValidateArgumentNonNull(value, "value"); @@ -231,11 +226,6 @@ internal ValuePatternInformation(AutomationElement el, bool useCache) #region Public Properties ///Value of a value control, as a a string. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public string Value { get @@ -251,11 +241,6 @@ public string Value ///Indicates that the value can only be read, not modified. ///returns True if the control is read-only - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool IsReadOnly { get diff --git a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/WindowPattern.cs b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/WindowPattern.cs index 5d42556a85d..e58940e319f 100644 --- a/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/WindowPattern.cs +++ b/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/WindowPattern.cs @@ -90,11 +90,6 @@ private WindowPattern(AutomationElement el, SafePatternHandle hPattern, bool cac /// Changes the State of the window based on the passed enum. /// /// The requested state of the window. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void SetWindowVisualState( WindowVisualState state ) { UiaCoreApi.WindowPattern_SetWindowVisualState(_hPattern, state); @@ -106,11 +101,6 @@ public void SetWindowVisualState( WindowVisualState state ) /// split), it may or may not also close all other panes related to the /// document/content/etc. This behavior is application dependent. /// - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public void Close() { UiaCoreApi.WindowPattern_Close(_hPattern); @@ -276,11 +266,6 @@ internal WindowPatternInformation(AutomationElement el, bool useCache) #region Public Properties /// Is this window Maximizable - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool CanMaximize { get @@ -290,11 +275,6 @@ public bool CanMaximize } /// Is this window Minimizable - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool CanMinimize { get @@ -304,11 +284,6 @@ public bool CanMinimize } /// Is this is a modal window. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool IsModal { get @@ -318,11 +293,6 @@ public bool IsModal } /// Is the Window Maximized, Minimized, or Normal (aka restored) - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public WindowVisualState WindowVisualState { get @@ -332,11 +302,6 @@ public WindowVisualState WindowVisualState } /// Is the Window Closing, ReadyForUserInteraction, BlockedByModalWindow or NotResponding. - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public WindowInteractionState WindowInteractionState { get @@ -346,11 +311,6 @@ public WindowInteractionState WindowInteractionState } /// Is this window is always on top - /// - /// - /// This API does not work inside the secure execution environment. - /// - /// public bool IsTopmost { get diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/Certificate.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/Certificate.cs index 9cf0929b3a2..c417ad3e1b6 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/Certificate.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/Certificate.cs @@ -131,7 +131,7 @@ internal void SetCertificate(X509Certificate2 certificate) Byte[] byteArray = _certificate.GetRawCertData(); // FileMode.Create will ensure that the stream will shrink if overwritten - using (Stream s = _part.GetStream(FileMode.Create, FileAccess.Write)) + using (Stream s = _part.GetSeekableStream(FileMode.Create, FileAccess.Write)) { s.Write(byteArray, 0, byteArray.Length); } diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs index 55d616dcca9..2a7079dd432 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs @@ -1,1241 +1,1246 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// -// -// Description: -// Implementation of the W3C Digital Signature Handler. -// Generates and consumes XmlDSig-compliant digital signatures based on the subset -// specified by the Opc file format. -// - - -using System; -using System.Diagnostics; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Security; // for SecurityCritical and SecurityTreatAsSafe -using System.Security.Cryptography; -using System.Security.Cryptography.Xml; -using System.Security.Cryptography.X509Certificates; -using System.Xml; -using System.IO; -using System.Windows; -using System.IO.Packaging; -using Microsoft.Win32; -using MS.Internal; -using MS.Internal.WindowsBase; - -using MS.Internal.IO.Packaging.Extensions; - -namespace MS.Internal.IO.Packaging -{ - /// - /// Signature Handler implementation that follows the Feb 12, 2002 W3C DigSig Recommendation - /// - /// See: http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/ for details - internal class XmlDigitalSignatureProcessor - { - //------------------------------------------------------ - // - // Internal Methods - // - //------------------------------------------------------ - - /// - /// Constructor - called from PackageDigitalSignatureManager when opening an existing signature - /// - /// current DigitalSignatureManager - /// public signature object - /// the part that will/does house the associated XML signature - internal XmlDigitalSignatureProcessor(PackageDigitalSignatureManager manager, - PackagePart signaturePart, PackageDigitalSignature packageSignature) : this(manager, signaturePart) - { - _signature = packageSignature; - } - - /// - /// Factory method that creates a new PackageDigitalSignature - /// - internal static PackageDigitalSignature Sign( - PackageDigitalSignatureManager manager, - PackagePart signaturePart, - IEnumerable parts, - IEnumerable relationshipSelectors, - X509Certificate2 signer, - String signatureId, - bool embedCertificate, - IEnumerable signatureObjects, - IEnumerable objectReferences) - { - // create - XmlDigitalSignatureProcessor p = new XmlDigitalSignatureProcessor(manager, signaturePart); - - // and sign - return p.Sign(parts, relationshipSelectors, signer, signatureId, - embedCertificate, signatureObjects, objectReferences); - } - - /// - /// Verify the given signature - /// - /// throws if no certificate found in the signature - /// true if the data stream has not been altered since it was signed - internal bool Verify() - { - return Verify(Signer); - } - - /// - /// Verify the given signature - /// - /// certificate to use (ignores any embedded cert) - /// true if the data stream has not been altered since it was signed - internal bool Verify(X509Certificate2 signer) - { - Invariant.Assert(signer != null); - - // Create a SignedXml to do the dirty work - SignedXml xmlSig = EnsureXmlSignatureParsed(); - - bool result = false; - - // Validate the Reference tags in the SignedInfo as per the - // restrictions imposed by the OPC spec - ValidateReferences(xmlSig.SignedInfo.References, true /*allowPackageSpecificReference*/); - - // verify "standard" XmlSignature portions - result = xmlSig.CheckSignature(signer, true); - - if (result) - { - HashAlgorithm hashAlgorithm = null; // optimize - generally only need to create and re-use one of these - String currentHashAlgorithmName = String.Empty; // guaranteed not to match - - try - { - try - { - // if that succeeds, verify the Manifest including Part/Relationship content and ContentTypes - ParsePackageDataObject(); - } - catch (XmlException) - { - // parsing exception - means this is a bad signature - return false; - } - - foreach (PartManifestEntry partEntry in _partEntryManifest) - { - // compare the content - Stream s = null; - - // Relationship requires special handling - if (partEntry.IsRelationshipEntry) - { - // This behaves correctely even if the Relationship Part is missing entirely - s = GetRelationshipStream(partEntry); - } - else // Part entry - inspect raw stream - { - // part is guaranteed to exist at this point because we fail early in PackageDigitalSignature.Verify() - Debug.Assert(_manager.Package.PartExists(partEntry.Uri)); - - // Compare the content type first so we can fail early if it doesn't match - // (faster than hashing the content itself). - // Compare ordinal case-sensitive which is more strict than normal ContentType - // comparision because this is manadated by the OPC specification. - PackagePart part = _manager.Package.GetPart(partEntry.Uri); - if (String.CompareOrdinal( - partEntry.ContentType.OriginalString, - part.ValidatedContentType().OriginalString) != 0) - { - result = false; // content type mismatch - break; - } - s = part.GetStream(FileMode.Open, FileAccess.Read); - } - - using (s) - { - // ensure hash algorithm object is available - re-use if possible - if (((hashAlgorithm != null) && (!hashAlgorithm.CanReuseTransform)) || - String.CompareOrdinal(partEntry.HashAlgorithm, currentHashAlgorithmName) != 0) - { - if (hashAlgorithm != null) - ((IDisposable)hashAlgorithm).Dispose(); - - currentHashAlgorithmName = partEntry.HashAlgorithm; - hashAlgorithm = GetHashAlgorithm(currentHashAlgorithmName); - - // not a supported or recognized algorithm? - if (hashAlgorithm == null) - { - // return invalid result instead of throwing exception - result = false; - break; - } - } - - // calculate hash - String base64EncodedHashValue = GenerateDigestValue(s, partEntry.Transforms, hashAlgorithm); - - // now compare the hash - must be identical - if (String.CompareOrdinal(base64EncodedHashValue, partEntry.HashValue) != 0) - { - result = false; // hash mismatch - break; - } - } - } - } - finally - { - if (hashAlgorithm != null) - ((IDisposable)hashAlgorithm).Dispose(); - } - } - - return result; - } - - /// - /// Get the list of transforms applied to the given part (works for Relationship parts too) - /// - /// part to get transforms for - /// possibly empty, ordered list of transforms applied to the given part (never null) - /// This method only returns transform names. Transform-specific properties can be obtained by parsing the actual - /// signature contents which conform to the W3C XmlDSig spec. - internal List GetPartTransformList(Uri partName) - { - // query the parsed manifest - ParsePackageDataObject(); - - List transformList = null; - - // look through the manifest for the requested part - foreach (PartManifestEntry entry in _partEntryManifest) - { - if (System.IO.Packaging.PackUriHelper.ComparePartUri(entry.Uri, partName) == 0) - { - transformList = entry.Transforms; - break; - } - } - - // never return null - an empty list is better form - if (transformList == null) - transformList = new List(); - - return transformList; - } - - //------------------------------------------------------ - // - // Internal Properties - // - //------------------------------------------------------ - - /// - /// Content type of signature parts created by this processor - /// - internal static ContentType ContentType - { - get - { - return _xmlSignaturePartType; - } - } - - - /// - /// Associated signature part - /// - internal PackagePart SignaturePart - { - get - { - return _signaturePart; - } - } - - - /// - /// Obtain the list of signed parts - /// - /// Authors identity in handler-proprietary format - /// if signature xml is malformed - internal List PartManifest - { - get - { - ParsePackageDataObject(); - return _partManifest; - } - } - - /// - /// Obtain the author's identity as a byte stream - /// - /// Authors identity in handler-proprietary format - /// if signature xml is malformed - internal List RelationshipManifest - { - get - { - ParsePackageDataObject(); - return _relationshipManifest; - } - } - - /// - /// Obtain the author's identity in X509 Certificate form - /// - /// Authors identity as a certificate in X509 form, or null if none found - internal X509Certificate2 Signer - { - get - { - // lazy init when loading existing cert - Sign may have assigned this for us - if (_certificate == null) - { - // first look for cert part - if (PackageSignature.GetCertificatePart() != null) - _certificate = PackageSignature.GetCertificatePart().GetCertificate(); - else - { - // look in signature - if (_lookForEmbeddedCert) - { - IEnumerator keyInfoClauseEnum = EnsureXmlSignatureParsed().KeyInfo.GetEnumerator(typeof(KeyInfoX509Data)); - while (keyInfoClauseEnum.MoveNext()) - { - KeyInfoX509Data x509Data = (KeyInfoX509Data)keyInfoClauseEnum.Current; - foreach (X509Certificate2 cert in x509Data.Certificates) - { - // just take the first one for now - _certificate = cert; - break; - } - - // just need one for now - if (_certificate != null) - break; - } - - // only need to do this once - _lookForEmbeddedCert = false; - } - } - } - - return _certificate; // may be null - } - } - - /// - /// encrypted hash value - /// - /// - internal byte[] SignatureValue - { - get - { - return EnsureXmlSignatureParsed().SignatureValue; - } - } - - /// - /// The object that actually creates the signature - /// Note: This API is exposed to the public API surface through the - /// PackageDigitalSignature.Signature property. Through this API it is - /// possible to create Signatures that are not OPC compliant. However, - /// at verify time, we will throw exceptions for non-conforming signatures. - /// - /// object of type System.Security.Cryptography.Xml.Signature - internal Signature Signature - { - get - { - return EnsureXmlSignatureParsed().Signature; - } - set - { - UpdatePartFromSignature(value); - } - } - - /// - /// Get the given signature - /// - internal PackageDigitalSignature PackageSignature - { - get - { - return _signature; - } - } - - /// - /// Time that the signature was created - /// - /// Time of signing if available, or DateTime.MinValue if signature was not time-stamped - internal DateTime SigningTime - { - get - { - // lazy init - ParsePackageDataObject(); - return _signingTime; - } - } - - internal String TimeFormat - { - get - { - // lazy init - ParsePackageDataObject(); - return _signingTimeFormat; - } - } - - //------------------------------------------------------ - // - // Digest Helper Functions - // - //------------------------------------------------------ - /// - /// Generate digest value tag - /// - /// - /// name of the single transform to use - may be null - /// hash algorithm to use - /// - internal static String GenerateDigestValue( - Stream s, - String transformName, - HashAlgorithm hashAlgorithm) - { - List transforms = null; - if (transformName != null) - { - transforms = new List(1); - transforms.Add(transformName); - } - return GenerateDigestValue(s, transforms, hashAlgorithm); - } - - /// - /// Generate digest value tag - /// - /// transforms to apply - may be null and list may contain empty strings - /// stream to hash - /// algorithm to use - internal static String GenerateDigestValue( - Stream s, - List transforms, - HashAlgorithm hashAlgorithm) - { - s.Seek(0, SeekOrigin.Begin); - - // We need to be able to dispose streams generated by the - // Transform object but we don't want to dispose the stream - // passed to us so we insert this to block any propagated Dispose() calls. - Stream transformStream = new IgnoreFlushAndCloseStream(s); - - List transformStreams = null; - - // canonicalize the part content if asked - if (transforms != null) - { - transformStreams = new List(transforms.Count); - transformStreams.Add(transformStream); - foreach (String transformName in transforms) - { - // ignore empty strings at this point (as well as Relationship Transforms) - these are legal - if ((transformName.Length == 0) - || (String.CompareOrdinal(transformName, XTable.Get(XTable.ID.RelationshipsTransformName)) == 0)) - { - continue; - } - - // convert the transform names into objects (if defined) - Transform transform = StringToTransform(transformName); - - if (transform == null) - { - // throw XmlException so the outer loop knows the signature is invalid - throw new XmlException(SR.Get(SRID.UnsupportedTransformAlgorithm)); - } - - transformStream = TransformXml(transform, transformStream); - transformStreams.Add(transformStream); - } - } - - // hash it and encode to Base64 - String hashValueString = System.Convert.ToBase64String(HashStream(hashAlgorithm, transformStream)); - - // dispose of any generated streams - if (transformStreams != null) - { - foreach (Stream stream in transformStreams) - stream.Close(); - } - - return hashValueString; - } - - /// - /// Synthesizes a NodeList of Reference tags to hash - /// - /// - /// - internal static Stream GenerateRelationshipNodeStream(IEnumerable relationships) - { - // create a NodeList containing valid Relationship XML and serialize it to the stream - Stream s = new MemoryStream(); - - // Wrap in a stream that ignores Flush and Close so the XmlTextWriter - // will not close it. - // use UTF-8 encoding by default - using (XmlTextWriter writer = new XmlTextWriter(new IgnoreFlushAndCloseStream(s), - System.Text.Encoding.UTF8)) - { - // start outer Relationships tag - writer.WriteStartElement(XTable.Get(XTable.ID.RelationshipsTagName), PackagingUtilities.RelationshipNamespaceUri); - - // generate a valid Relationship tag according to the Opc schema - InternalRelationshipCollection.WriteRelationshipsAsXml(writer, relationships, - true, /* systematically write target mode */ - false /* not in streaming production */ - ); - - // end of Relationships tag - writer.WriteEndElement(); - } - - return s; - } - - /// - /// Convert algorithm name to object - /// - /// fully specified name - /// HashAlgorithm object or null if it does not map to a supported hash type - /// Caller is responsible for calling Dispose() on returned object - internal static HashAlgorithm GetHashAlgorithm(String hashAlgorithmName) - { - Object o = CryptoConfig.CreateFromName(hashAlgorithmName); - HashAlgorithm algorithm = o as HashAlgorithm; - - // In the case that we get a valid crypto object that is not a hash algorithm - // we should attempt to dispose it if it offers IDisposable. - if (algorithm == null && o != null) - { - IDisposable disposable = o as IDisposable; - if (disposable != null) - disposable.Dispose(); - } - - return algorithm; - } - - /// - /// IMPORTANT NOTE: - /// 1. In the XmlDigitalSignatureProcessor.IsValidXmlCanonicalizationTransform method, - /// we have similar logic regarding these two transforms.So both these methods must be updated - /// in sync. - /// - private static Transform StringToTransform(String transformName) - { - Invariant.Assert(transformName != null); - - if (String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NTransformUrl) == 0) - { - return new XmlDsigC14NTransform(); - } - else if (String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NWithCommentsTransformUrl) == 0) - { - return new XmlDsigC14NWithCommentsTransform(); - } - else - return null; -} - - // As per the OPC spec, only two tranforms are valid. Also, both of these happen to be - // XML canonicalization transforms. - // In the XmlSignatureManifest.ParseTransformsTag method we make use this method to - // validate the transforms to make sure that they are supported by the OPC spec and - // we also take advantage of the fact that both of them are XML canonicalization transforms - // IMPORTANT NOTE: - // 1. In the XmlDigitalSignatureProcessor.StringToTransform method, we have similar logic - // regarding these two transforms.So both these methods must be updated in sync. - // 2. If ever this method is updated to add other transforms, careful review must be done to - // make sure that methods calling this method are updated as required. - internal static bool IsValidXmlCanonicalizationTransform(String transformName) - { - Invariant.Assert(transformName != null); - - if (String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NTransformUrl) == 0 || - String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NWithCommentsTransformUrl) == 0) - { - return true; - } - else - return false; - } - - //------------------------------------------------------ - // - // Private Properties - // - //------------------------------------------------------ - /// - /// Helper class - /// - private SignedXml EnsureXmlSignatureParsed() - { - // lazy init - if (_signedXml == null) - { - _signedXml = new CustomSignedXml(); - - // Load the XML - XmlDocument xmlDocument = new XmlDocument(); - xmlDocument.PreserveWhitespace = true; - using (Stream s = SignaturePart.GetStream()) - { - using (XmlTextReader xmlReader = new XmlTextReader(s)) - { - //Prohibit DTD from the markup as per the OPC spec - xmlReader.ProhibitDtd = true; - - //This method expects the reader to be in ReadState.Initial. - //It will make the first read call. - PackagingUtilities.PerformInitailReadAndVerifyEncoding(xmlReader); - - //If the reader.ReadState is ReadState.Initial, then XmlDocument with perform the - //first xmlReader.Read() and start loading from that node/tag. - //If the reader.ReadState is ReadState.Intermediate, then XmlDocument, will start - //loading from that location itself. - //Note: Since in the above method we perform only the first read and will have not - //moved the reader state further down in the markup, we should be okay, and - //xmlDocument.Load will load from the very begining as intended. - xmlDocument.Load(xmlReader); - - // W3C spec allows for Signature tag to appear as an island and inherently allows - // for multiple Signature tags within the same XML document. - // OPC restricts this to a single, root-level Signature tag. However, Signature - // tags are allowed to exist within the non-OPC Object tags within an OPC signature. - // This is common for XAdES signatures and must be explicitly allowed. - XmlNodeList nodeList = xmlDocument.ChildNodes; - if (nodeList == null || nodeList.Count == 0 || nodeList.Count > 2) - throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); - - XmlNode node = nodeList[0]; - if (nodeList.Count == 2) - { - // First node must be the XmlDeclaration - if (nodeList[0].NodeType != XmlNodeType.XmlDeclaration) - throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); - - // Second node must be in the w3c namespace, and must be the tag - node = nodeList[1]; - } - - if ((node.NodeType != XmlNodeType.Element) || - (String.CompareOrdinal(node.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) != 0) || - (String.CompareOrdinal(node.LocalName, XTable.Get(XTable.ID.SignatureTagName)) != 0)) - { - throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); - } - - // instantiate the SignedXml from the xmlDoc - _signedXml.LoadXml((XmlElement)node); - } - } - } - - // As per the OPC spec, only two Canonicalization methods can be specified - if (!IsValidXmlCanonicalizationTransform(_signedXml.SignedInfo.CanonicalizationMethod)) - throw new XmlException(SR.Get(SRID.UnsupportedCanonicalizationMethod)); - - // As per OPC spec, signature ID must be NCName - if (_signedXml.Signature.Id != null) - { - try - { - System.Xml.XmlConvert.VerifyNCName(_signedXml.Signature.Id); - } - catch (System.Xml.XmlException) - { - throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); - } - } - - return _signedXml; - } - - //------------------------------------------------------ - // - // Private Methods - // - //------------------------------------------------------ - - /// - /// Constructor - called from public constructor as well as static Sign() method - /// - /// current DigitalSignatureManager - /// the part that will/does house the associated XML signature - private XmlDigitalSignatureProcessor(PackageDigitalSignatureManager manager, - PackagePart signaturePart) - { - Invariant.Assert(manager != null); - Invariant.Assert(signaturePart != null); - - _signaturePart = signaturePart; - _manager = manager; - _lookForEmbeddedCert = true; - } - - /// - /// Create a new PackageDigitalSignature - /// - /// the data being protected by this signature - /// possibly null collection of relationshipSelectors that represent the - /// relationships that are to be signed - /// Identity of the author - /// Id attribute of the new Xml Signature - /// true if caller wants certificate embedded in the signature itself - /// references - /// objects to sign - private PackageDigitalSignature Sign( - IEnumerable parts, - IEnumerable relationshipSelectors, - X509Certificate2 signer, - String signatureId, - bool embedCertificate, - IEnumerable signatureObjects, - IEnumerable objectReferences) - { - // don't overwrite - Debug.Assert(SignaturePart.GetStream().Length == 0, "Logic Error: Can't sign when signature already exists"); - - // grab hash algorithm as this may change in the future - _hashAlgorithmName = _manager.HashAlgorithm; - - // keep the signer if indicated - if (_manager.CertificateOption == CertificateEmbeddingOption.NotEmbedded) - _lookForEmbeddedCert = false; // don't bother parsing - else - _certificate = signer; // save some parsing - - // we only release this key if we obtain it - AsymmetricAlgorithm key = null; - if (signer.HasPrivateKey) - { - key = GetPrivateKey(signer); - } - else - { - key = GetPrivateKeyForSigning(signer); - } - - try - { - _signedXml = new CustomSignedXml(); - _signedXml.SigningKey = key; - _signedXml.Signature.Id = signatureId; - - if (BaseCompatibilityPreferences.MatchPackageSignatureMethodToPackagePartDigestMethod) - { - // Defaulting to SHA1 for key signing is counter-productive if the hash algorithm - // for the rest of the package is more secure. So if we have a selected hash - // algorithm in the PackageDigitalSignatureManager that is more secure, then - // select an equivalent level algorithm for key signing. - _signedXml.SignedInfo.SignatureMethod = SelectSignatureMethod(key); - } - - // Track if we are matching the signature method in order to retry on failure - bool usingMatchingSignatureMethod = _signedXml.SignedInfo.SignatureMethod != null; - - // put it in the XML - if (embedCertificate) - { - _signedXml.KeyInfo = GenerateKeyInfo(key, signer); - } - - // Package object tag - // convert from string to class and ensure we dispose - using (HashAlgorithm hashAlgorithm = GetHashAlgorithm(_hashAlgorithmName)) - { - // inform caller if hash algorithm is unknown - if (hashAlgorithm == null) - throw new InvalidOperationException(SR.Get(SRID.UnsupportedHashAlgorithm)); - - _signedXml.AddObject(GenerateObjectTag(hashAlgorithm, parts, relationshipSelectors, signatureId)); - } - - // add reference from SignedInfo to Package object tag - Reference objectReference = new Reference(XTable.Get(XTable.ID.OpcLinkAttrValue)); - objectReference.Type = XTable.Get(XTable.ID.W3CSignatureNamespaceRoot) + "Object"; - objectReference.DigestMethod = _hashAlgorithmName; - _signedXml.AddReference(objectReference); - - // add any custom object tags - AddCustomObjectTags(signatureObjects, objectReferences); - - // compute the signature - SignedXml xmlSig = _signedXml; - - try - { - xmlSig.ComputeSignature(); - } - catch (CryptographicException) when (usingMatchingSignatureMethod) - { - // We've hit a state where System.Security is possibly missing the required updates to process the matched signature. - // Disable our matching and attempt to sign again with the default SignatureMethod - BaseCompatibilityPreferences.MatchPackageSignatureMethodToPackagePartDigestMethod = false; - xmlSig.SignedInfo.SignatureMethod = null; - xmlSig.ComputeSignature(); - } - - // persist - UpdatePartFromSignature(_signedXml.Signature); - } - finally - { - if (key != null) - ((IDisposable)key).Dispose(); - } - - // create the PackageDigitalSignature object - _signature = new PackageDigitalSignature(_manager, this); - return _signature; - } - - /// - /// Attempt to select a key signing method that matches the strength of the selected - /// hash algorithm in the PackageDigitalSignatureManager. - /// - /// If no algorithm was selected, defaults to SHA1. - /// - /// - /// DSA keys have no supported stronger signing solution and are always SHA1 signed. - /// - /// The key being used - /// The URI of the appropriate signing method - private string SelectSignatureMethod(AsymmetricAlgorithm key) - { - string signatureMethod = null; - - if (key is RSA) - { - _rsaSigMethodLookup.TryGetValue(_manager.HashAlgorithm, out signatureMethod); - } - - return signatureMethod; - } - - /// - /// Extracts the private key from the X509Certificate2 certificate - /// - /// certificate for which we are looking for the private key - /// returns the private key - private static AsymmetricAlgorithm GetPrivateKey(X509Certificate2 cert) - { - // Adding support for CNG certificates. The default certificate template in Windows Server 2008+ is CNG - // Get[Algorithm]PrivateKey methods returns unique object while PrivateKey property returns shared one - // Make sure to dispose the key if it is from Get[Algorithm]PrivateKey methods - AsymmetricAlgorithm key = cert.GetRSAPrivateKey(); - if (key != null) - return key; - - key = cert.GetDSAPrivateKey(); - if (key != null) - return key; - - key = cert.GetECDsaPrivateKey(); - if (key != null) - return key; - - // Get[Algorithm]PrivateKey methods would always have returned the private key if the PrivateKey property would - // But Get[Algorithm]PrivateKey methods never throw but returns null in case of error during cryptographic operations - // But we want exception to be thrown when an error occurs during a cryptographic operation so that we can revert the changes - return cert.PrivateKey; - } - - /// - /// Assembles the sorted list of relationships for this part entry and - /// generates a stream with the Xml-equivalent as defined in the Opc spec - /// - /// relationship-type part entry - /// - private Stream GetRelationshipStream(PartManifestEntry partEntry) - { - Debug.Assert(partEntry.IsRelationshipEntry); - - //Get the list of relationships from the RelationshipSelectors for this part - SortedDictionary partRelationships = - new SortedDictionary(StringComparer.Ordinal); - foreach (System.IO.Packaging.PackageRelationshipSelector relationshipSelector in partEntry.RelationshipSelectors) - { - foreach (System.IO.Packaging.PackageRelationship r in relationshipSelector.Select(_manager.Package)) - { - if(!partRelationships.ContainsKey(r.Id)) - partRelationships.Add(r.Id, r); - } - } - - return GenerateRelationshipNodeStream(partRelationships.Values); - } - - private void AddCustomObjectTags(IEnumerable signatureObjects, - IEnumerable objectReferences) - { - Invariant.Assert(_signedXml != null); - - - // add any references - if (objectReferences != null) - { - // Validate the Reference tags in the SignedInfo as per the - // restrictions imposed by the OPC spec - ValidateReferences(objectReferences, false /*allowPackageSpecificReference*/); - - foreach (Reference reference in objectReferences) - { - // consistent hash algorithm for entire signature - reference.DigestMethod = _hashAlgorithmName; - _signedXml.AddReference(reference); - } - } - - // any object tags - if (signatureObjects != null) - { - // thes have been pre-screened for matches against reserved OpcAttrValue and duplicates - foreach (DataObject obj in signatureObjects) - { - _signedXml.AddObject(obj); - } - } - } - - private void UpdatePartFromSignature(Signature sig) - { - // write to stream - using (Stream s = SignaturePart.GetStream(FileMode.Create, FileAccess.Write)) - { - using (XmlTextWriter xWriter = new XmlTextWriter(s, System.Text.Encoding.UTF8)) - { - xWriter.WriteStartDocument(true); - sig.GetXml().WriteTo(xWriter); - xWriter.WriteEndDocument(); - } - } - _signedXml = null; // force a re-parse - } - - private static byte[] HashStream(HashAlgorithm hashAlgorithm, Stream s) - { - s.Seek(0, SeekOrigin.Begin); - - // reset algorithm - hashAlgorithm.Initialize(); - return hashAlgorithm.ComputeHash(s); - } - - private static Stream TransformXml(Transform xForm, Object source) - { - // transform - xForm.LoadInput(source); - - return (Stream)xForm.GetOutput(); - } - - /// - /// Full parse of the Package-specific Object tag - /// - /// Side effect of updating _signingTime, _signingTimeFormat, - /// _partManifest, _partEntryManifest and _relationshipManifest - /// throws if markup does not match OPC spec - private void ParsePackageDataObject() - { - if (!_dataObjectParsed) - { - EnsureXmlSignatureParsed(); - - // find the package-specific Object tag - XmlNodeList nodeList = GetPackageDataObject().Data; - - // The legal parent is a "Package" Object tag with 2 children - // and - if (nodeList.Count != 2) - throw new XmlException(SR.Get(SRID.XmlSignatureParseError)); - - // get a NodeReader that allows us to easily and correctly skip comments - XmlReader reader = new XmlNodeReader(nodeList[0].ParentNode); - - // parse the tag - ensure that it is in the correct namespace - reader.Read(); // enter the Object tag - if (String.CompareOrdinal(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) != 0) - throw new XmlException(SR.Get(SRID.XmlSignatureParseError)); - - string signaturePropertiesTagName = XTable.Get(XTable.ID.SignaturePropertiesTagName); - string manifestTagName = XTable.Get(XTable.ID.ManifestTagName); - bool signaturePropertiesTagFound = false; - bool manifestTagFound = false; - while (reader.Read() && (reader.NodeType == XmlNodeType.Element)) - { - if (reader.MoveToContent() == XmlNodeType.Element - && (String.CompareOrdinal(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) == 0) - && reader.Depth == 1) - { - if (!signaturePropertiesTagFound && String.CompareOrdinal(reader.LocalName, signaturePropertiesTagName) == 0) - { - signaturePropertiesTagFound = true; - - // parse the tag - _signingTime = XmlSignatureProperties.ParseSigningTime( - reader, _signedXml.Signature.Id, out _signingTimeFormat); - - continue; - } - else if (!manifestTagFound && String.CompareOrdinal(reader.LocalName, manifestTagName) == 0) - { - manifestTagFound = true; - - // parse the tag - XmlSignatureManifest.ParseManifest(_manager, reader, - out _partManifest, out _partEntryManifest, out _relationshipManifest); - - continue; - } - } - - throw new XmlException(SR.Get(SRID.XmlSignatureParseError)); - } - - // these must both exist on exit - if (!(signaturePropertiesTagFound && manifestTagFound)) - throw new XmlException(SR.Get(SRID.XmlSignatureParseError)); - - _dataObjectParsed = true; - } - } - - /// - /// Finds and return the package-specific Object tag - /// - /// - private DataObject GetPackageDataObject() - { - EnsureXmlSignatureParsed(); - - // look for the Package-specific object tag - String opcId = XTable.Get(XTable.ID.OpcAttrValue); - DataObject returnValue = null; - foreach (DataObject dataObject in _signedXml.Signature.ObjectList) - { - if (String.CompareOrdinal(dataObject.Id, opcId) == 0) - { - // duplicates not allowed - if (returnValue != null) - throw new XmlException(SR.Get(SRID.SignatureObjectIdMustBeUnique)); - - returnValue = dataObject; - } - } - - // Package object tag required - if (returnValue != null) - return returnValue; - else - throw new XmlException(SR.Get(SRID.PackageSignatureObjectTagRequired)); - } - - private KeyInfo GenerateKeyInfo(AsymmetricAlgorithm key, X509Certificate2 signer) - { - // KeyInfo section - KeyInfo keyInfo = new KeyInfo(); - KeyInfoName keyInfoName = new KeyInfoName(); - keyInfoName.Value = signer.Subject; - keyInfo.AddClause(keyInfoName); // human readable Principal name - - // Include the public key information (if we are familiar with the algorithm type) - if (key is RSA) - keyInfo.AddClause(new RSAKeyValue((RSA)key)); // RSA key parameters - else - { - if (key is DSA) - keyInfo.AddClause(new DSAKeyValue((DSA)key)); // DSA - else - throw new ArgumentException(SR.Get(SRID.CertificateKeyTypeNotSupported), "signer"); - } - - // the actual X509 cert - keyInfo.AddClause(new KeyInfoX509Data(signer)); - - return keyInfo; - } - - private DataObject GenerateObjectTag( - HashAlgorithm hashAlgorithm, - IEnumerable parts, IEnumerable relationshipSelectors, - String signatureId) - { - XmlDocument xDoc = new XmlDocument(); - xDoc.AppendChild(xDoc.CreateNode(XmlNodeType.Element, "root", "namespace")); // dummy root - xDoc.DocumentElement.AppendChild(XmlSignatureManifest.GenerateManifest(_manager, xDoc, hashAlgorithm, parts, relationshipSelectors)); - xDoc.DocumentElement.AppendChild(XmlSignatureProperties.AssembleSignatureProperties(xDoc, DateTime.Now, _manager.TimeFormat, signatureId)); - - DataObject dataObject = new DataObject(); - dataObject.Data = xDoc.DocumentElement.ChildNodes; - dataObject.Id = XTable.Get(XTable.ID.OpcAttrValue); - - return dataObject; - } - - /// - /// lookup the private key using the given identity - /// - /// X509Cert - /// IDisposable asymmetric algorithm that serves as a proxy to the private key. Caller must dispose - /// of properly. - private static AsymmetricAlgorithm GetPrivateKeyForSigning(X509Certificate2 signer) - { - // if the certificate does not actually contain the key, we need to look it up via ThumbPrint - Invariant.Assert(!signer.HasPrivateKey); - - // look for appropriate certificates - X509Store store = new X509Store(StoreLocation.CurrentUser); - - try - { - store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); - - X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; - - collection = collection.Find(X509FindType.FindByThumbprint, signer.Thumbprint, true); - if (collection.Count > 0) - { - if (collection.Count > 1) - throw new CryptographicException(SR.Get(SRID.DigSigDuplicateCertificate)); - - signer = collection[0]; - } - else - throw new CryptographicException(SR.Get(SRID.DigSigCannotLocateCertificate)); - } - finally - { - store.Close(); - } - - // get the corresponding AsymmetricAlgorithm - return GetPrivateKey(signer); - } - - - /// - /// This method validated the Reference tags as per the restrictions imposed - /// by the OPC spec. - /// NOTE: The same method is called from Verify and Sign methods. At verify time we need to make sure - /// that there is exactly one Package-specific reference. At Sign time we need to make sure that - /// there are no package-specific references in the list of references passed to Sign APIs as a - /// input parameter, since we will be generating Package-specific object. - /// - /// list of references to be validated - /// When "true", we check to make sure that there is - /// exactly one package-specific reference and when "false", we do not allow any package-specific - /// references - private void ValidateReferences(IEnumerable references, bool allowPackageSpecificReferences) - { - Debug.Assert(references != null); - - bool packageReferenceFound = false; - TransformChain currentTransformChain; - - foreach (Reference currentReference in references) - { - //As per the OPC spec, Uri attribute in Reference elements MUST refer using fragment identifiers - //This implies that Uri cannot be absolute. - if (currentReference.Uri.StartsWith("#", StringComparison.Ordinal)) - { - //As per the OPC spec, there MUST be exactly one package specific reference to the - //package specific element - if (String.CompareOrdinal(currentReference.Uri, XTable.Get(XTable.ID.OpcLinkAttrValue)) == 0) - { - if (!allowPackageSpecificReferences) - throw new ArgumentException(SR.Get(SRID.PackageSpecificReferenceTagMustBeUnique)); - - //If there are more than one package specific tags - if (packageReferenceFound == true) - throw new XmlException(SR.Get(SRID.MoreThanOnePackageSpecificReference)); - else - packageReferenceFound = true; - } - - currentTransformChain = currentReference.TransformChain; - - for(int j=0; j _partManifest; // signed parts (suitable for return to public API) - private List _partEntryManifest; // signed parts (with extra info) - private List _relationshipManifest; // signed relationship selectors - - private static readonly ContentType _xmlSignaturePartType - = new ContentType("application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml"); - - /// - /// Mapping from hash algorithms in the PackageDigitalSignatureManager to RSA key signing methods. - /// - private static readonly Dictionary _rsaSigMethodLookup = new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "http://www.w3.org/2001/04/xmlenc#sha256", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" }, - { "http://www.w3.org/2001/04/xmldsig-more#sha384", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384" }, - { "http://www.w3.org/2001/04/xmlenc#sha512", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" }, - }; - } -} - +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// +// +// Description: +// Implementation of the W3C Digital Signature Handler. +// Generates and consumes XmlDSig-compliant digital signatures based on the subset +// specified by the Opc file format. +// + + +using System; +using System.Diagnostics; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Security; // for SecurityCritical and SecurityTreatAsSafe +using System.Security.Cryptography; +using System.Security.Cryptography.Xml; +using System.Security.Cryptography.X509Certificates; +using System.Xml; +using System.IO; +using System.Windows; +using System.IO.Packaging; +using Microsoft.Win32; +using MS.Internal; +using MS.Internal.WindowsBase; + +using MS.Internal.IO.Packaging.Extensions; + +namespace MS.Internal.IO.Packaging +{ + /// + /// Signature Handler implementation that follows the Feb 12, 2002 W3C DigSig Recommendation + /// + /// See: http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/ for details + internal class XmlDigitalSignatureProcessor + { + //------------------------------------------------------ + // + // Internal Methods + // + //------------------------------------------------------ + + /// + /// Constructor - called from PackageDigitalSignatureManager when opening an existing signature + /// + /// current DigitalSignatureManager + /// public signature object + /// the part that will/does house the associated XML signature + internal XmlDigitalSignatureProcessor(PackageDigitalSignatureManager manager, + PackagePart signaturePart, PackageDigitalSignature packageSignature) : this(manager, signaturePart) + { + _signature = packageSignature; + } + + /// + /// Factory method that creates a new PackageDigitalSignature + /// + internal static PackageDigitalSignature Sign( + PackageDigitalSignatureManager manager, + PackagePart signaturePart, + IEnumerable parts, + IEnumerable relationshipSelectors, + X509Certificate2 signer, + String signatureId, + bool embedCertificate, + IEnumerable signatureObjects, + IEnumerable objectReferences) + { + // create + XmlDigitalSignatureProcessor p = new XmlDigitalSignatureProcessor(manager, signaturePart); + + // and sign + return p.Sign(parts, relationshipSelectors, signer, signatureId, + embedCertificate, signatureObjects, objectReferences); + } + + /// + /// Verify the given signature + /// + /// throws if no certificate found in the signature + /// true if the data stream has not been altered since it was signed + internal bool Verify() + { + return Verify(Signer); + } + + /// + /// Verify the given signature + /// + /// certificate to use (ignores any embedded cert) + /// true if the data stream has not been altered since it was signed + internal bool Verify(X509Certificate2 signer) + { + Invariant.Assert(signer != null); + + // Create a SignedXml to do the dirty work + SignedXml xmlSig = EnsureXmlSignatureParsed(); + + bool result = false; + + // Validate the Reference tags in the SignedInfo as per the + // restrictions imposed by the OPC spec + ValidateReferences(xmlSig.SignedInfo.References, true /*allowPackageSpecificReference*/); + + // verify "standard" XmlSignature portions + result = xmlSig.CheckSignature(signer, true); + + if (result) + { + HashAlgorithm hashAlgorithm = null; // optimize - generally only need to create and re-use one of these + String currentHashAlgorithmName = String.Empty; // guaranteed not to match + + try + { + try + { + // if that succeeds, verify the Manifest including Part/Relationship content and ContentTypes + ParsePackageDataObject(); + } + catch (XmlException) + { + // parsing exception - means this is a bad signature + return false; + } + + foreach (PartManifestEntry partEntry in _partEntryManifest) + { + // compare the content + Stream s = null; + + // Relationship requires special handling + if (partEntry.IsRelationshipEntry) + { + // This behaves correctely even if the Relationship Part is missing entirely + s = GetRelationshipStream(partEntry); + } + else // Part entry - inspect raw stream + { + // part is guaranteed to exist at this point because we fail early in PackageDigitalSignature.Verify() + Debug.Assert(_manager.Package.PartExists(partEntry.Uri)); + + // Compare the content type first so we can fail early if it doesn't match + // (faster than hashing the content itself). + // Compare ordinal case-sensitive which is more strict than normal ContentType + // comparision because this is manadated by the OPC specification. + PackagePart part = _manager.Package.GetPart(partEntry.Uri); + if (String.CompareOrdinal( + partEntry.ContentType.OriginalString, + part.ValidatedContentType().OriginalString) != 0) + { + result = false; // content type mismatch + break; + } + s = part.GetSeekableStream(FileMode.Open, FileAccess.Read); + } + + using (s) + { + // ensure hash algorithm object is available - re-use if possible + if (((hashAlgorithm != null) && (!hashAlgorithm.CanReuseTransform)) || + String.CompareOrdinal(partEntry.HashAlgorithm, currentHashAlgorithmName) != 0) + { + if (hashAlgorithm != null) + ((IDisposable)hashAlgorithm).Dispose(); + + currentHashAlgorithmName = partEntry.HashAlgorithm; + hashAlgorithm = GetHashAlgorithm(currentHashAlgorithmName); + + // not a supported or recognized algorithm? + if (hashAlgorithm == null) + { + // return invalid result instead of throwing exception + result = false; + break; + } + } + + // calculate hash + String base64EncodedHashValue = GenerateDigestValue(s, partEntry.Transforms, hashAlgorithm); + + // now compare the hash - must be identical + if (String.CompareOrdinal(base64EncodedHashValue, partEntry.HashValue) != 0) + { + result = false; // hash mismatch + break; + } + } + } + } + finally + { + if (hashAlgorithm != null) + ((IDisposable)hashAlgorithm).Dispose(); + } + } + + return result; + } + + /// + /// Get the list of transforms applied to the given part (works for Relationship parts too) + /// + /// part to get transforms for + /// possibly empty, ordered list of transforms applied to the given part (never null) + /// This method only returns transform names. Transform-specific properties can be obtained by parsing the actual + /// signature contents which conform to the W3C XmlDSig spec. + internal List GetPartTransformList(Uri partName) + { + // query the parsed manifest + ParsePackageDataObject(); + + List transformList = null; + + // look through the manifest for the requested part + foreach (PartManifestEntry entry in _partEntryManifest) + { + if (System.IO.Packaging.PackUriHelper.ComparePartUri(entry.Uri, partName) == 0) + { + transformList = entry.Transforms; + break; + } + } + + // never return null - an empty list is better form + if (transformList == null) + transformList = new List(); + + return transformList; + } + + //------------------------------------------------------ + // + // Internal Properties + // + //------------------------------------------------------ + + /// + /// Content type of signature parts created by this processor + /// + internal static ContentType ContentType + { + get + { + return _xmlSignaturePartType; + } + } + + + /// + /// Associated signature part + /// + internal PackagePart SignaturePart + { + get + { + return _signaturePart; + } + } + + + /// + /// Obtain the list of signed parts + /// + /// Authors identity in handler-proprietary format + /// if signature xml is malformed + internal List PartManifest + { + get + { + ParsePackageDataObject(); + return _partManifest; + } + } + + /// + /// Obtain the author's identity as a byte stream + /// + /// Authors identity in handler-proprietary format + /// if signature xml is malformed + internal List RelationshipManifest + { + get + { + ParsePackageDataObject(); + return _relationshipManifest; + } + } + + /// + /// Obtain the author's identity in X509 Certificate form + /// + /// Authors identity as a certificate in X509 form, or null if none found + internal X509Certificate2 Signer + { + get + { + // lazy init when loading existing cert - Sign may have assigned this for us + if (_certificate == null) + { + // first look for cert part + if (PackageSignature.GetCertificatePart() != null) + _certificate = PackageSignature.GetCertificatePart().GetCertificate(); + else + { + // look in signature + if (_lookForEmbeddedCert) + { + IEnumerator keyInfoClauseEnum = EnsureXmlSignatureParsed().KeyInfo.GetEnumerator(typeof(KeyInfoX509Data)); + while (keyInfoClauseEnum.MoveNext()) + { + KeyInfoX509Data x509Data = (KeyInfoX509Data)keyInfoClauseEnum.Current; + foreach (X509Certificate2 cert in x509Data.Certificates) + { + // just take the first one for now + _certificate = cert; + break; + } + + // just need one for now + if (_certificate != null) + break; + } + + // only need to do this once + _lookForEmbeddedCert = false; + } + } + } + + return _certificate; // may be null + } + } + + /// + /// encrypted hash value + /// + /// + internal byte[] SignatureValue + { + get + { + return EnsureXmlSignatureParsed().SignatureValue; + } + } + + /// + /// The object that actually creates the signature + /// Note: This API is exposed to the public API surface through the + /// PackageDigitalSignature.Signature property. Through this API it is + /// possible to create Signatures that are not OPC compliant. However, + /// at verify time, we will throw exceptions for non-conforming signatures. + /// + /// object of type System.Security.Cryptography.Xml.Signature + internal Signature Signature + { + get + { + return EnsureXmlSignatureParsed().Signature; + } + set + { + UpdatePartFromSignature(value); + } + } + + /// + /// Get the given signature + /// + internal PackageDigitalSignature PackageSignature + { + get + { + return _signature; + } + } + + /// + /// Time that the signature was created + /// + /// Time of signing if available, or DateTime.MinValue if signature was not time-stamped + internal DateTime SigningTime + { + get + { + // lazy init + ParsePackageDataObject(); + return _signingTime; + } + } + + internal String TimeFormat + { + get + { + // lazy init + ParsePackageDataObject(); + return _signingTimeFormat; + } + } + + //------------------------------------------------------ + // + // Digest Helper Functions + // + //------------------------------------------------------ + /// + /// Generate digest value tag + /// + /// + /// name of the single transform to use - may be null + /// hash algorithm to use + /// + internal static String GenerateDigestValue( + Stream s, + String transformName, + HashAlgorithm hashAlgorithm) + { + List transforms = null; + if (transformName != null) + { + transforms = new List(1); + transforms.Add(transformName); + } + return GenerateDigestValue(s, transforms, hashAlgorithm); + } + + /// + /// Generate digest value tag + /// + /// transforms to apply - may be null and list may contain empty strings + /// stream to hash + /// algorithm to use + internal static String GenerateDigestValue( + Stream s, + List transforms, + HashAlgorithm hashAlgorithm) + { + s.Seek(0, SeekOrigin.Begin); + + // We need to be able to dispose streams generated by the + // Transform object but we don't want to dispose the stream + // passed to us so we insert this to block any propagated Dispose() calls. + Stream transformStream = new IgnoreFlushAndCloseStream(s); + + List transformStreams = null; + + // canonicalize the part content if asked + if (transforms != null) + { + transformStreams = new List(transforms.Count); + transformStreams.Add(transformStream); + foreach (String transformName in transforms) + { + // ignore empty strings at this point (as well as Relationship Transforms) - these are legal + if ((transformName.Length == 0) + || (String.CompareOrdinal(transformName, XTable.Get(XTable.ID.RelationshipsTransformName)) == 0)) + { + continue; + } + + // convert the transform names into objects (if defined) + Transform transform = StringToTransform(transformName); + + if (transform == null) + { + // throw XmlException so the outer loop knows the signature is invalid + throw new XmlException(SR.Get(SRID.UnsupportedTransformAlgorithm)); + } + + transformStream = TransformXml(transform, transformStream); + transformStreams.Add(transformStream); + } + } + + // hash it and encode to Base64 + String hashValueString = System.Convert.ToBase64String(HashStream(hashAlgorithm, transformStream)); + + // dispose of any generated streams + if (transformStreams != null) + { + foreach (Stream stream in transformStreams) + stream.Close(); + } + + return hashValueString; + } + + /// + /// Synthesizes a NodeList of Reference tags to hash + /// + /// + /// + internal static Stream GenerateRelationshipNodeStream(IEnumerable relationships) + { + // create a NodeList containing valid Relationship XML and serialize it to the stream + Stream s = new MemoryStream(); + + // Wrap in a stream that ignores Flush and Close so the XmlTextWriter + // will not close it. + // use UTF-8 encoding by default + using (XmlTextWriter writer = new XmlTextWriter(new IgnoreFlushAndCloseStream(s), + System.Text.Encoding.UTF8)) + { + // start outer Relationships tag + writer.WriteStartElement(XTable.Get(XTable.ID.RelationshipsTagName), PackagingUtilities.RelationshipNamespaceUri); + + // generate a valid Relationship tag according to the Opc schema + InternalRelationshipCollection.WriteRelationshipsAsXml(writer, relationships, + true, /* systematically write target mode */ + false /* not in streaming production */ + ); + + // end of Relationships tag + writer.WriteEndElement(); + } + + return s; + } + + /// + /// Convert algorithm name to object + /// + /// fully specified name + /// HashAlgorithm object or null if it does not map to a supported hash type + /// Caller is responsible for calling Dispose() on returned object + internal static HashAlgorithm GetHashAlgorithm(String hashAlgorithmName) + { + Object o = CryptoConfig.CreateFromName(hashAlgorithmName); + HashAlgorithm algorithm = o as HashAlgorithm; + + // In the case that we get a valid crypto object that is not a hash algorithm + // we should attempt to dispose it if it offers IDisposable. + if (algorithm == null && o != null) + { + IDisposable disposable = o as IDisposable; + if (disposable != null) + disposable.Dispose(); + } + + return algorithm; + } + + /// + /// IMPORTANT NOTE: + /// 1. In the XmlDigitalSignatureProcessor.IsValidXmlCanonicalizationTransform method, + /// we have similar logic regarding these two transforms.So both these methods must be updated + /// in sync. + /// + private static Transform StringToTransform(String transformName) + { + Invariant.Assert(transformName != null); + + if (String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NTransformUrl) == 0) + { + return new XmlDsigC14NTransform(); + } + else if (String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NWithCommentsTransformUrl) == 0) + { + return new XmlDsigC14NWithCommentsTransform(); + } + else + return null; +} + + // As per the OPC spec, only two tranforms are valid. Also, both of these happen to be + // XML canonicalization transforms. + // In the XmlSignatureManifest.ParseTransformsTag method we make use this method to + // validate the transforms to make sure that they are supported by the OPC spec and + // we also take advantage of the fact that both of them are XML canonicalization transforms + // IMPORTANT NOTE: + // 1. In the XmlDigitalSignatureProcessor.StringToTransform method, we have similar logic + // regarding these two transforms.So both these methods must be updated in sync. + // 2. If ever this method is updated to add other transforms, careful review must be done to + // make sure that methods calling this method are updated as required. + internal static bool IsValidXmlCanonicalizationTransform(String transformName) + { + Invariant.Assert(transformName != null); + + if (String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NTransformUrl) == 0 || + String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NWithCommentsTransformUrl) == 0) + { + return true; + } + else + return false; + } + + //------------------------------------------------------ + // + // Private Properties + // + //------------------------------------------------------ + /// + /// Helper class + /// + private SignedXml EnsureXmlSignatureParsed() + { + // lazy init + if (_signedXml == null) + { + _signedXml = new CustomSignedXml(); + + // Load the XML + XmlDocument xmlDocument = new XmlDocument(); + xmlDocument.PreserveWhitespace = true; + using (Stream s = SignaturePart.GetSeekableStream()) + { + using (XmlTextReader xmlReader = new XmlTextReader(s)) + { + //Prohibit DTD from the markup as per the OPC spec + xmlReader.ProhibitDtd = true; + + //This method expects the reader to be in ReadState.Initial. + //It will make the first read call. + PackagingUtilities.PerformInitailReadAndVerifyEncoding(xmlReader); + + //If the reader.ReadState is ReadState.Initial, then XmlDocument with perform the + //first xmlReader.Read() and start loading from that node/tag. + //If the reader.ReadState is ReadState.Intermediate, then XmlDocument, will start + //loading from that location itself. + //Note: Since in the above method we perform only the first read and will have not + //moved the reader state further down in the markup, we should be okay, and + //xmlDocument.Load will load from the very begining as intended. + xmlDocument.Load(xmlReader); + + // W3C spec allows for Signature tag to appear as an island and inherently allows + // for multiple Signature tags within the same XML document. + // OPC restricts this to a single, root-level Signature tag. However, Signature + // tags are allowed to exist within the non-OPC Object tags within an OPC signature. + // This is common for XAdES signatures and must be explicitly allowed. + XmlNodeList nodeList = xmlDocument.ChildNodes; + if (nodeList == null || nodeList.Count == 0 || nodeList.Count > 2) + throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); + + XmlNode node = nodeList[0]; + if (nodeList.Count == 2) + { + // First node must be the XmlDeclaration + if (nodeList[0].NodeType != XmlNodeType.XmlDeclaration) + throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); + + // Second node must be in the w3c namespace, and must be the tag + node = nodeList[1]; + } + + if ((node.NodeType != XmlNodeType.Element) || + (String.CompareOrdinal(node.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) != 0) || + (String.CompareOrdinal(node.LocalName, XTable.Get(XTable.ID.SignatureTagName)) != 0)) + { + throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); + } + + // instantiate the SignedXml from the xmlDoc + _signedXml.LoadXml((XmlElement)node); + } + } + } + + // As per the OPC spec, only two Canonicalization methods can be specified + if (!IsValidXmlCanonicalizationTransform(_signedXml.SignedInfo.CanonicalizationMethod)) + throw new XmlException(SR.Get(SRID.UnsupportedCanonicalizationMethod)); + + // As per OPC spec, signature ID must be NCName + if (_signedXml.Signature.Id != null) + { + try + { + System.Xml.XmlConvert.VerifyNCName(_signedXml.Signature.Id); + } + catch (System.Xml.XmlException) + { + throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); + } + } + + return _signedXml; + } + + //------------------------------------------------------ + // + // Private Methods + // + //------------------------------------------------------ + + /// + /// Constructor - called from public constructor as well as static Sign() method + /// + /// current DigitalSignatureManager + /// the part that will/does house the associated XML signature + private XmlDigitalSignatureProcessor(PackageDigitalSignatureManager manager, + PackagePart signaturePart) + { + Invariant.Assert(manager != null); + Invariant.Assert(signaturePart != null); + + _signaturePart = signaturePart; + _manager = manager; + _lookForEmbeddedCert = true; + } + + /// + /// Create a new PackageDigitalSignature + /// + /// the data being protected by this signature + /// possibly null collection of relationshipSelectors that represent the + /// relationships that are to be signed + /// Identity of the author + /// Id attribute of the new Xml Signature + /// true if caller wants certificate embedded in the signature itself + /// references + /// objects to sign + private PackageDigitalSignature Sign( + IEnumerable parts, + IEnumerable relationshipSelectors, + X509Certificate2 signer, + String signatureId, + bool embedCertificate, + IEnumerable signatureObjects, + IEnumerable objectReferences) + { + // don't overwrite +#if DEBUG + using (Stream stream = SignaturePart.GetStream()) + { + Debug.Assert(stream.Length == 0, "Logic Error: Can't sign when signature already exists"); + } +#endif + + // grab hash algorithm as this may change in the future + _hashAlgorithmName = _manager.HashAlgorithm; + + // keep the signer if indicated + if (_manager.CertificateOption == CertificateEmbeddingOption.NotEmbedded) + _lookForEmbeddedCert = false; // don't bother parsing + else + _certificate = signer; // save some parsing + + // we only release this key if we obtain it + AsymmetricAlgorithm key = null; + if (signer.HasPrivateKey) + { + key = GetPrivateKey(signer); + } + else + { + key = GetPrivateKeyForSigning(signer); + } + + try + { + _signedXml = new CustomSignedXml(); + _signedXml.SigningKey = key; + _signedXml.Signature.Id = signatureId; + + if (BaseCompatibilityPreferences.MatchPackageSignatureMethodToPackagePartDigestMethod) + { + // Defaulting to SHA1 for key signing is counter-productive if the hash algorithm + // for the rest of the package is more secure. So if we have a selected hash + // algorithm in the PackageDigitalSignatureManager that is more secure, then + // select an equivalent level algorithm for key signing. + _signedXml.SignedInfo.SignatureMethod = SelectSignatureMethod(key); + } + + // Track if we are matching the signature method in order to retry on failure + bool usingMatchingSignatureMethod = _signedXml.SignedInfo.SignatureMethod != null; + + // put it in the XML + if (embedCertificate) + { + _signedXml.KeyInfo = GenerateKeyInfo(key, signer); + } + + // Package object tag + // convert from string to class and ensure we dispose + using (HashAlgorithm hashAlgorithm = GetHashAlgorithm(_hashAlgorithmName)) + { + // inform caller if hash algorithm is unknown + if (hashAlgorithm == null) + throw new InvalidOperationException(SR.Get(SRID.UnsupportedHashAlgorithm)); + + _signedXml.AddObject(GenerateObjectTag(hashAlgorithm, parts, relationshipSelectors, signatureId)); + } + + // add reference from SignedInfo to Package object tag + Reference objectReference = new Reference(XTable.Get(XTable.ID.OpcLinkAttrValue)); + objectReference.Type = XTable.Get(XTable.ID.W3CSignatureNamespaceRoot) + "Object"; + objectReference.DigestMethod = _hashAlgorithmName; + _signedXml.AddReference(objectReference); + + // add any custom object tags + AddCustomObjectTags(signatureObjects, objectReferences); + + // compute the signature + SignedXml xmlSig = _signedXml; + + try + { + xmlSig.ComputeSignature(); + } + catch (CryptographicException) when (usingMatchingSignatureMethod) + { + // We've hit a state where System.Security is possibly missing the required updates to process the matched signature. + // Disable our matching and attempt to sign again with the default SignatureMethod + BaseCompatibilityPreferences.MatchPackageSignatureMethodToPackagePartDigestMethod = false; + xmlSig.SignedInfo.SignatureMethod = null; + xmlSig.ComputeSignature(); + } + + // persist + UpdatePartFromSignature(_signedXml.Signature); + } + finally + { + if (key != null) + ((IDisposable)key).Dispose(); + } + + // create the PackageDigitalSignature object + _signature = new PackageDigitalSignature(_manager, this); + return _signature; + } + + /// + /// Attempt to select a key signing method that matches the strength of the selected + /// hash algorithm in the PackageDigitalSignatureManager. + /// + /// If no algorithm was selected, defaults to SHA1. + /// + /// + /// DSA keys have no supported stronger signing solution and are always SHA1 signed. + /// + /// The key being used + /// The URI of the appropriate signing method + private string SelectSignatureMethod(AsymmetricAlgorithm key) + { + string signatureMethod = null; + + if (key is RSA) + { + _rsaSigMethodLookup.TryGetValue(_manager.HashAlgorithm, out signatureMethod); + } + + return signatureMethod; + } + + /// + /// Extracts the private key from the X509Certificate2 certificate + /// + /// certificate for which we are looking for the private key + /// returns the private key + private static AsymmetricAlgorithm GetPrivateKey(X509Certificate2 cert) + { + // Adding support for CNG certificates. The default certificate template in Windows Server 2008+ is CNG + // Get[Algorithm]PrivateKey methods returns unique object while PrivateKey property returns shared one + // Make sure to dispose the key if it is from Get[Algorithm]PrivateKey methods + AsymmetricAlgorithm key = cert.GetRSAPrivateKey(); + if (key != null) + return key; + + key = cert.GetDSAPrivateKey(); + if (key != null) + return key; + + key = cert.GetECDsaPrivateKey(); + if (key != null) + return key; + + // Get[Algorithm]PrivateKey methods would always have returned the private key if the PrivateKey property would + // But Get[Algorithm]PrivateKey methods never throw but returns null in case of error during cryptographic operations + // But we want exception to be thrown when an error occurs during a cryptographic operation so that we can revert the changes + return cert.PrivateKey; + } + + /// + /// Assembles the sorted list of relationships for this part entry and + /// generates a stream with the Xml-equivalent as defined in the Opc spec + /// + /// relationship-type part entry + /// + private Stream GetRelationshipStream(PartManifestEntry partEntry) + { + Debug.Assert(partEntry.IsRelationshipEntry); + + //Get the list of relationships from the RelationshipSelectors for this part + SortedDictionary partRelationships = + new SortedDictionary(StringComparer.Ordinal); + foreach (System.IO.Packaging.PackageRelationshipSelector relationshipSelector in partEntry.RelationshipSelectors) + { + foreach (System.IO.Packaging.PackageRelationship r in relationshipSelector.Select(_manager.Package)) + { + if(!partRelationships.ContainsKey(r.Id)) + partRelationships.Add(r.Id, r); + } + } + + return GenerateRelationshipNodeStream(partRelationships.Values); + } + + private void AddCustomObjectTags(IEnumerable signatureObjects, + IEnumerable objectReferences) + { + Invariant.Assert(_signedXml != null); + + + // add any references + if (objectReferences != null) + { + // Validate the Reference tags in the SignedInfo as per the + // restrictions imposed by the OPC spec + ValidateReferences(objectReferences, false /*allowPackageSpecificReference*/); + + foreach (Reference reference in objectReferences) + { + // consistent hash algorithm for entire signature + reference.DigestMethod = _hashAlgorithmName; + _signedXml.AddReference(reference); + } + } + + // any object tags + if (signatureObjects != null) + { + // thes have been pre-screened for matches against reserved OpcAttrValue and duplicates + foreach (DataObject obj in signatureObjects) + { + _signedXml.AddObject(obj); + } + } + } + + private void UpdatePartFromSignature(Signature sig) + { + // write to stream + using (Stream s = SignaturePart.GetSeekableStream(FileMode.Create, FileAccess.Write)) + { + using (XmlTextWriter xWriter = new XmlTextWriter(s, System.Text.Encoding.UTF8)) + { + xWriter.WriteStartDocument(true); + sig.GetXml().WriteTo(xWriter); + xWriter.WriteEndDocument(); + } + } + _signedXml = null; // force a re-parse + } + + private static byte[] HashStream(HashAlgorithm hashAlgorithm, Stream s) + { + s.Seek(0, SeekOrigin.Begin); + + // reset algorithm + hashAlgorithm.Initialize(); + return hashAlgorithm.ComputeHash(s); + } + + private static Stream TransformXml(Transform xForm, Object source) + { + // transform + xForm.LoadInput(source); + + return (Stream)xForm.GetOutput(); + } + + /// + /// Full parse of the Package-specific Object tag + /// + /// Side effect of updating _signingTime, _signingTimeFormat, + /// _partManifest, _partEntryManifest and _relationshipManifest + /// throws if markup does not match OPC spec + private void ParsePackageDataObject() + { + if (!_dataObjectParsed) + { + EnsureXmlSignatureParsed(); + + // find the package-specific Object tag + XmlNodeList nodeList = GetPackageDataObject().Data; + + // The legal parent is a "Package" Object tag with 2 children + // and + if (nodeList.Count != 2) + throw new XmlException(SR.Get(SRID.XmlSignatureParseError)); + + // get a NodeReader that allows us to easily and correctly skip comments + XmlReader reader = new XmlNodeReader(nodeList[0].ParentNode); + + // parse the tag - ensure that it is in the correct namespace + reader.Read(); // enter the Object tag + if (String.CompareOrdinal(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) != 0) + throw new XmlException(SR.Get(SRID.XmlSignatureParseError)); + + string signaturePropertiesTagName = XTable.Get(XTable.ID.SignaturePropertiesTagName); + string manifestTagName = XTable.Get(XTable.ID.ManifestTagName); + bool signaturePropertiesTagFound = false; + bool manifestTagFound = false; + while (reader.Read() && (reader.NodeType == XmlNodeType.Element)) + { + if (reader.MoveToContent() == XmlNodeType.Element + && (String.CompareOrdinal(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) == 0) + && reader.Depth == 1) + { + if (!signaturePropertiesTagFound && String.CompareOrdinal(reader.LocalName, signaturePropertiesTagName) == 0) + { + signaturePropertiesTagFound = true; + + // parse the tag + _signingTime = XmlSignatureProperties.ParseSigningTime( + reader, _signedXml.Signature.Id, out _signingTimeFormat); + + continue; + } + else if (!manifestTagFound && String.CompareOrdinal(reader.LocalName, manifestTagName) == 0) + { + manifestTagFound = true; + + // parse the tag + XmlSignatureManifest.ParseManifest(_manager, reader, + out _partManifest, out _partEntryManifest, out _relationshipManifest); + + continue; + } + } + + throw new XmlException(SR.Get(SRID.XmlSignatureParseError)); + } + + // these must both exist on exit + if (!(signaturePropertiesTagFound && manifestTagFound)) + throw new XmlException(SR.Get(SRID.XmlSignatureParseError)); + + _dataObjectParsed = true; + } + } + + /// + /// Finds and return the package-specific Object tag + /// + /// + private DataObject GetPackageDataObject() + { + EnsureXmlSignatureParsed(); + + // look for the Package-specific object tag + String opcId = XTable.Get(XTable.ID.OpcAttrValue); + DataObject returnValue = null; + foreach (DataObject dataObject in _signedXml.Signature.ObjectList) + { + if (String.CompareOrdinal(dataObject.Id, opcId) == 0) + { + // duplicates not allowed + if (returnValue != null) + throw new XmlException(SR.Get(SRID.SignatureObjectIdMustBeUnique)); + + returnValue = dataObject; + } + } + + // Package object tag required + if (returnValue != null) + return returnValue; + else + throw new XmlException(SR.Get(SRID.PackageSignatureObjectTagRequired)); + } + + private KeyInfo GenerateKeyInfo(AsymmetricAlgorithm key, X509Certificate2 signer) + { + // KeyInfo section + KeyInfo keyInfo = new KeyInfo(); + KeyInfoName keyInfoName = new KeyInfoName(); + keyInfoName.Value = signer.Subject; + keyInfo.AddClause(keyInfoName); // human readable Principal name + + // Include the public key information (if we are familiar with the algorithm type) + if (key is RSA) + keyInfo.AddClause(new RSAKeyValue((RSA)key)); // RSA key parameters + else + { + if (key is DSA) + keyInfo.AddClause(new DSAKeyValue((DSA)key)); // DSA + else + throw new ArgumentException(SR.Get(SRID.CertificateKeyTypeNotSupported), "signer"); + } + + // the actual X509 cert + keyInfo.AddClause(new KeyInfoX509Data(signer)); + + return keyInfo; + } + + private DataObject GenerateObjectTag( + HashAlgorithm hashAlgorithm, + IEnumerable parts, IEnumerable relationshipSelectors, + String signatureId) + { + XmlDocument xDoc = new XmlDocument(); + xDoc.AppendChild(xDoc.CreateNode(XmlNodeType.Element, "root", "namespace")); // dummy root + xDoc.DocumentElement.AppendChild(XmlSignatureManifest.GenerateManifest(_manager, xDoc, hashAlgorithm, parts, relationshipSelectors)); + xDoc.DocumentElement.AppendChild(XmlSignatureProperties.AssembleSignatureProperties(xDoc, DateTime.Now, _manager.TimeFormat, signatureId)); + + DataObject dataObject = new DataObject(); + dataObject.Data = xDoc.DocumentElement.ChildNodes; + dataObject.Id = XTable.Get(XTable.ID.OpcAttrValue); + + return dataObject; + } + + /// + /// lookup the private key using the given identity + /// + /// X509Cert + /// IDisposable asymmetric algorithm that serves as a proxy to the private key. Caller must dispose + /// of properly. + private static AsymmetricAlgorithm GetPrivateKeyForSigning(X509Certificate2 signer) + { + // if the certificate does not actually contain the key, we need to look it up via ThumbPrint + Invariant.Assert(!signer.HasPrivateKey); + + // look for appropriate certificates + X509Store store = new X509Store(StoreLocation.CurrentUser); + + try + { + store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); + + X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; + + collection = collection.Find(X509FindType.FindByThumbprint, signer.Thumbprint, true); + if (collection.Count > 0) + { + if (collection.Count > 1) + throw new CryptographicException(SR.Get(SRID.DigSigDuplicateCertificate)); + + signer = collection[0]; + } + else + throw new CryptographicException(SR.Get(SRID.DigSigCannotLocateCertificate)); + } + finally + { + store.Close(); + } + + // get the corresponding AsymmetricAlgorithm + return GetPrivateKey(signer); + } + + + /// + /// This method validated the Reference tags as per the restrictions imposed + /// by the OPC spec. + /// NOTE: The same method is called from Verify and Sign methods. At verify time we need to make sure + /// that there is exactly one Package-specific reference. At Sign time we need to make sure that + /// there are no package-specific references in the list of references passed to Sign APIs as a + /// input parameter, since we will be generating Package-specific object. + /// + /// list of references to be validated + /// When "true", we check to make sure that there is + /// exactly one package-specific reference and when "false", we do not allow any package-specific + /// references + private void ValidateReferences(IEnumerable references, bool allowPackageSpecificReferences) + { + Debug.Assert(references != null); + + bool packageReferenceFound = false; + TransformChain currentTransformChain; + + foreach (Reference currentReference in references) + { + //As per the OPC spec, Uri attribute in Reference elements MUST refer using fragment identifiers + //This implies that Uri cannot be absolute. + if (currentReference.Uri.StartsWith("#", StringComparison.Ordinal)) + { + //As per the OPC spec, there MUST be exactly one package specific reference to the + //package specific element + if (String.CompareOrdinal(currentReference.Uri, XTable.Get(XTable.ID.OpcLinkAttrValue)) == 0) + { + if (!allowPackageSpecificReferences) + throw new ArgumentException(SR.Get(SRID.PackageSpecificReferenceTagMustBeUnique)); + + //If there are more than one package specific tags + if (packageReferenceFound == true) + throw new XmlException(SR.Get(SRID.MoreThanOnePackageSpecificReference)); + else + packageReferenceFound = true; + } + + currentTransformChain = currentReference.TransformChain; + + for(int j=0; j _partManifest; // signed parts (suitable for return to public API) + private List _partEntryManifest; // signed parts (with extra info) + private List _relationshipManifest; // signed relationship selectors + + private static readonly ContentType _xmlSignaturePartType + = new ContentType("application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml"); + + /// + /// Mapping from hash algorithms in the PackageDigitalSignatureManager to RSA key signing methods. + /// + private static readonly Dictionary _rsaSigMethodLookup = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "http://www.w3.org/2001/04/xmlenc#sha256", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" }, + { "http://www.w3.org/2001/04/xmldsig-more#sha384", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384" }, + { "http://www.w3.org/2001/04/xmlenc#sha512", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512" }, + }; + } +} + diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlSignatureManifest.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlSignatureManifest.cs index f3d2cf2c11a..b4af9e3a751 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlSignatureManifest.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlSignatureManifest.cs @@ -783,7 +783,7 @@ private static XmlNode GeneratePartSigningReference( reference.AppendChild(GenerateDigestMethod(manager, xDoc)); // - using (Stream s = part.GetStream(FileMode.Open, FileAccess.Read)) + using (Stream s = part.GetSeekableStream(FileMode.Open, FileAccess.Read)) { reference.AppendChild(GenerateDigestValueNode(xDoc, hashAlgorithm, s, transformName)); } diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Collections/ObjectModel/WeakReadOnlyCollection.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Collections/ObjectModel/WeakReadOnlyCollection.cs index 03e05cb52f1..160cfaebf6f 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Collections/ObjectModel/WeakReadOnlyCollection.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Collections/ObjectModel/WeakReadOnlyCollection.cs @@ -39,7 +39,7 @@ internal class WeakReadOnlyCollection: IList, IList public WeakReadOnlyCollection(IList list) { // assumption: the WRs in list refer to T's if (list == null) { - throw new ArgumentNullException("list"); + throw new ArgumentNullException(nameof(list)); } this.list = list; } @@ -145,9 +145,9 @@ object ICollection.SyncRoot { } void ICollection.CopyTo(Array array, int index) { - if (array==null) { + if (array == null) { //ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); - throw new ArgumentNullException("array"); + throw new ArgumentNullException(nameof(array)); } if (array.Rank != 1) { @@ -162,7 +162,7 @@ void ICollection.CopyTo(Array array, int index) { if (index < 0) { //ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); - throw new ArgumentOutOfRangeException("index", SR.Get(SRID.ArgumentOutOfRange_NeedNonNegNum)); + throw new ArgumentOutOfRangeException(nameof(index), SR.Get(SRID.ArgumentOutOfRange_NeedNonNegNum)); } if (array.Length - index < Count) { diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/ComponentModel/DependencyPropertyDescriptor.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/ComponentModel/DependencyPropertyDescriptor.cs index 95fd8d32f66..acc8b8dba1d 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/ComponentModel/DependencyPropertyDescriptor.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/ComponentModel/DependencyPropertyDescriptor.cs @@ -66,12 +66,12 @@ private DependencyPropertyDescriptor(PropertyDescriptor property, string name, T /// public static DependencyPropertyDescriptor FromProperty(PropertyDescriptor property) { - if (property == null) throw new ArgumentNullException("property"); + if (property == null) throw new ArgumentNullException(nameof(property)); DependencyPropertyDescriptor dpd; bool found; - lock(_cache) + lock (_cache) { found = _cache.TryGetValue(property, out dpd); } @@ -98,7 +98,7 @@ public static DependencyPropertyDescriptor FromProperty(PropertyDescriptor prope } else { - #pragma warning suppress 6506 // property is obviously not null + #pragma warning suppress 6506 // Property is obviously not null. DependencyPropertyAttribute dpa = property.Attributes[typeof(DependencyPropertyAttribute)] as DependencyPropertyAttribute; if (dpa != null) { @@ -129,8 +129,8 @@ public static DependencyPropertyDescriptor FromProperty(PropertyDescriptor prope /// internal static DependencyPropertyDescriptor FromProperty(DependencyProperty dependencyProperty, Type ownerType, Type targetType, bool ignorePropertyType) { - if (dependencyProperty == null) throw new ArgumentNullException("dependencyProperty"); - if (targetType == null) throw new ArgumentNullException("targetType"); + if (dependencyProperty == null) throw new ArgumentNullException(nameof(dependencyProperty)); + if (targetType == null) throw new ArgumentNullException(nameof(targetType)); // We have a different codepath here for attached and direct // properties. For direct properties, we route through Type @@ -196,8 +196,8 @@ internal static DependencyPropertyDescriptor FromProperty(DependencyProperty dep /// public static DependencyPropertyDescriptor FromProperty(DependencyProperty dependencyProperty, Type targetType) { - if (dependencyProperty == null) throw new ArgumentNullException("dependencyProperty"); - if (targetType == null) throw new ArgumentNullException("targetType"); + if (dependencyProperty == null) throw new ArgumentNullException(nameof(dependencyProperty)); + if (targetType == null) throw new ArgumentNullException(nameof(targetType)); // We have a different codepath here for attached and direct // properties. For direct properties, we route through Type @@ -216,7 +216,7 @@ public static DependencyPropertyDescriptor FromProperty(DependencyProperty depen // For direct properties we don't want to get the property descriptor // yet because it is very expensive. Delay it until needed. - lock(_cache) + lock (_cache) { _cache.TryGetValue(dependencyProperty, out dpd); } @@ -229,7 +229,7 @@ public static DependencyPropertyDescriptor FromProperty(DependencyProperty depen dpd = new DependencyPropertyDescriptor(null, dependencyProperty.Name, targetType, dependencyProperty, false); - lock(_cache) + lock (_cache) { _cache[dependencyProperty] = dpd; } @@ -259,9 +259,9 @@ public static DependencyPropertyDescriptor FromProperty(DependencyProperty depen /// public static DependencyPropertyDescriptor FromName(string name, Type ownerType, Type targetType) { - if (name == null) throw new ArgumentNullException("name"); - if (ownerType == null) throw new ArgumentNullException("ownerType"); - if (targetType == null) throw new ArgumentNullException("targetType"); + if (name == null) throw new ArgumentNullException(nameof(name)); + if (ownerType == null) throw new ArgumentNullException(nameof(ownerType)); + if (targetType == null) throw new ArgumentNullException(nameof(targetType)); DependencyProperty dp = DependencyProperty.FromName(name, ownerType); if (dp != null) @@ -282,9 +282,9 @@ public static DependencyPropertyDescriptor FromName(string name, Type ownerType, public static DependencyPropertyDescriptor FromName(string name, Type ownerType, Type targetType, bool ignorePropertyType) { - if (name == null) throw new ArgumentNullException("name"); - if (ownerType == null) throw new ArgumentNullException("ownerType"); - if (targetType == null) throw new ArgumentNullException("targetType"); + if (name == null) throw new ArgumentNullException(nameof(name)); + if (ownerType == null) throw new ArgumentNullException(nameof(ownerType)); + if (targetType == null) throw new ArgumentNullException(nameof(targetType)); DependencyProperty dp = DependencyProperty.FromName(name, ownerType); if (dp != null) @@ -493,7 +493,7 @@ public override TypeConverter Converter { // We only support public type converters, in order to avoid asserts. TypeConverter typeConverter = Property.Converter; - if( typeConverter.GetType().IsPublic ) + if (typeConverter.GetType().IsPublic) { return typeConverter; } diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Interop/ComponentDispatcher.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Interop/ComponentDispatcher.cs index c68053bbe91..3eac991fc67 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Interop/ComponentDispatcher.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Interop/ComponentDispatcher.cs @@ -61,9 +61,6 @@ private static ComponentDispatcherThread CurrentThreadData /// Returns true if one or more components has gone modal. /// Although once one component is modal a 2nd shouldn't. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public static bool IsThreadModal { get @@ -76,9 +73,6 @@ public static bool IsThreadModal /// /// Returns "current" message. More exactly the last MSG Raised. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public static MSG CurrentKeyboardMessage { get @@ -110,9 +104,6 @@ internal static MSG UnsecureCurrentKeyboardMessage /// /// A component calls this to go modal. Current thread wide only. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public static void PushModal() { CriticalPushModal(); @@ -130,9 +121,6 @@ internal static void CriticalPushModal() /// /// A component calls this to end being modal. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public static void PopModal() { CriticalPopModal(); @@ -150,9 +138,6 @@ internal static void CriticalPopModal() /// /// The message loop pumper calls this when it is time to do idle processing. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")] public static void RaiseIdle() { @@ -163,9 +148,6 @@ public static void RaiseIdle() /// /// The message loop pumper calls this for every keyboard message. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")] [SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")] public static bool RaiseThreadMessage(ref MSG msg) @@ -180,9 +162,6 @@ public static bool RaiseThreadMessage(ref MSG msg) /// Components register delegates with this event to handle /// thread idle processing. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public static event EventHandler ThreadIdle { add { @@ -197,9 +176,6 @@ public static event EventHandler ThreadIdle /// Components register delegates with this event to handle /// Keyboard Messages (first chance processing). /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// [SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")] public static event ThreadMessageEventHandler ThreadFilterMessage { @@ -215,9 +191,6 @@ public static event ThreadMessageEventHandler ThreadFilterMessage /// Components register delegates with this event to handle /// Keyboard Messages (second chance processing). /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// [SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")] public static event ThreadMessageEventHandler ThreadPreprocessMessage { @@ -252,9 +225,6 @@ internal static void CriticalRemoveThreadPreprocessMessageHandlerFirst(ThreadMes /// Components register delegates with this event to handle /// a component on this thread has "gone modal", when previously none were. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public static event EventHandler EnterThreadModal { add { @@ -269,9 +239,6 @@ public static event EventHandler EnterThreadModal /// Components register delegates with this event to handle /// all components on this thread are done being modal. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public static event EventHandler LeaveThreadModal { add diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/Dispatcher.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/Dispatcher.cs index d61a4514445..b494828f349 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/Dispatcher.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/Dispatcher.cs @@ -243,9 +243,6 @@ public void BeginInvokeShutdown(DispatcherPriority priority) // NOTE: should be /// /// Begins the process of shutting down the dispatcher. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public void InvokeShutdown() { @@ -295,7 +292,6 @@ public bool HasShutdownFinished /// /// /// This frame will continue until the dispatcher is shut down. - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// public static void Run() { @@ -308,9 +304,6 @@ public static void Run() /// /// The frame for the dispatcher to process. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public static void PushFrame(DispatcherFrame frame) { if(frame == null) @@ -340,9 +333,6 @@ public static void PushFrame(DispatcherFrame frame) /// /// Requests that all nested frames exit. /// - /// - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. - /// public static void ExitAllFrames() { @@ -1598,7 +1588,6 @@ public static void ValidatePriority(DispatcherPriority priority, string paramete ///

/// This method is public so that any thread can probe to /// see if it has access to the DispatcherObject. - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// /// /// True if the calling thread has access to this object. @@ -1637,7 +1626,6 @@ public DispatcherHooks Hooks /// creating secondary exceptions and to catch any that occur. /// It is recommended to avoid allocating memory or doing any /// heavylifting if possible. - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// public event DispatcherUnhandledExceptionFilterEventHandler UnhandledExceptionFilter { @@ -1849,11 +1837,6 @@ private void StartShutdownImpl() // Because we may have to defer the actual shutting-down until // later, we need to remember the execution context we started // the shutdown from. - // - // Note that we demanded permissions when BeginInvokeShutdown - // or InvokeShutdown were called. So if there were not enough - // permissions, we would have thrown then. - // CulturePreservingExecutionContext shutdownExecutionContext = CulturePreservingExecutionContext.Capture(); _shutdownExecutionContext = new SecurityCriticalDataClass(shutdownExecutionContext); diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/DispatcherHooks.cs b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/DispatcherHooks.cs index 000230c5ec1..27d4aa1cd17 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/DispatcherHooks.cs +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Threading/DispatcherHooks.cs @@ -20,7 +20,6 @@ public sealed class DispatcherHooks ///

/// Note also that this event could come before the last operation is /// invoked, because that is when we determine that the queue is empty. - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// public event EventHandler DispatcherInactive { @@ -51,7 +50,6 @@ public event EventHandler DispatcherInactive ///

/// Note that any thread can post operations, so this event can be /// raised by any thread. - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// public event DispatcherHookEventHandler OperationPosted { @@ -82,7 +80,6 @@ public event DispatcherHookEventHandler OperationPosted ///

/// Note that any thread can post operations, so this event can be /// raised by any thread. - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// public event DispatcherHookEventHandler OperationStarted { @@ -113,7 +110,6 @@ public event DispatcherHookEventHandler OperationStarted /// /// Note that this event will be raised by the dispatcher thread after /// the operation has completed. - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// public event DispatcherHookEventHandler OperationCompleted { @@ -139,7 +135,6 @@ public event DispatcherHookEventHandler OperationCompleted /// /// Note that any thread can change the priority of operations, /// so this event can be raised by any thread. - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// public event DispatcherHookEventHandler OperationPriorityChanged { @@ -165,7 +160,6 @@ public event DispatcherHookEventHandler OperationPriorityChanged /// /// Note that any thread can abort an operation, so this event /// can be raised by any thread. - /// Callers must have UIPermission(PermissionState.Unrestricted) to call this API. /// public event DispatcherHookEventHandler OperationAborted { diff --git a/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj b/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj index f5cc90b0a55..871caa101d6 100644 --- a/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj +++ b/src/Microsoft.DotNet.Wpf/src/WindowsBase/WindowsBase.csproj @@ -40,6 +40,7 @@ + diff --git a/src/Microsoft.DotNet.Wpf/test/Common/DRT/TestServices/DrtBaseInput.cs b/src/Microsoft.DotNet.Wpf/test/Common/DRT/TestServices/DrtBaseInput.cs index 5f9304c70a8..85a54108f6a 100644 --- a/src/Microsoft.DotNet.Wpf/test/Common/DRT/TestServices/DrtBaseInput.cs +++ b/src/Microsoft.DotNet.Wpf/test/Common/DRT/TestServices/DrtBaseInput.cs @@ -371,6 +371,7 @@ internal class InternalNativeMethods public const int KEYEVENTF_UNICODE = 0x0004; public const int KEYEVENTF_SCANCODE = 0x0008; + public const int MOUSEEVENTF_MOVE_NOCOALESCE = 0x2000; public const int MOUSEEVENTF_VIRTUALDESK = 0x4000; public const int INPUT_MOUSE = 0; @@ -483,6 +484,12 @@ public static void SendMouseInput( double x, double y, int data, SendMouseInputF intflags |= InternalNativeMethods.MOUSEEVENTF_VIRTUALDESK; } + + // don't coalesce mouse moves - tests expect to see the results immediately + if ((intflags & (int)SendMouseInputFlags.Move) != 0) + { + intflags |= InternalNativeMethods.MOUSEEVENTF_MOVE_NOCOALESCE; + } InternalUnsafeNativeMethods.INPUT mi = new InternalUnsafeNativeMethods.INPUT(); mi.type = InternalNativeMethods.INPUT_MOUSE; @@ -495,6 +502,14 @@ public static void SendMouseInput( double x, double y, int data, SendMouseInputF //Console.WriteLine("Sending"); if ( InternalUnsafeNativeMethods.SendInput( 1, ref mi, Marshal.SizeOf( mi ) ) == 0 ) throw new Win32Exception( Marshal.GetLastWin32Error() ); + + if ((intflags & (int)SendMouseInputFlags.Wheel) != 0) + { + // MouseWheel input seems to be getting coalesced by the OS, similar to mouse-move. + // There isn't a NOCOALESCE flag to turn this off, so instead just sleep for + // a short time, hopefully enough to avoid the coalescing. + System.Threading.Thread.Sleep(50); + } }