diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index c155a5dad..d15a7c2fa 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1677,7 +1677,6 @@ namespace Microsoft.PowerShell.Commands /// /// /// - [ArchitectureSensitive] protected override void ProcessRecord() { @@ -2065,7 +2064,6 @@ namespace Microsoft.PowerShell.Commands /// /// Create the service /// - [ArchitectureSensitive] protected override void BeginProcessing() { Diagnostics.Assert(!String.IsNullOrEmpty(Name), diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs index 6c61c44b5..929ee0e16 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs @@ -490,13 +490,6 @@ namespace Microsoft.PowerShell.Commands internal bool referencedAssembliesSpecified = false; internal string[] referencedAssemblies = Utils.EmptyArray(); - /// - /// Resolve referenced assembly from name or path to a platform specific form. - /// - /// - /// - internal abstract string ResolveReferencedAssembly(string referencedAssembly); - /// /// The path to the output assembly /// @@ -998,7 +991,14 @@ namespace Microsoft.PowerShell.Commands { foreach (string assemblyName in assemblies) { - Assembly assembly = LoadFrom(ResolveReferencedAssembly(assemblyName)); + // CoreCLR doesn't allow re-load TPA assemblis with different API (i.e. we load them by name and now want to load by path). + // LoadAssemblyHelper helps us avoid re-loading them, if they already loaded. + Assembly assembly = LoadAssemblyHelper(assemblyName); + if (assembly == null) + { + assembly = LoadFrom(ResolveReferencedAssembly(assemblyName)); + } + if (passThru) { WriteTypes(assembly); @@ -1072,7 +1072,7 @@ namespace Microsoft.PowerShell.Commands private bool InMemory { get { return String.IsNullOrEmpty(outputAssembly); } } - internal override string ResolveReferencedAssembly(string referencedAssembly) + private string ResolveReferencedAssembly(string referencedAssembly) { // if it's a path, resolve it if (referencedAssembly.Contains(System.IO.Path.DirectorySeparatorChar) || referencedAssembly.Contains(System.IO.Path.AltDirectorySeparatorChar)) @@ -1143,6 +1143,9 @@ namespace Microsoft.PowerShell.Commands // Generates a FileNotFoundException if you can't load the strong type. // So we'll try from the short name. catch (System.IO.FileNotFoundException) { } + // File load exception can happen, when we trying to load from the incorrect assembly name + // or file corrupted. + catch (System.IO.FileLoadException) { } if (loadedAssembly != null) return loadedAssembly; @@ -1339,7 +1342,7 @@ namespace Microsoft.PowerShell.Commands // Internal mapping table from the shortcut name to the strong name private static readonly Lazy> StrongNames = new Lazy>(InitializeStrongNameDictionary); - internal override string ResolveReferencedAssembly(string referencedAssembly) + private string ResolveReferencedAssembly(string referencedAssembly) { if (!String.Equals(System.IO.Path.GetExtension(referencedAssembly), ".dll", StringComparison.OrdinalIgnoreCase)) { diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs index cf5868ce2..553c2b300 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/SetDateCommand.cs @@ -83,7 +83,6 @@ namespace Microsoft.PowerShell.Commands /// /// set the date /// - [ArchitectureSensitive] protected override void ProcessRecord() { DateTime dateToUse; diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs index 53136bbb8..61a4012d6 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs @@ -1359,7 +1359,7 @@ namespace Microsoft.PowerShell inputFormat = cpp.InputFormat; wasInitialCommandEncoded = cpp.WasInitialCommandEncoded; - ui.ReadFromStdin = cpp.ExplicitReadCommandsFromStdin || Console.IsInputRedirected; + ui.ReadFromStdin = cpp.ExplicitReadCommandsFromStdin || (Console.IsInputRedirected && !cpp.NonInteractive); ui.NoPrompt = cpp.NoPrompt; ui.ThrowOnReadAndPrompt = cpp.ThrowOnReadAndPrompt; noExit = cpp.NoExit; diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleShell.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleShell.cs index 080daee74..e9536c2d9 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleShell.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleShell.cs @@ -17,40 +17,28 @@ namespace Microsoft.PowerShell public static class ConsoleShell { - /// - /// Entry point in to ConsoleShell. This method is called by - /// main of minishell. - /// - /// - /// Configuration information which is used to create Runspace. - /// - /// - /// - /// Banner text to be displayed by ConsoleHost - /// - /// - /// - /// Help text for minishell. This is displayed on 'minishell -?'. - /// - /// - /// - /// Commandline parameters specified by user. - /// - /// - /// - /// An integer value which should be used as exit code for the - /// process. - /// - /// - public static - int - Start(RunspaceConfiguration configuration, - string bannerText, - string helpText, - string[] args) +#if CORECLR + /// Entry point in to ConsoleShell. This method is called by main of minishell. + /// Banner text to be displayed by ConsoleHost + /// Help text for minishell. This is displayed on 'minishell -?'. + /// Commandline parameters specified by user. + /// An integer value which should be used as exit code for the process. + public static int Start(string bannerText, string helpText, string[] args) + { + return Start(null, bannerText, helpText, null, args); + } +#else + /// Entry point in to ConsoleShell. This method is called by main of minishell. + /// Configuration information which is used to create Runspace. + /// Banner text to be displayed by ConsoleHost + /// Help text for minishell. This is displayed on 'minishell -?'. + /// Commandline parameters specified by user. + /// An integer value which should be used as exit code for the process. + public static int Start(RunspaceConfiguration configuration, string bannerText, string helpText, string[] args) { return Start(configuration, bannerText, helpText, null, args); } +#endif /// /// @@ -82,7 +70,7 @@ namespace Microsoft.PowerShell /// An integer value which should be used as exit code for the /// process. /// - + internal static int Start(RunspaceConfiguration configuration, diff --git a/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs b/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs index f1c993950..c095c3942 100644 --- a/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs +++ b/src/Microsoft.PowerShell.Security/security/CertificateProvider.cs @@ -3843,7 +3843,6 @@ namespace Microsoft.PowerShell.Commands /// /// get a list of store names at the specified location /// - [ArchitectureSensitive] internal static List GetStoreNamesAtLocation(StoreLocation location) { Security.NativeMethods.CertStoreFlags locationFlag = diff --git a/src/Microsoft.PowerShell.Security/security/Utils.cs b/src/Microsoft.PowerShell.Security/security/Utils.cs index 966e9ad4e..fd14b42df 100644 --- a/src/Microsoft.PowerShell.Security/security/Utils.cs +++ b/src/Microsoft.PowerShell.Security/security/Utils.cs @@ -131,7 +131,6 @@ namespace Microsoft.PowerShell /// /// /// - [ArchitectureSensitive] internal static string GetStringFromSecureString(SecureString ss) { IntPtr p = Marshal.SecureStringToGlobalAllocUnicode(ss); diff --git a/src/Modules/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.psm1 b/src/Modules/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.psm1 index 3b57dcb84..bb645b27b 100644 Binary files a/src/Modules/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.psm1 and b/src/Modules/Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.psm1 differ diff --git a/src/Modules/PSGet/PSGet.Resource.psd1 b/src/Modules/PSGet/PSGet.Resource.psd1 index 42a789da6..60cd290d6 100644 Binary files a/src/Modules/PSGet/PSGet.Resource.psd1 and b/src/Modules/PSGet/PSGet.Resource.psd1 differ diff --git a/src/Modules/PSGet/PSModule.psm1 b/src/Modules/PSGet/PSModule.psm1 index 86f863c30..7305e389e 100644 --- a/src/Modules/PSGet/PSModule.psm1 +++ b/src/Modules/PSGet/PSModule.psm1 @@ -396,9 +396,10 @@ Microsoft.PowerShell.Utility\Import-LocalizedData LocalizedData -filename PSGet # This code is required to add a .Net type and call the Telemetry APIs # This is required since PowerShell does not support generation of .Net Anonymous types # -$requiredAssembly = ( - "system.management.automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" - ) +$requiredAssembly = @( "system.management.automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", + "$([System.Net.IWebProxy].AssemblyQualifiedName)".Substring('System.Net.IWebProxy'.Length+1).Trim(), + "$([System.Uri].AssemblyQualifiedName)".Substring('System.Uri'.Length+1).Trim() + ) $source = @" using System; @@ -469,8 +470,6 @@ $script:TelemetryEnabled = $false try { - Add-Type -ReferencedAssemblies $requiredAssembly -TypeDefinition $source -Language CSharp -ErrorAction SilentlyContinue - # If the telemetry namespace/methods are not found flow goes to the catch block where telemetry is disabled $telemetryMethods = ([Microsoft.PowerShell.Get.Telemetry] | Get-Member -Static).Name @@ -482,10 +481,30 @@ try } catch { - # Disable Telemetry if there are any issues finding/loading the Telemetry infrastructure - $script:TelemetryEnabled = $false + # Ignore the error and try adding the type below } +if(-not $script:TelemetryEnabled) +{ + try + { + Add-Type -ReferencedAssemblies $requiredAssembly -TypeDefinition $source -Language CSharp -ErrorAction SilentlyContinue + + # If the telemetry namespace/methods are not found flow goes to the catch block where telemetry is disabled + $telemetryMethods = ([Microsoft.PowerShell.Get.Telemetry] | Get-Member -Static).Name + + if ($telemetryMethods.Contains("TraceMessageArtifactsNotFound") -and $telemetryMethods.Contains("TraceMessageNonPSGalleryRegistration")) + { + # Turn ON Telemetry if the infrastructure is present on the machine + $script:TelemetryEnabled = $true + } + } + catch + { + # Disable Telemetry if there are any issues finding/loading the Telemetry infrastructure + $script:TelemetryEnabled = $false + } +} #endregion @@ -1458,6 +1477,10 @@ function Install-Module [PSCredential] $ProxyCredential, + [Parameter()] + [switch] + $AllowClobber, + [Parameter()] [switch] $Force @@ -5675,6 +5698,64 @@ function Get-ScriptCommentHelpInfoString #endregion *-ScriptFileInfo cmdlets #region Utility functions + +function Get-ManifestHashTable +{ + param + ( + [Parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string] + $Path, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCmdlet] + $CallerPSCmdlet + ) + + $Lines = $null + + try + { + $Lines = Get-Content -Path $Path -Force + } + catch + { + if($CallerPSCmdlet) + { + $CallerPSCmdlet.ThrowTerminatingError($_.Exception.ErrorRecord) + } + } + + if(-not $Lines) + { + return + } + + $scriptBlock = [ScriptBlock]::Create( $Lines -join "`n" ) + + $allowedVariables = [System.Collections.Generic.List[String]] @('PSEdition', 'PSScriptRoot') + $allowedCommands = [System.Collections.Generic.List[String]] @() + $allowEnvironmentVariables = $false + + try + { + $scriptBlock.CheckRestrictedLanguage($allowedCommands, $allowedVariables, $allowEnvironmentVariables) + } + catch + { + if($CallerPSCmdlet) + { + $CallerPSCmdlet.ThrowTerminatingError($_.Exception.ErrorRecord) + } + + return + } + + return $scriptBlock.InvokeReturnAsIs() +} + function Get-ParametersHashtable { param( @@ -7555,13 +7636,9 @@ function Get-ModuleDependencies if($PSModuleInfo.RequiredModules -or $PSModuleInfo.NestedModules) { # PSModuleInfo.RequiredModules doesn't provide the RequiredVersion info from the ModuleSpecification - # Reading the contents of module manifest file using Import-LocalizedData cmdlet + # Reading the contents of module manifest file # to get the RequiredVersion details. - Import-LocalizedData -BindingVariable ModuleManifestHashTable ` - -FileName (Microsoft.PowerShell.Management\Split-Path $PSModuleInfo.Path -Leaf) ` - -BaseDirectory $PSModuleInfo.ModuleBase ` - -ErrorAction SilentlyContinue ` - -WarningAction SilentlyContinue + $ModuleManifestHashTable = Get-ManifestHashTable -Path $PSModuleInfo.Path if($PSModuleInfo.RequiredModules) { @@ -7814,12 +7891,7 @@ function Publish-PSArtifactUtility { $Tags += "PSModule" - Import-LocalizedData -BindingVariable ModuleManifestHashTable ` - -FileName (Microsoft.PowerShell.Management\Split-Path $ManifestPath -Leaf) ` - -BaseDirectory (Microsoft.PowerShell.Management\Split-Path $ManifestPath -Parent) ` - -ErrorAction SilentlyContinue ` - -WarningAction SilentlyContinue - + $ModuleManifestHashTable = Get-ManifestHashTable -Path $ManifestPath if($PSModuleInfo.ExportedCommands.Count) { @@ -7989,7 +8061,7 @@ function Publish-PSArtifactUtility $tempOutputFile = Microsoft.PowerShell.Management\Join-Path -Path $nugetPackageRoot -ChildPath "TempPublishOutput.txt" Microsoft.PowerShell.Management\Start-Process -FilePath "$script:NuGetExePath" ` - -ArgumentList @('push', $NupkgPath, '-source', $Destination, '-NonInteractive', '-ApiKey', $NugetApiKey) ` + -ArgumentList @('push', "`"$NupkgPath`"", '-source', "`"$Destination`"", '-NonInteractive', '-ApiKey', "`"$NugetApiKey`"") ` -RedirectStandardError $tempErrorFile ` -RedirectStandardOutput $tempOutputFile ` -NoNewWindow ` @@ -8397,6 +8469,7 @@ function Get-DynamicOptions -IsRequired $false ` -PermittedValues @($script:PSArtifactTypeModule,$script:PSArtifactTypeScript, $script:All)) Write-Output -InputObject (New-DynamicOption -Category $category -Name "Scope" -ExpectedType String -IsRequired $false -PermittedValues @("CurrentUser","AllUsers")) + Write-Output -InputObject (New-DynamicOption -Category $category -Name 'AllowClobber' -ExpectedType Switch -IsRequired $false) Write-Output -InputObject (New-DynamicOption -Category $category -Name "InstallUpdate" -ExpectedType Switch -IsRequired $false) Write-Output -InputObject (New-DynamicOption -Category $category -Name 'NoPathUpdate' -ExpectedType Switch -IsRequired $false) } @@ -9845,6 +9918,7 @@ function Install-PackageUtility Write-Debug ($LocalizedData.FastPackageReference -f $fastPackageReference) $Force = $false + $AllowClobber = $false $Debug = $false $MinimumVersion = $null $RequiredVersion = $null @@ -9933,6 +10007,23 @@ function Install-PackageUtility -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument } + + if($options.ContainsKey('AllowClobber')) + { + $AllowClobber = $options['AllowClobber'] + + if($AllowClobber.GetType().ToString() -eq 'System.String') + { + if($AllowClobber -eq 'false') + { + $AllowClobber = $false + } + elseif($AllowClobber -eq 'true') + { + $AllowClobber = $true + } + } + } if($options.ContainsKey('Force')) { @@ -10339,13 +10430,17 @@ function Install-PackageUtility # Validate the module if(-not $IsSavePackage) { - $CurrentModuleInfo = Test-ValidManifestModule -ModuleBasePath $sourceModulePath + $CurrentModuleInfo = Test-ValidManifestModule -ModuleBasePath $sourceModulePath ` + -InstallLocation $InstallLocation ` + -AllowClobber:$AllowClobber ` + -IsUpdateOperation:$installUpdate if(-not $CurrentModuleInfo) { - $message = $LocalizedData.InvalidPSModule -f ($pkg.Name) - Write-Error -Message $message -ErrorId "InvalidManifestModule" -Category InvalidOperation - continue + # This Install-Package provider API gets called once per an item/package/SoftwareIdentity. + # Return if there is an error instead of continuing further to install the dependencies or current module. + # + return } } @@ -10449,19 +10544,7 @@ function Install-PackageUtility } } } - - # Remove the old module base folder if it is different from the required destination module path when -Force is specified - if($Force -and - $InstalledModuleInfo2 -and - -not $destinationModulePath.StartsWith($InstalledModuleInfo2.ModuleBase, [System.StringComparison]::OrdinalIgnoreCase)) - { - Microsoft.PowerShell.Management\Remove-Item -Path $InstalledModuleInfo2.ModuleBase ` - -Force -Recurse ` - -ErrorAction SilentlyContinue ` - -WarningAction SilentlyContinue ` - -Confirm:$false -WhatIf:$false - } - + if($IsSavePackage) { $message = $LocalizedData.ModuleSavedSuccessfully -f ($psgItemInfo.Name, $installLocation) @@ -12371,14 +12454,7 @@ function Update-ModuleManifest $PackageManagementProviders ) - - Import-LocalizedData -BindingVariable ModuleManifestHashTable ` - -FileName (Microsoft.PowerShell.Management\Split-Path $Path -Leaf) ` - -BaseDirectory (Microsoft.PowerShell.Management\Split-Path $Path -Parent) ` - -ErrorAction SilentlyContinue ` - -WarningAction SilentlyContinue - - if(-not (Microsoft.PowerShell.Management\Test-Path $Path)) + if(-not (Microsoft.PowerShell.Management\Test-Path -Path $Path -PathType Leaf)) { $message = $LocalizedData.UpdateModuleManifestPathCannotFound -f ($Path) ThrowError -ExceptionName "System.ArgumentException" ` @@ -12387,7 +12463,25 @@ function Update-ModuleManifest -ExceptionObject $Path ` -CallerPSCmdlet $PSCmdlet ` -ErrorCategory InvalidArgument - } + } + + $ModuleManifestHashTable = $null + + try + { + $ModuleManifestHashTable = Get-ManifestHashTable -Path $Path -CallerPSCmdlet $PSCmdlet + } + catch + { + $message = $LocalizedData.TestModuleManifestFail -f ($_.Exception.Message) + ThrowError -ExceptionName "System.ArgumentException" ` + -ExceptionMessage $message ` + -ErrorId "InvalidModuleManifestFile" ` + -ExceptionObject $Path ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidArgument + return + } #Get the original module manifest and migrate all the fields to the new module manifest, including the specified parameter values $moduleInfo = $null @@ -13383,6 +13477,348 @@ function Test-ModuleInUse return $false } +function Validate-ModuleAuthenticodeSignature +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory=$true)] + $CurrentModuleInfo, + + [Parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string] + $InstallLocation, + + [Parameter()] + [Switch] + $AllowClobber, + + [Parameter()] + [Switch] + $IsUpdateOperation + ) + + $CurrentModuleAuthenticodeIssuer = $null + + # Validate the catalog signature + $ev = $null + $CurrentModuleAuthenticodeIssuer = ValidateAndGet-CatalogSigningIssuer -ModuleBasePath $CurrentModuleInfo.ModuleBase ` + -ModuleName $CurrentModuleInfo.Name ` + -ErrorVariable ev + if($ev) + { + return $false + } + + $InstalledModuleInfo = Test-ModuleInstalled -Name $CurrentModuleInfo.Name + + # Remove the version folder on 5.0 to get the actual module base folder without version + if(Test-ModuleSxSVersionSupport) + { + $InstallLocation = Microsoft.PowerShell.Management\Split-Path -Path $InstallLocation + } + + if($InstalledModuleInfo) + { + # if $InstalledModuleInfo module base is not starting with current module destination + # Check if the destination location has a previously-installed version, then use that in the further validation. + # + if(-not $InstalledModuleInfo.ModuleBase.StartsWith($InstallLocation, [System.StringComparison]::OrdinalIgnoreCase)) + { + $DestinationModulePath = Microsoft.PowerShell.Management\Join-Path -Path $InstallLocation -ChildPath "$($CurrentModuleInfo.Name)" + + $ModuleInfoUnderDestination = Microsoft.PowerShell.Core\Get-Module -ListAvailable ` + -Name $DestinationModulePath ` + -ErrorAction SilentlyContinue ` + -WarningAction SilentlyContinue ` + -Verbose:$false | + Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction SilentlyContinue + + if($ModuleInfoUnderDestination) + { + $InstalledModuleInfo = $ModuleInfoUnderDestination + } + } + + $InstalledModuleAuthenticodeIssuer = ValidateAndGet-CatalogSigningIssuer -ModuleBasePath $InstalledModuleInfo.ModuleBase ` + -ModuleName $InstalledModuleInfo.Name ` + -IsLocal ` + -ErrorAction SilentlyContinue + + Write-Debug -Message "Previously installed module authenticode issuer: $InstalledModuleAuthenticodeIssuer" + Write-Debug -Message "Current module authenticode issuer: $CurrentModuleAuthenticodeIssuer" + + if($InstalledModuleAuthenticodeIssuer -and + $CurrentModuleAuthenticodeIssuer -and + ($InstalledModuleAuthenticodeIssuer -eq $CurrentModuleAuthenticodeIssuer)) + { + $Message = $LocalizedData.AuthenticodeIssuerMatch -f ($CurrentModuleAuthenticodeIssuer, $CurrentModuleInfo.Name, $CurrentModuleInfo.Version, $InstalledModuleAuthenticodeIssuer, $InstalledModuleInfo.Name, $InstalledModuleInfo.Version) + Write-Verbose -Message $message + + return $true + } + elseif(-not $InstalledModuleInfo.ModuleBase.StartsWith($PSHome, [System.StringComparison]::OrdinalIgnoreCase) -and + $InstalledModuleAuthenticodeIssuer -and + (-not $CurrentModuleAuthenticodeIssuer -or + ($InstalledModuleAuthenticodeIssuer -ne $CurrentModuleAuthenticodeIssuer))) + { + $Message = $LocalizedData.AuthenticodeIssuerMismatch -f ($CurrentModuleAuthenticodeIssuer, $CurrentModuleInfo.Name, $CurrentModuleInfo.Version, $InstalledModuleAuthenticodeIssuer, $InstalledModuleInfo.Name, $InstalledModuleInfo.Version) + ThrowError -ExceptionName 'System.InvalidOperationException' ` + -ExceptionMessage $message ` + -ErrorId 'AuthenticodeIssuerMismatch' ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidOperation + + return $false + } + + # Check if there is a system module + $SystemModuleBase = $null + $SystemModuleManifestFilePath = $null + + if($InstalledModuleInfo -and + $InstalledModuleInfo.ModuleBase.StartsWith($PSHome, [System.StringComparison]::OrdinalIgnoreCase)) + { + $SystemModuleBase = $InstalledModuleInfo.ModuleBase + } + else + { + $SystemModuleBase = Microsoft.PowerShell.Management\Join-Path -Path $PSHome -ChildPath "Modules\$($CurrentModuleInfo.Name)" + } + + if($SystemModuleBase -and + (Microsoft.PowerShell.Management\Test-Path -Path $SystemModuleBase -PathType Container)) + { + $ManifestFileName = "$($CurrentModuleInfo.Name).psd1" + $SystemModuleManifestFilePath = Microsoft.PowerShell.Management\Join-Path -Path $SystemModuleBase -ChildPath $ManifestFileName + } + + if($SystemModuleManifestFilePath -and + (Microsoft.PowerShell.Management\Test-Path -Path $SystemModuleManifestFilePath -PathType Leaf)) + { + $AuthenticodeSignature = Microsoft.PowerShell.Security\Get-AuthenticodeSignature -FilePath $SystemModuleManifestFilePath + $SystemModuleAuthenticodeIssuer = Get-AuthentcodeIssuer -AuthenticodeSignature $AuthenticodeSignature + + if($SystemModuleAuthenticodeIssuer -eq $CurrentModuleAuthenticodeIssuer) + { + $Message = $LocalizedData.AuthenticodeIssuerMatch -f ($CurrentModuleAuthenticodeIssuer, $CurrentModuleInfo.Name, $CurrentModuleInfo.Version, $SystemModuleAuthenticodeIssuer, $SystemModuleInfo.Name, $SystemModuleInfo.Version) + Write-Verbose -Message $message + + return $true + } + else + { + $SystemModuleInfo = Microsoft.PowerShell.Core\Test-ModuleManifest -Path $SystemModuleManifestFilePath + $Message = $LocalizedData.AuthenticodeIssuerMismatch -f ($CurrentModuleAuthenticodeIssuer, $CurrentModuleInfo.Name, $CurrentModuleInfo.Version, $SystemModuleAuthenticodeIssuer, $SystemModuleInfo.Name, $SystemModuleInfo.Version) + ThrowError -ExceptionName 'System.InvalidOperationException' ` + -ExceptionMessage $message ` + -ErrorId 'AuthenticodeIssuerMismatch' ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidOperation + + return $false + } + } + } + + # When module being installed doesn't have the security catalog file, check for the existing commands + # We are calling Test-ModuleCommandAlreadyAvailable as InstalledModuleInfo is required for checking the possible clobbering + # + return Test-ModuleCommandAlreadyAvailable -CurrentModuleInfo $CurrentModuleInfo ` + -InstallLocation $InstallLocation ` + -InstalledModuleInfo $InstalledModuleInfo ` + -AllowClobber:$AllowClobber ` + -IsUpdateOperation:$IsUpdateOperation +} + +function Test-ModuleCommandAlreadyAvailable +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory=$true)] + $CurrentModuleInfo, + + [Parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string] + $InstallLocation, + + [Parameter()] + $InstalledModuleInfo, + + [Parameter()] + [Switch] + $AllowClobber, + + [Parameter()] + [Switch] + $IsUpdateOperation + ) + + # When new module has some commands, no clobber error if + # - AllowClobber is specified, or + # - Installing to the same module base, or + # - Update operation + if($CurrentModuleInfo.ExportedCommands.Keys -and + -not $AllowClobber -and + -not $IsUpdateOperation -and + ($InstalledModuleInfo -and -not $InstalledModuleInfo.ModuleBase.StartsWith($InstallLocation, [System.StringComparison]::OrdinalIgnoreCase))) + { + # Throw an error if there is a command with the same name. + # Get-Command loads the module if a command is already available. + $AvailableCommand = Microsoft.PowerShell.Core\Get-Command -Name $CurrentModuleInfo.ExportedCommands.Values.Name ` + -ErrorAction SilentlyContinue ` + -WarningAction SilentlyContinue | + Microsoft.PowerShell.Utility\Select-Object -First 1 -ErrorAction SilentlyContinue + if($AvailableCommand) + { + $message = $LocalizedData.ModuleCommandAlreadyAvailable -f ($AvailableCommand.Name, $CurrentModuleInfo.Name) + ThrowError -ExceptionName 'System.InvalidOperationException' ` + -ExceptionMessage $message ` + -ErrorId 'CommandAlreadyAvailable' ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidOperation + + return $false + } + } + + return $true +} + +function ValidateAndGet-CatalogSigningIssuer +{ + [CmdletBinding()] + Param + ( + [Parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string] + $ModuleBasePath, + + [Parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string] + $ModuleName, + + [Parameter()] + [Switch] + $IsLocal + ) + + $CatalogFileName = "$ModuleName.cat" + $CatalogFilePath = Microsoft.PowerShell.Management\Join-Path -Path $ModuleBasePath -ChildPath $CatalogFileName + + $AuthenticodeSignature = $null + + if(Microsoft.PowerShell.Management\Test-Path -Path $CatalogFilePath -PathType Leaf) + { + $message = $LocalizedData.CatalogFileFound -f ($CatalogFileName, $ModuleName) + Write-Verbose -Message $message + + $AuthenticodeSignature = Microsoft.PowerShell.Security\Get-AuthenticodeSignature -FilePath $CatalogFilePath + + if(-not $IsLocal) + { + if(-not $AuthenticodeSignature -or ($AuthenticodeSignature.Status -ne "Valid")) + { + $message = $LocalizedData.InvalidModuleAuthenticodeSignature -f ($ModuleName, $CatalogFileName) + ThrowError -ExceptionName 'System.InvalidOperationException' ` + -ExceptionMessage $message ` + -ErrorId 'InvalidAuthenticodeSignature' ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidOperation + + return + } + + Write-Verbose -Message ($LocalizedData.ValidAuthenticodeSignature -f @($CatalogFileName, $ModuleName)) + + if(Get-Command -Name Test-FileCatalog -Module Microsoft.PowerShell.Security -ErrorAction SilentlyContinue) + { + Write-Verbose -Message ($LocalizedData.ValidatingCatalogSignature -f @($ModuleName, $CatalogFileName)) + + # Skip the PSGetModuleInfo.xml and ModuleName.cat files in the catalog validation + $TestFileCatalogResult = Microsoft.PowerShell.Security\Test-FileCatalog -Path $ModuleBasePath ` + -CatalogFilePath $CatalogFilePath ` + -FilesToSkip $script:PSGetItemInfoFileName ` + -Detailed + if(-not $TestFileCatalogResult -or + ($TestFileCatalogResult.Status -ne "Valid") -or + ($TestFileCatalogResult.Signature.Status -ne "Valid")) + { + $message = $LocalizedData.InvalidCatalogSignature -f ($ModuleName, $CatalogFileName) + ThrowError -ExceptionName 'System.InvalidOperationException' ` + -ExceptionMessage $message ` + -ErrorId 'InvalidCatalogSignature' ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidOperation + return + } + else + { + Write-Verbose -Message ($LocalizedData.ValidCatalogSignature -f @($CatalogFileName, $ModuleName)) + } + } + } + } + else + { + if($IsLocal) + { + Write-Verbose -Message ($LocalizedData.CatalogFileNotFoundInAvailableModule -f ($CatalogFileName, $ModuleName)) + } + else + { + Write-Verbose -Message ($LocalizedData.CatalogFileNotFoundInNewModule -f ($CatalogFileName, $ModuleName)) + } + } + + if($AuthenticodeSignature) + { + return Get-AuthentcodeIssuer -AuthenticodeSignature $AuthenticodeSignature + } +} + +function Get-AuthentcodeIssuer +{ + [CmdletBinding()] + [OutputType([bool])] + Param + ( + [Parameter(Mandatory=$true)] + [System.Management.Automation.Signature] + $AuthenticodeSignature + ) + + if(($AuthenticodeSignature.Status -eq "Valid") -and + $AuthenticodeSignature.SignerCertificate) + { + $chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain + $null = $chain.Build($AuthenticodeSignature.SignerCertificate) + + $certStoreLocations = @('cert:\LocalMachine\Root', + 'cert:\LocalMachine\AuthRoot', + 'cert:\CurrentUser\Root', + 'cert:\CurrentUser\AuthRoot') + + foreach($element in $chain.ChainElements.Certificate) + { + foreach($certStoreLocation in $certStoreLocations) + { + $rootCertificateAuthority = Microsoft.PowerShell.Management\Get-ChildItem -Path $certStoreLocation | + Microsoft.PowerShell.Core\Where-Object { $_.Subject -eq $element.Subject } + if($rootCertificateAuthority) + { + return $rootCertificateAuthority.Subject + } + } + } + } +} + function Test-ValidManifestModule { [CmdletBinding()] @@ -13392,16 +13828,50 @@ function Test-ValidManifestModule [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] - $ModuleBasePath + $ModuleBasePath, + + [Parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string] + $InstallLocation, + + [Parameter()] + [Switch] + $AllowClobber, + + [Parameter()] + [Switch] + $IsUpdateOperation ) $moduleName = Microsoft.PowerShell.Management\Split-Path $ModuleBasePath -Leaf $manifestPath = Microsoft.PowerShell.Management\Join-Path $ModuleBasePath "$moduleName.psd1" $PSModuleInfo = $null - + if(Microsoft.PowerShell.Management\Test-Path $manifestPath) { $PSModuleInfo = Microsoft.PowerShell.Core\Test-ModuleManifest -Path $manifestPath -ErrorAction SilentlyContinue -WarningAction SilentlyContinue + + if(-not $PSModuleInfo) + { + $message = $LocalizedData.InvalidPSModule -f ($moduleName) + ThrowError -ExceptionName 'System.InvalidOperationException' ` + -ExceptionMessage $message ` + -ErrorId 'InvalidManifestModule' ` + -CallerPSCmdlet $PSCmdlet ` + -ErrorCategory InvalidOperation + } + else + { + $ValidationResult = Validate-ModuleAuthenticodeSignature -CurrentModuleInfo $PSModuleInfo ` + -InstallLocation $InstallLocation ` + -AllowClobber:$AllowClobber ` + -IsUpdateOperation:$IsUpdateOperation + if(-not $ValidationResult) + { + $PSModuleInfo = $null + } + } } return $PSModuleInfo diff --git a/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs b/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs index dfd9c13fb..0c6ae0caa 100644 --- a/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs +++ b/src/System.Management.Automation/CoreCLR/CorePsExtensions.cs @@ -1129,16 +1129,6 @@ namespace System.Management.Automation } } - //TODO:CORECLR Need to decide what to do with 'requestedClrVersion' and 'requestedDotNetFrameworkVersion' in ModuleCmdletBase.cs [LoadModuleManifest] - public static Version Version - { - get - { - //dongbow:hack - return new Version(4, 0, 30319, 34011); - } - } - #endregion Property_Extensions #region SpecialFolder_Extensions diff --git a/src/System.Management.Automation/DscSupport/CimDSCParser.cs b/src/System.Management.Automation/DscSupport/CimDSCParser.cs index b3f25f10d..54f9a4739 100644 --- a/src/System.Management.Automation/DscSupport/CimDSCParser.cs +++ b/src/System.Management.Automation/DscSupport/CimDSCParser.cs @@ -3381,6 +3381,20 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal return e.ErrorRecord; } + /// + /// Returns an error record to use when composite resource and its resource instances both has PsDscRunAsCredentials value + /// + /// resourceId of resource + /// + public static ErrorRecord PsDscRunAsCredentialMergeErrorForCompositeResources(string resourceId) + { + PSInvalidOperationException e = PSTraceSource.NewInvalidOperationException( + ParserStrings.PsDscRunAsCredentialMergeErrorForCompositeResources, resourceId); + + e.SetErrorId("PsDscRunAsCredentialMergeErrorForCompositeResources"); + return e.ErrorRecord; + } + /// /// Routine to format a usage string from keyword. The resulting string should look like: /// User [string] #ResourceName @@ -3653,6 +3667,23 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal # This routine also adds the resource to the global node resources table. Test-DependsOn +# Check if PsDscRunCredetial is being specified as Arguments to Configuration + if($PsDscRunAsCredential -ne $null) + { +# Check if resource is also trying to set the value for RunAsCred +# In that case we will generate error during compilation, this is merge error + if($value['PsDscRunAsCredential'] -ne $null) + { + Update-ConfigurationErrorCount + Write-Error -ErrorRecord ([Microsoft.PowerShell.DesiredStateConfiguration.Internal.DscClassCache]::PsDscRunAsCredentialMergeErrorForCompositeResources($resourceId)) + } +# Set the Value of RunAsCred to that of outer configuration + else + { + $value['PsDscRunAsCredential'] = $PsDscRunAsCredential + } + } + # Save the resource id in a per-node dictionary to do cross validation at the end if($keywordData.ImplementingModule -ieq ""PSDesiredStateConfigurationEngine"") { @@ -3830,6 +3861,7 @@ namespace Microsoft.PowerShell.DesiredStateConfiguration.Internal -or ($keywordData.ResourceName -eq 'MSFT_WebResourceManager') ` -or ($keywordData.ResourceName -eq 'MSFT_FileResourceManager') ` -or ($keywordData.ResourceName -eq 'MSFT_WebReportManager') ` + -or ($keywordData.ResourceName -eq 'MSFT_SignatureValidation') ` -or ($keywordData.ResourceName -eq 'MSFT_PartialConfiguration')) { Set-PSMetaConfigVersionInfoV2 diff --git a/src/System.Management.Automation/engine/COM/ComTypeInfo.cs b/src/System.Management.Automation/engine/COM/ComTypeInfo.cs index ab9bb3998..9dc261b40 100644 --- a/src/System.Management.Automation/engine/COM/ComTypeInfo.cs +++ b/src/System.Management.Automation/engine/COM/ComTypeInfo.cs @@ -196,7 +196,6 @@ namespace System.Management.Automation /// /// reference to ITypeInfo from which to get TypeAttr /// - [ArchitectureSensitive] internal static COM.TYPEATTR GetTypeAttr(COM.ITypeInfo typeinfo) { IntPtr pTypeAttr; @@ -212,7 +211,6 @@ namespace System.Management.Automation /// /// /// - [ArchitectureSensitive] internal static COM.FUNCDESC GetFuncDesc(COM.ITypeInfo typeinfo, int index) { IntPtr pFuncDesc; diff --git a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs index a391cfbe6..77c305ee7 100644 --- a/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs +++ b/src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs @@ -35,11 +35,26 @@ namespace System.Management.Automation { static CompletionCompleters() { -#if !CORECLR // TODO:CORECLR AppDomain is not on CoreClr. Disable this part for now until we do a work around in PSAssemblyLoadContext +#if CORECLR + // Porting note: removed until we have full assembly loading solution + // ClrFacade.AddAssemblyLoadHandler(UpdateTypeCacheOnAssemblyLoad); +#else AppDomain.CurrentDomain.AssemblyLoad += UpdateTypeCacheOnAssemblyLoad; #endif } +#if CORECLR + static void UpdateTypeCacheOnAssemblyLoad(Assembly loadedAssembly) +#else + static void UpdateTypeCacheOnAssemblyLoad(object sender, AssemblyLoadEventArgs args) +#endif + { + // Just null out the cache - we'll rebuild it the next time someone tries to complete a type. + // We could rebuild it now, but we could be loading multiple assemblies (e.g. dependent assemblies) + // and there is no sense in rebuilding anything until we're done loading all of the assemblies. + Interlocked.Exchange(ref typeCache, null); + } + #region Command Names /// @@ -5973,18 +5988,6 @@ namespace System.Management.Automation } } -#if !CORECLR - // TODO:CORECLR AssemblyLoadEventArgs is not in CoreClr. Also we have ifdef the whole event registration since AppDomain is not on CoreClr. - // TODO:CORECLR So for now disable this part until we do a work around PSAssemblyLoadContext - static void UpdateTypeCacheOnAssemblyLoad(object sender, AssemblyLoadEventArgs args) - { - // Just null out the cache - we'll rebuild it the next time someone tries to complete a type. - // We could rebuild it now, but we could be loading multiple assemblies (e.g. dependent assemblies) - // and there is no sense in rebuilding anything until we're done loading all of the assemblies. - Interlocked.Exchange(ref typeCache, null); - } -#endif - internal static List CompleteNamespace(CompletionContext context, string prefix = "", string suffix = "") { var localTypeCache = typeCache ?? InitializeTypeCache(); diff --git a/src/System.Management.Automation/engine/CoreAdapter.cs b/src/System.Management.Automation/engine/CoreAdapter.cs index d57734296..94dde0c1c 100644 --- a/src/System.Management.Automation/engine/CoreAdapter.cs +++ b/src/System.Management.Automation/engine/CoreAdapter.cs @@ -3160,7 +3160,7 @@ namespace System.Management.Automation /// /// Walk up the derivation chain to find the first public parent type. /// - private static Type GetFirstPublicParentType(TypeInfo typeInfo) + internal static Type GetFirstPublicParentType(TypeInfo typeInfo) { Dbg.Assert(!TypeResolver.IsPublic(typeInfo), "typeInfo should not be public."); Type parent = typeInfo.BaseType; @@ -3347,20 +3347,6 @@ namespace System.Management.Automation return t == typeof(PSMemberInfo) || t == typeof(PSParameterizedProperty); } - /// - /// Get an instance that represents 'System.RuntimeType'. - /// - private static readonly Type RuntimeType = (typeof(object)).GetType(); - - /// - /// Check if an object is a type instance. If it is, such as 'typeof(string)', then 'object.GetType()' - /// should be equal to the type instance that represents 'System.RuntimeType'. - /// - internal static bool IsRuntimeTypeInstance(object obj) - { - return obj.GetType() == RuntimeType; - } - internal T GetDotNetProperty(object obj, string propertyName) where T : PSMemberInfo { bool lookingForProperties = typeof(T).IsAssignableFrom(typeof(PSProperty)); @@ -3372,7 +3358,7 @@ namespace System.Management.Automation CacheTable typeTable = this.isStatic ? GetStaticPropertyReflectionTable((Type)obj) - : GetInstancePropertyReflectionTable(IsRuntimeTypeInstance(obj) ? typeof(Type) : obj.GetType()); + : GetInstancePropertyReflectionTable(obj.GetType()); object entry = typeTable[propertyName]; if (entry == null) @@ -3408,7 +3394,7 @@ namespace System.Management.Automation CacheTable typeTable = this.isStatic ? GetStaticMethodReflectionTable((Type)obj) - : GetInstanceMethodReflectionTable(IsRuntimeTypeInstance(obj) ? typeof(Type) : obj.GetType()); + : GetInstanceMethodReflectionTable(obj.GetType()); var methods = (MethodCacheEntry)typeTable[methodName]; if (methods == null) @@ -3440,7 +3426,7 @@ namespace System.Management.Automation CacheTable table = this.isStatic ? GetStaticPropertyReflectionTable((Type)obj) - : GetInstancePropertyReflectionTable(IsRuntimeTypeInstance(obj) ? typeof(Type) : obj.GetType()); + : GetInstancePropertyReflectionTable(obj.GetType()); for (int i = 0; i < table.memberCollection.Count; i++) { @@ -3481,7 +3467,7 @@ namespace System.Management.Automation CacheTable table = this.isStatic ? GetStaticMethodReflectionTable((Type)obj) - : GetInstanceMethodReflectionTable(IsRuntimeTypeInstance(obj) ? typeof(Type) : obj.GetType()); + : GetInstanceMethodReflectionTable(obj.GetType()); for (int i = 0; i < table.memberCollection.Count; i++) { @@ -3515,7 +3501,7 @@ namespace System.Management.Automation var table = this.isStatic ? GetStaticEventReflectionTable((Type)obj) - : GetInstanceEventReflectionTable(IsRuntimeTypeInstance(obj) ? typeof(Type) : obj.GetType()); + : GetInstanceEventReflectionTable(obj.GetType()); foreach (var psEvent in table.Values) { diff --git a/src/System.Management.Automation/engine/InitialSessionState.cs b/src/System.Management.Automation/engine/InitialSessionState.cs index a581da18c..a4a129de7 100644 --- a/src/System.Management.Automation/engine/InitialSessionState.cs +++ b/src/System.Management.Automation/engine/InitialSessionState.cs @@ -4611,7 +4611,7 @@ namespace System.Management.Automation.Runspaces Dictionary> aliases = null; Dictionary providers = null; - string assemblyPath = ClrFacade.GetAssemblyLocation(assembly); + string assemblyPath = assembly.Location; string throwAwayHelpFile = null; PSSnapInHelpers.AnalyzePSSnapInAssembly(assembly, assemblyPath, null, module, true, out cmdlets, out aliases, out providers, out throwAwayHelpFile); @@ -5815,7 +5815,7 @@ if($paths) { } } - string assemblyPath = ClrFacade.GetAssemblyLocation(assembly); + string assemblyPath = assembly.Location; Type[] assemblyTypes; if (cmdlets != null || providers != null) { diff --git a/src/System.Management.Automation/engine/Modules/AnalysisCache.cs b/src/System.Management.Automation/engine/Modules/AnalysisCache.cs index 5fc3c48c2..bcdcbe496 100644 --- a/src/System.Management.Automation/engine/Modules/AnalysisCache.cs +++ b/src/System.Management.Automation/engine/Modules/AnalysisCache.cs @@ -633,7 +633,7 @@ namespace System.Management.Automation await Task.Delay(3000); counter2 = _saveCacheToDiskQueued; } while (counter1 != counter2); - Serialize(GetCacheStoreLocation()); + Serialize(cacheStoreLocation); }); } } @@ -642,6 +642,9 @@ namespace System.Management.Automation // If anything is removed, save the cache. private void Cleanup() { + Diagnostics.Assert(Environment.GetEnvironmentVariable("PSDisableModuleAnalysisCacheCleanup") == null, + "Caller to check environment variable before calling"); + bool removedSomething = false; var keys = Entries.Keys; foreach (var key in keys) @@ -753,50 +756,57 @@ namespace System.Management.Automation // int ( 4 bytes) -> type name length // string (?? bytes) -> utf8 encoded type name // int ( 4 bytes) -> type attributes - - var bytes = new byte[8]; - using (var stream = File.Create(filename)) + try { - var headerBytes = GetHeader(); - stream.Write(headerBytes, 0, headerBytes.Length); + var bytes = new byte[8]; - // Count of entries - Write(Entries.Count, bytes, stream); - - foreach (var pair in Entries.ToArray()) + using (var stream = File.Create(filename)) { - var path = pair.Key; - var entry = pair.Value; + var headerBytes = GetHeader(); + stream.Write(headerBytes, 0, headerBytes.Length); - // Module last write time - Write(entry.LastWriteTime.Ticks, bytes, stream); + // Count of entries + Write(Entries.Count, bytes, stream); - // Module path - Write(path, bytes, stream); - - // Commands - var commandPairs = entry.Commands.ToArray(); - Write(commandPairs.Length, bytes, stream); - - foreach (var command in commandPairs) + foreach (var pair in Entries.ToArray()) { - Write(command.Key, bytes, stream); - Write((int)command.Value, bytes, stream); - } + var path = pair.Key; + var entry = pair.Value; - // Types - var typePairs = entry.Types.ToArray(); - Write(entry.TypesAnalyzed ? typePairs.Length : -1, bytes, stream); + // Module last write time + Write(entry.LastWriteTime.Ticks, bytes, stream); - foreach (var type in typePairs) - { - Write(type.Key, bytes, stream); - Write((int)type.Value, bytes, stream); + // Module path + Write(path, bytes, stream); + + // Commands + var commandPairs = entry.Commands.ToArray(); + Write(commandPairs.Length, bytes, stream); + + foreach (var command in commandPairs) + { + Write(command.Key, bytes, stream); + Write((int) command.Value, bytes, stream); + } + + // Types + var typePairs = entry.Types.ToArray(); + Write(entry.TypesAnalyzed ? typePairs.Length : -1, bytes, stream); + + foreach (var type in typePairs) + { + Write(type.Key, bytes, stream); + Write((int) type.Value, bytes, stream); + } } } + // We just wrote the file, note this so we can detect writes from another process + LastReadTime = new FileInfo(filename).LastWriteTime; + } + catch (Exception e) + { + ModuleIntrinsics.Tracer.WriteLine("Exception writing module analysis cache {0}: {1} ", filename, e.Message); } - // We just wrote the file, note this so we can detect writes from another process - LastReadTime = new FileInfo(filename).LastWriteTime; // Reset our counter so we can write again if asked. Interlocked.Exchange(ref _saveCacheToDiskQueued, 0); @@ -949,24 +959,16 @@ namespace System.Management.Automation entries -= 1; } - Task.Delay(10000).ContinueWith(_ => result.Cleanup()); + if (Environment.GetEnvironmentVariable("PSDisableModuleAnalysisCacheCleanup") == null) + { + Task.Delay(10000).ContinueWith(_ => result.Cleanup()); + } return result; } } - internal static string GetCacheStoreLocation() - { - string cacheStoreLocation = Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), - @"Microsoft\Windows\PowerShell\ModuleAnalysisCache"); - - return cacheStoreLocation; - } - internal static AnalysisCacheData Get() { - var cacheStoreLocation = GetCacheStoreLocation(); - int retryCount = 3; do @@ -1006,6 +1008,16 @@ namespace System.Management.Automation private AnalysisCacheData() { } + + private static readonly string cacheStoreLocation; + + static AnalysisCacheData() + { + cacheStoreLocation = + Environment.GetEnvironmentVariable("PSModuleAnalysisCachePath") ?? + Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + @"Microsoft\Windows\PowerShell\ModuleAnalysisCache"); + } } [DebuggerDisplay("ModulePath = {ModulePath}")] diff --git a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs index 2e5562d38..543c4126b 100644 --- a/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs +++ b/src/System.Management.Automation/engine/Modules/ImportModuleCommand.cs @@ -511,7 +511,7 @@ namespace Microsoft.PowerShell.Commands } } - if (pair.Value.Path.Equals(ClrFacade.GetAssemblyLocation(suppliedAssembly), StringComparison.OrdinalIgnoreCase)) + if (pair.Value.Path.Equals(suppliedAssembly.Location, StringComparison.OrdinalIgnoreCase)) { moduleLoaded = true; if (BasePassThru) diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs index 2a19bec90..6e40156b3 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs @@ -2000,6 +2000,7 @@ namespace Microsoft.PowerShell.Commands containedErrors = true; if (bailOnFirstError) return null; } +#if !CORECLR // CLR version is not applicable to CoreCLR else if (requestedClrVersion != null) { Version currentClrVersion = Environment.Version; @@ -2018,10 +2019,10 @@ namespace Microsoft.PowerShell.Commands if (bailOnFirstError) return null; } } +#endif // Test the required .NET Framework version - Version requestedDotNetFrameworkVersion = new Version (0, 0, 0, 0); -#if !CORECLR + Version requestedDotNetFrameworkVersion; if ( !GetScalarFromData(data, moduleManifestPath, "DotNetFrameworkVersion", manifestProcessingFlags, out requestedDotNetFrameworkVersion)) @@ -2029,6 +2030,7 @@ namespace Microsoft.PowerShell.Commands containedErrors = true; if (bailOnFirstError) return null; } +#if !CORECLR // .NET Framework Version is not applicable to CoreCLR else if (requestedDotNetFrameworkVersion != null) { bool higherThanKnownHighestVersion = false; @@ -4964,7 +4966,7 @@ namespace Microsoft.PowerShell.Commands Assembly assembly = ExecutionContext.LoadAssembly(name, null, out ignored); if (assembly != null) { - result = ClrFacade.GetAssemblyLocation(assembly); + result = assembly.Location; } } @@ -5333,7 +5335,7 @@ namespace Microsoft.PowerShell.Commands ProviderInfo pi = pl.Value[i]; // If it was implemented by this module, remove it - string implAssemblyLocation = ClrFacade.GetAssemblyLocation(pi.ImplementingType.GetTypeInfo().Assembly); + string implAssemblyLocation = pi.ImplementingType.GetTypeInfo().Assembly.Location; if (implAssemblyLocation.Equals(module.Path, StringComparison.OrdinalIgnoreCase)) { // Remove all drives from the top level session state @@ -6885,7 +6887,7 @@ namespace Microsoft.PowerShell.Commands } else { - modulePath = ClrFacade.GetAssemblyLocation(assemblyToLoad); + modulePath = assemblyToLoad.Location; } // And what to use for a module name... @@ -6992,7 +6994,7 @@ namespace Microsoft.PowerShell.Commands assemblyVersion = GetAssemblyVersionNumber(assembly); if (string.IsNullOrEmpty(fileName)) - modulePath = ClrFacade.GetAssemblyLocation(assembly); + modulePath = assembly.Location; else modulePath = fileName; diff --git a/src/System.Management.Automation/engine/Modules/ModuleSpecification.cs b/src/System.Management.Automation/engine/Modules/ModuleSpecification.cs index 05750ec19..6e9b4e6b4 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleSpecification.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleSpecification.cs @@ -87,38 +87,47 @@ namespace Microsoft.PowerShell.Commands internal static Exception ModuleSpecificationInitHelper(ModuleSpecification moduleSpecification, Hashtable hashtable) { StringBuilder badKeys = new StringBuilder(); - foreach (DictionaryEntry entry in hashtable) + try { - if (entry.Key.ToString().Equals("ModuleName", StringComparison.OrdinalIgnoreCase)) + foreach (DictionaryEntry entry in hashtable) { - moduleSpecification.Name = LanguagePrimitives.ConvertTo(entry.Value); - } - else if (entry.Key.ToString().Equals("ModuleVersion", StringComparison.OrdinalIgnoreCase)) - { - moduleSpecification.Version = LanguagePrimitives.ConvertTo(entry.Value); - } - else if (entry.Key.ToString().Equals("RequiredVersion", StringComparison.OrdinalIgnoreCase)) - { - moduleSpecification.RequiredVersion = LanguagePrimitives.ConvertTo(entry.Value); - } - else if (entry.Key.ToString().Equals("MaximumVersion", StringComparison.OrdinalIgnoreCase)) - { - moduleSpecification.MaximumVersion = LanguagePrimitives.ConvertTo(entry.Value); - ModuleCmdletBase.GetMaximumVersion(moduleSpecification.MaximumVersion); - } - else if (entry.Key.ToString().Equals("GUID", StringComparison.OrdinalIgnoreCase)) - { - moduleSpecification.Guid = LanguagePrimitives.ConvertTo(entry.Value); - } - else - { - if (badKeys.Length > 0) - badKeys.Append(", "); - badKeys.Append("'"); - badKeys.Append(entry.Key.ToString()); - badKeys.Append("'"); + if (entry.Key.ToString().Equals("ModuleName", StringComparison.OrdinalIgnoreCase)) + { + moduleSpecification.Name = LanguagePrimitives.ConvertTo(entry.Value); + } + else if (entry.Key.ToString().Equals("ModuleVersion", StringComparison.OrdinalIgnoreCase)) + { + moduleSpecification.Version = LanguagePrimitives.ConvertTo(entry.Value); + } + else if (entry.Key.ToString().Equals("RequiredVersion", StringComparison.OrdinalIgnoreCase)) + { + moduleSpecification.RequiredVersion = LanguagePrimitives.ConvertTo(entry.Value); + } + else if (entry.Key.ToString().Equals("MaximumVersion", StringComparison.OrdinalIgnoreCase)) + { + moduleSpecification.MaximumVersion = LanguagePrimitives.ConvertTo(entry.Value); + ModuleCmdletBase.GetMaximumVersion(moduleSpecification.MaximumVersion); + } + else if (entry.Key.ToString().Equals("GUID", StringComparison.OrdinalIgnoreCase)) + { + moduleSpecification.Guid = LanguagePrimitives.ConvertTo(entry.Value); + } + else + { + if (badKeys.Length > 0) + badKeys.Append(", "); + badKeys.Append("'"); + badKeys.Append(entry.Key.ToString()); + badKeys.Append("'"); + } } } + // catch all exceptions here, we are going to report them via return value. + // Example of catched exception: one of convertions to Version failed. + catch (Exception e) + { + return e; + } string message; if (badKeys.Length != 0) diff --git a/src/System.Management.Automation/engine/Modules/RemoveModuleCommand.cs b/src/System.Management.Automation/engine/Modules/RemoveModuleCommand.cs index 915143e7a..20976ddac 100644 --- a/src/System.Management.Automation/engine/Modules/RemoveModuleCommand.cs +++ b/src/System.Management.Automation/engine/Modules/RemoveModuleCommand.cs @@ -259,7 +259,7 @@ namespace Microsoft.PowerShell.Commands Dbg.Assert(pList.Value != null, "There should never be a null list of entries in the provider table"); foreach (ProviderInfo pInfo in pList.Value) { - string implTypeAssemblyLocation = ClrFacade.GetAssemblyLocation(pInfo.ImplementingType.GetTypeInfo().Assembly); + string implTypeAssemblyLocation = pInfo.ImplementingType.GetTypeInfo().Assembly.Location; if (implTypeAssemblyLocation.Equals(module.Path, StringComparison.OrdinalIgnoreCase)) { foreach (PSDriveInfo dInfo in Context.TopLevelSessionState.GetDrivesForProvider(pInfo.FullName)) diff --git a/src/System.Management.Automation/engine/MshCmdlet.cs b/src/System.Management.Automation/engine/MshCmdlet.cs index 411368c2e..64ced58ca 100644 --- a/src/System.Management.Automation/engine/MshCmdlet.cs +++ b/src/System.Management.Automation/engine/MshCmdlet.cs @@ -313,6 +313,10 @@ namespace System.Management.Automation { commandOrigin = this._cmdlet.CommandOrigin; } + else if (this._context != null) + { + commandOrigin = this._context.EngineSessionState.CurrentScope.ScopeOrigin; + } result = CommandDiscovery.LookupCommandInfo(commandName, type, SearchResolutionOptions.None, commandOrigin, this._context); diff --git a/src/System.Management.Automation/engine/NativeCommandProcessor.cs b/src/System.Management.Automation/engine/NativeCommandProcessor.cs index fb025bce9..286d4ab19 100644 --- a/src/System.Management.Automation/engine/NativeCommandProcessor.cs +++ b/src/System.Management.Automation/engine/NativeCommandProcessor.cs @@ -848,7 +848,6 @@ namespace System.Management.Automation /// /// /// - [ArchitectureSensitive] static bool IsWindowsApplication(string fileName) { #if CORECLR @@ -1251,7 +1250,6 @@ namespace System.Management.Automation private static extern IntPtr FindExecutableW( string fileName, string directoryPath, StringBuilder pathFound); - [ArchitectureSensitive] private static string FindExecutable(string filename) { // Preallocate a diff --git a/src/System.Management.Automation/engine/PSVersionInfo.cs b/src/System.Management.Automation/engine/PSVersionInfo.cs index 8d84ac1ce..d500e7e85 100644 --- a/src/System.Management.Automation/engine/PSVersionInfo.cs +++ b/src/System.Management.Automation/engine/PSVersionInfo.cs @@ -61,13 +61,17 @@ namespace System.Management.Automation _psVersionTable[PSVersionInfo.PSVersionName] = _psV51Version; _psVersionTable["PSEdition"] = PSEditionValue; - _psVersionTable["CLRVersion"] = Environment.Version; _psVersionTable["BuildVersion"] = GetBuildVersion(); _psVersionTable["GitCommitId"] = GetCommitInfo(); _psVersionTable["PSCompatibleVersions"] = new Version[] { _psV1Version, _psV2Version, _psV3Version, _psV4Version, _psV5Version, _psV51Version }; _psVersionTable[PSVersionInfo.SerializationVersionName] = new Version(InternalSerializer.DefaultVersion); _psVersionTable[PSVersionInfo.PSRemotingProtocolVersionName] = RemotingConstants.ProtocolVersion; _psVersionTable[PSVersionInfo.WSManStackVersionName] = GetWSManStackVersion(); +#if CORECLR + _psVersionTable["CLRVersion"] = null; +#else + _psVersionTable["CLRVersion"] = Environment.Version; +#endif } static internal Hashtable GetPSVersionTable() diff --git a/src/System.Management.Automation/engine/Utils.cs b/src/System.Management.Automation/engine/Utils.cs index cb1eb9bd4..8c4f55e7d 100644 --- a/src/System.Management.Automation/engine/Utils.cs +++ b/src/System.Management.Automation/engine/Utils.cs @@ -164,7 +164,6 @@ namespace System.Management.Automation } } - [ArchitectureSensitive] internal static string GetStringFromSecureString(SecureString ss) { IntPtr p = IntPtr.Zero; @@ -253,7 +252,7 @@ namespace System.Management.Automation #if CORECLR // Use the location of SMA.dll as the application base // Assembly.GetEntryAssembly is not in CoreCLR. GAC is not in CoreCLR. Assembly assembly = typeof(PSObject).GetTypeInfo().Assembly; - return Path.GetDirectoryName(ClrFacade.GetAssemblyLocation(assembly)); + return Path.GetDirectoryName(assembly.Location); #else // The default keys aren't installed, so try and use the entry assembly to // get the application base. This works for managed apps like minishells... @@ -536,6 +535,7 @@ namespace System.Management.Automation return AllowedEditionValues.Contains(editionValue, StringComparer.OrdinalIgnoreCase); } +#if !CORECLR /// /// Checks whether current monad session supports NetFrameworkVersion specified /// by checkVersion. The specified version is treated as the the minimum required @@ -592,7 +592,7 @@ namespace System.Management.Automation return isSupported; } - +#endif #endregion /// diff --git a/src/System.Management.Automation/engine/hostifaces/Connection.cs b/src/System.Management.Automation/engine/hostifaces/Connection.cs index dd4404360..97fffe467 100644 --- a/src/System.Management.Automation/engine/hostifaces/Connection.cs +++ b/src/System.Management.Automation/engine/hostifaces/Connection.cs @@ -692,7 +692,12 @@ namespace System.Management.Automation.Runspaces /// /// RunspaceConfiguration information for this runspace. /// - public abstract RunspaceConfiguration RunspaceConfiguration +#if CORECLR + internal +#else + public +#endif + abstract RunspaceConfiguration RunspaceConfiguration { get; } diff --git a/src/System.Management.Automation/engine/hostifaces/ConnectionBase.cs b/src/System.Management.Automation/engine/hostifaces/ConnectionBase.cs index fb267e465..9b64442d7 100644 --- a/src/System.Management.Automation/engine/hostifaces/ConnectionBase.cs +++ b/src/System.Management.Automation/engine/hostifaces/ConnectionBase.cs @@ -151,7 +151,12 @@ namespace System.Management.Automation.Runspaces /// /// runspaceConfiguration information for this runspace /// - public override RunspaceConfiguration RunspaceConfiguration +#if CORECLR + internal +#else + public +#endif + override RunspaceConfiguration RunspaceConfiguration { get { diff --git a/src/System.Management.Automation/engine/hostifaces/ConnectionFactory.cs b/src/System.Management.Automation/engine/hostifaces/ConnectionFactory.cs index bf1c11e83..44dbb1e5a 100644 --- a/src/System.Management.Automation/engine/hostifaces/ConnectionFactory.cs +++ b/src/System.Management.Automation/engine/hostifaces/ConnectionFactory.cs @@ -81,7 +81,12 @@ namespace System.Management.Automation.Runspaces /// /// Thrown when runspaceConfiguration is null /// - public static Runspace CreateRunspace(RunspaceConfiguration runspaceConfiguration) +#if CORECLR + internal +#else + public +#endif + static Runspace CreateRunspace(RunspaceConfiguration runspaceConfiguration) { if (runspaceConfiguration == null) { @@ -111,7 +116,12 @@ namespace System.Management.Automation.Runspaces /// /// Thrown when runspaceConfiguration is null /// - public static Runspace CreateRunspace(PSHost host, RunspaceConfiguration runspaceConfiguration) +#if CORECLR + internal +#else + public +#endif + static Runspace CreateRunspace(PSHost host, RunspaceConfiguration runspaceConfiguration) { if (host == null) { diff --git a/src/System.Management.Automation/engine/interpreter/Utilities.cs b/src/System.Management.Automation/engine/interpreter/Utilities.cs index efd5ce1bc..fb2a4cf7a 100644 --- a/src/System.Management.Automation/engine/interpreter/Utilities.cs +++ b/src/System.Management.Automation/engine/interpreter/Utilities.cs @@ -328,7 +328,7 @@ namespace System.Management.Automation.Interpreter /// public static Exception UpdateForRethrow(Exception rethrow) { -#if !SILVERLIGHT && !CORECLR +#if !SILVERLIGHT List prev; // we don't have any dynamic stack trace data, capture the data we can @@ -342,12 +342,10 @@ namespace System.Management.Automation.Interpreter } prev.Add(st); - #endif return rethrow; } -#if !CORECLR /// /// Returns all the stack traces associates with an exception /// @@ -367,7 +365,6 @@ namespace System.Management.Automation.Interpreter traces = e.Data[prevStackTraces] as List; return traces != null; } -#endif } /// diff --git a/src/System.Management.Automation/engine/parser/Parser.cs b/src/System.Management.Automation/engine/parser/Parser.cs index d93647047..0cfc4dd70 100644 --- a/src/System.Management.Automation/engine/parser/Parser.cs +++ b/src/System.Management.Automation/engine/parser/Parser.cs @@ -2886,6 +2886,14 @@ namespace System.Management.Automation.Language }; keywordToAddForThisConfigurationStatement.Properties.Add(dependsOnProp.Name, dependsOnProp); + // Add the PsDscRunAsCredential property. + var RunAsProp = new DynamicKeywordProperty + { + Mandatory = true, + Name = "PsDscRunAsCredential", + }; + keywordToAddForThisConfigurationStatement.Properties.Add(RunAsProp.Name, RunAsProp); + // Extract the parameters, if any and them to the keyword definition. var sbeAst = configurationBodyScriptBlock as ScriptBlockExpressionAst; if (sbeAst != null) @@ -4399,11 +4407,16 @@ namespace System.Management.Automation.Language } var itemToken = NextToken(); - if (itemToken.Kind == TokenKind.EndOfInput || itemToken.Kind == TokenKind.NewLine) + switch (itemToken.Kind) { - UngetToken(itemToken); - ReportIncompleteInput(After(directiveToken), () => ParserStrings.MissingUsingItemName); - return new ErrorStatementAst(ExtentOf(usingToken, directiveToken)); + case TokenKind.EndOfInput: + case TokenKind.NewLine: + // Example, using module ,FooBar + case TokenKind.Comma: + { + ReportIncompleteInput(After(directiveToken), () => ParserStrings.MissingUsingItemName); + return new ErrorStatementAst(ExtentOf(usingToken, directiveToken)); + } } var itemAst = GetCommandArgument(CommandArgumentContext.CommandArgument, itemToken); diff --git a/src/System.Management.Automation/engine/parser/ast.cs b/src/System.Management.Automation/engine/parser/ast.cs index d6ce0333e..eef44d6e1 100644 --- a/src/System.Management.Automation/engine/parser/ast.cs +++ b/src/System.Management.Automation/engine/parser/ast.cs @@ -6786,6 +6786,8 @@ namespace System.Management.Automation.Language $InstanceName, [string[]] $DependsOn, + [PSCredential] + $PsDscRunAsCredential, [string] $OutputPath, [hashtable] diff --git a/src/System.Management.Automation/engine/remoting/client/ClientRemotePowerShell.cs b/src/System.Management.Automation/engine/remoting/client/ClientRemotePowerShell.cs index 503f5262e..4abbcb961 100644 --- a/src/System.Management.Automation/engine/remoting/client/ClientRemotePowerShell.cs +++ b/src/System.Management.Automation/engine/remoting/client/ClientRemotePowerShell.cs @@ -426,12 +426,23 @@ namespace System.Management.Automation.Runspaces.Internal stateInfo.State == PSInvocationState.Failed || stateInfo.State == PSInvocationState.Completed) { + // Special case for failure error due to ErrorCode==-2144108453 (no ShellId found). + // In this case terminate session since there is no longer a shell to communicate + // with. + bool terminateSession = false; + if (stateInfo.State == PSInvocationState.Failed) + { + PSRemotingTransportException remotingTransportException = stateInfo.Reason as PSRemotingTransportException; + terminateSession = (remotingTransportException != null) && + (remotingTransportException.ErrorCode == System.Management.Automation.Remoting.Client.WSManNativeApi.ERROR_WSMAN_TARGETSESSION_DOESNOTEXIST); + } + // if state is completed or failed or stopped, // then the collections need to be closed as // well, else the enumerator will block UnblockCollections(); - if (stopCalled) + if (stopCalled || terminateSession) { // Reset stop called flag. stopCalled = false; @@ -468,7 +479,8 @@ namespace System.Management.Automation.Runspaces.Internal PSRemotingTransportException transportException = ex as PSRemotingTransportException; if (transportException != null && (transportException.ErrorCode == System.Management.Automation.Remoting.Client.WSManNativeApi.ERROR_WSMAN_SENDDATA_CANNOT_CONNECT || - transportException.ErrorCode == System.Management.Automation.Remoting.Client.WSManNativeApi.ERROR_WSMAN_SENDDATA_CANNOT_COMPLETE)) + transportException.ErrorCode == System.Management.Automation.Remoting.Client.WSManNativeApi.ERROR_WSMAN_SENDDATA_CANNOT_COMPLETE || + transportException.ErrorCode == System.Management.Automation.Remoting.Client.WSManNativeApi.ERROR_WSMAN_TARGETSESSION_DOESNOTEXIST)) { object rsObject = shell.GetRunspaceConnection(); if (rsObject is Runspace) diff --git a/src/System.Management.Automation/engine/remoting/client/remoterunspace.cs b/src/System.Management.Automation/engine/remoting/client/remoterunspace.cs index f885af03f..52e7f349b 100644 --- a/src/System.Management.Automation/engine/remoting/client/remoterunspace.cs +++ b/src/System.Management.Automation/engine/remoting/client/remoterunspace.cs @@ -230,7 +230,12 @@ namespace System.Management.Automation /// /// runspaceConfiguration information for this runspace /// - public override RunspaceConfiguration RunspaceConfiguration +#if CORECLR + internal +#else + public +#endif + override RunspaceConfiguration RunspaceConfiguration { get { diff --git a/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs b/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs index a1e7b64ac..623eb116c 100644 --- a/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs +++ b/src/System.Management.Automation/engine/remoting/commands/CustomShellCommands.cs @@ -1488,10 +1488,17 @@ else internal static void CheckIfPowerShellVersionIsInstalled(Version version) { // Check if PowerShell 2.0 is installed - // Because of app-compat issues, in Win8, we will have PS 2.0 installed by default but not .NET 2.0 - // In such a case, it is not enough if we check just PowerShell registry keys. We also need to check if .NET 2.0 is installed. if (version != null && version.Major == 2) { +#if CORECLR + // PowerShell 2.0 is not available for CoreCLR + throw new ArgumentException( + PSRemotingErrorInvariants.FormatResourceString( + RemotingErrorIdStrings.PowerShellNotInstalled, + version, "PSVersion")); +#else + // Because of app-compat issues, in Win8, we will have PS 2.0 installed by default but not .NET 2.0 + // In such a case, it is not enough if we check just PowerShell registry keys. We also need to check if .NET 2.0 is installed. try { RegistryKey engineKey = PSSnapInReader.GetPSEngineKey(PSVersionInfo.RegistryVersion1Key); @@ -1511,6 +1518,7 @@ else RemotingErrorIdStrings.PowerShellNotInstalled, version, "PSVersion")); } +#endif } } diff --git a/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs b/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs index f3f1627ed..c360173d8 100644 --- a/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs +++ b/src/System.Management.Automation/engine/remoting/commands/newrunspacecommand.cs @@ -485,10 +485,11 @@ namespace Microsoft.PowerShell.Commands PSRemotingTransportException transException = reason as PSRemotingTransportException; String errorDetails = null; + int transErrorCode = 0; if (transException != null) { OpenRunspaceOperation senderAsOp = sender as OpenRunspaceOperation; - + transErrorCode = transException.ErrorCode; if (senderAsOp != null) { String host = senderAsOp.OperatedRunspace.ConnectionInfo.ComputerName; @@ -507,7 +508,7 @@ namespace Microsoft.PowerShell.Commands "AllowRedirection"); errorDetails = "[" + host + "] " + message; - + } else { @@ -546,8 +547,13 @@ namespace Microsoft.PowerShell.Commands } string fullyQualifiedErrorId = WSManTransportManagerUtils.GetFQEIDFromTransportError( - (transException != null) ? transException.ErrorCode : 0, + transErrorCode, _defaultFQEID); + + if (WSManNativeApi.ERROR_WSMAN_NO_LOGON_SESSION_EXIST == transErrorCode) + { + errorDetails += System.Environment.NewLine + String.Format(System.Globalization.CultureInfo.CurrentCulture, RemotingErrorIdStrings.RemotingErrorNoLogonSessionExist); + } ErrorRecord errorRecord = new ErrorRecord(reason, remoteRunspace, fullyQualifiedErrorId, ErrorCategory.OpenError, null, null, diff --git a/src/System.Management.Automation/engine/remoting/common/RemoteSessionNamedPipe.cs b/src/System.Management.Automation/engine/remoting/common/RemoteSessionNamedPipe.cs index c39c53b5f..cc9ed26d3 100644 --- a/src/System.Management.Automation/engine/remoting/common/RemoteSessionNamedPipe.cs +++ b/src/System.Management.Automation/engine/remoting/common/RemoteSessionNamedPipe.cs @@ -1217,20 +1217,25 @@ namespace System.Management.Automation.Remoting #region Constructors /// - /// Constructor. Creates Named Pipe based on process Id, app domain name and container Guid. + /// Constructor. Creates Named Pipe based on process Id, app domain name and container object root path. /// /// Target process Id for pipe. /// AppDomain name or null for default AppDomain - /// Container Guid. + /// Container OB root. public ContainerSessionNamedPipeClient( int procId, string appDomainName, - Guid containerGuid) - { + string containerObRoot) + { + if (String.IsNullOrEmpty(containerObRoot)) + { + throw new PSArgumentNullException("containerObRoot"); + } + // // Named pipe inside Windows Server container is under different name space. // - _pipeName = @"\\.\Containers\" + containerGuid.ToString() + @"\Device\NamedPipe\" + + _pipeName = containerObRoot + @"\Device\NamedPipe\" + NamedPipeUtils.CreateProcessPipeName(procId, appDomainName); } diff --git a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs index 48bfc628c..dfdb215dc 100644 --- a/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs +++ b/src/System.Management.Automation/engine/remoting/common/RunspaceConnectionInfo.cs @@ -2240,7 +2240,7 @@ namespace System.Management.Automation.Runspaces bool runAsAdmin, string configurationName) { - ContainerProcess containerProc = new ContainerProcess(containerId, null, Guid.Empty, 0, runAsAdmin, configurationName); + ContainerProcess containerProc = new ContainerProcess(containerId, null, null, 0, runAsAdmin, configurationName); return new ContainerConnectionInfo(containerProc); } @@ -2253,7 +2253,7 @@ namespace System.Management.Automation.Runspaces bool runAsAdmin, string configurationName) { - ContainerProcess containerProc = new ContainerProcess(null, containerName, Guid.Empty, 0, runAsAdmin, configurationName); + ContainerProcess containerProc = new ContainerProcess(null, containerName, null, 0, runAsAdmin, configurationName); return new ContainerConnectionInfo(containerProc); } @@ -2288,7 +2288,7 @@ namespace System.Management.Automation.Runspaces #region Private Data private Guid runtimeId; - private Guid containerGuid = Guid.Empty; + private string containerObRoot; private string containerId; private string containerName; private int processId; @@ -2320,12 +2320,12 @@ namespace System.Management.Automation.Runspaces } /// - /// Guid of the container. + /// OB root of the container. /// - public Guid ContainerGuid + public string ContainerObRoot { - get { return containerGuid; } - set { containerGuid = value; } + get { return containerObRoot; } + set { containerObRoot = value; } } /// @@ -2423,11 +2423,11 @@ namespace System.Management.Automation.Runspaces /// /// Creates an instance used for PowerShell Direct for container. /// - public ContainerProcess(string containerId, string containerName, Guid containerGuid, int processId, bool runAsAdmin, string configurationName) + public ContainerProcess(string containerId, string containerName, string containerObRoot, int processId, bool runAsAdmin, string configurationName) { this.ContainerId = containerId; this.ContainerName = containerName; - this.ContainerGuid = containerGuid; + this.ContainerObRoot = containerObRoot; this.ProcessId = processId; this.RunAsAdmin = runAsAdmin; this.ConfigurationName = configurationName; @@ -2497,7 +2497,7 @@ namespace System.Management.Automation.Runspaces } /// - /// Get container name and Guid based on given container id. + /// Get container name and object root based on given container id. /// public void GetContainerPropertiesFromContainerId() { @@ -2520,7 +2520,7 @@ namespace System.Management.Automation.Runspaces } /// - /// Get container id and Guid based on given container name. + /// Get container id and object root based on given container name. /// public void GetContainerPropertiesFromContainerName() { @@ -2659,7 +2659,7 @@ namespace System.Management.Automation.Runspaces } /// - /// Get container name and Guid based on given container id. + /// Get container name and object root based on given container id. /// private void GetContainerPropertiesFromContainerIdInternal() { @@ -2678,11 +2678,11 @@ namespace System.Management.Automation.Runspaces RuntimeId = (Guid)computeSystemPropertiesType.GetProperty("RuntimeId").GetValue(computeSystemPropertiesHandle); // - // Get container Guid for Windows Server container. + // Get container object root for Windows Server container. // if (RuntimeId == Guid.Empty) { - ContainerGuid = new Guid((string)computeSystemPropertiesType.GetProperty("SiloGuid").GetValue(computeSystemPropertiesHandle)); + ContainerObRoot = (string)computeSystemPropertiesType.GetProperty("ObRoot").GetValue(computeSystemPropertiesHandle); } } catch (FileNotFoundException) @@ -2713,7 +2713,7 @@ namespace System.Management.Automation.Runspaces } /// - /// Get container id and Guid based on given container name. + /// Get container id and object root based on given container name. /// private void GetContainerPropertiesFromContainerNameInternal() { @@ -2759,11 +2759,11 @@ namespace System.Management.Automation.Runspaces RuntimeId = (Guid)computeSystemPropertiesType.GetProperty("RuntimeId").GetValue(computeSystemPropertiesHandle); // - // Get container Guid for Windows Server container. + // Get container object root for Windows Server container. // if (RuntimeId == Guid.Empty) { - ContainerGuid = new Guid((string)computeSystemPropertiesType.GetProperty("SiloGuid").GetValue(computeSystemPropertiesHandle)); + ContainerObRoot = (string)computeSystemPropertiesType.GetProperty("ObRoot").GetValue(computeSystemPropertiesHandle); } } catch (FileNotFoundException) diff --git a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs index 793df88f0..1b09af736 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs @@ -1636,7 +1636,7 @@ namespace System.Management.Automation.Remoting.Client _clientPipe = new ContainerSessionNamedPipeClient( _connectionInfo.ContainerProc.ProcessId, string.Empty, // AppDomainName - _connectionInfo.ContainerProc.ContainerGuid); + _connectionInfo.ContainerProc.ContainerObRoot); // Wait for named pipe to connect. _clientPipe.Connect(_connectionInfo.OpenTimeout); diff --git a/src/System.Management.Automation/engine/remoting/fanin/WSManNativeAPI.cs b/src/System.Management.Automation/engine/remoting/fanin/WSManNativeAPI.cs index 4e0ac2d1e..a11eeb9b5 100644 --- a/src/System.Management.Automation/engine/remoting/fanin/WSManNativeAPI.cs +++ b/src/System.Management.Automation/engine/remoting/fanin/WSManNativeAPI.cs @@ -84,6 +84,8 @@ namespace System.Management.Automation.Remoting.Client internal const int ERROR_WSMAN_AUTHENTICATION_FAILED = 1311; + internal const int ERROR_WSMAN_NO_LOGON_SESSION_EXIST = 1312; + internal const int ERROR_WSMAN_LOGON_FAILURE = 1326; internal const int ERROR_WSMAN_IMPROPER_RESPONSE = 1722; diff --git a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs index 16acec325..7970e8c5d 100644 --- a/src/System.Management.Automation/engine/runtime/Binding/Binders.cs +++ b/src/System.Management.Automation/engine/runtime/Binding/Binders.cs @@ -5224,13 +5224,21 @@ namespace System.Management.Automation.Language value = PSObject.Base(value); } - // If the target value is a Type instance, we need to use 'typeof(Type)' as the type of the value, so as to avoid - // casting the expression to the internal type 'System.RuntimeType'. - // Reflection execution on internal framework types is unconditionally disallowed in CoreCLR. - var type = castToType ?? - ((value != null) - ? (DotNetAdapter.IsRuntimeTypeInstance(value)) ? typeof(Type) : value.GetType() - : typeof(object)); + var type = castToType ?? ((value != null) ? value.GetType() : typeof(object)); +#if CORECLR + var typeInfo = type.GetTypeInfo(); + // Assemblies in CoreCLR might not allow reflection execution on their internal types. In such case, we walk up + // the derivation chain to find the first public parent, and use reflection methods on the public parent. + if (!TypeResolver.IsPublic(typeInfo) && DotNetAdapter.DisallowPrivateReflection(typeInfo)) + { + var publicType = DotNetAdapter.GetFirstPublicParentType(typeInfo); + if (publicType != null) + { + type = publicType; + } + // else we'll probably fail, but the error message might be more helpful than NullReferenceException + } +#endif if (expr.Type != type) { // Unbox value types (or use Nullable.Value) to avoid a copy in case the value is mutated. diff --git a/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs b/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs index 6bec3a28f..3dfd923c2 100644 --- a/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs +++ b/src/System.Management.Automation/engine/runtime/CompiledScriptBlock.cs @@ -1890,7 +1890,7 @@ namespace System.Management.Automation if (_scriptBlock.HasBeginBlock) { - RunClause(_runOptimized ? _scriptBlock.BeginBlock : _scriptBlock.UnoptimizedBeginBlock, AutomationNull.Value, _input); + RunClause(_runOptimized ? _scriptBlock.BeginBlock : _scriptBlock.UnoptimizedBeginBlock, AutomationNull.Value, _input.GetEnumerator()); } } @@ -1901,11 +1901,19 @@ namespace System.Management.Automation return; } - _input.Add(this.CurrentPipelineObject); + object dollarUnder; + if (CurrentPipelineObject == AutomationNull.Value) + { + dollarUnder = null; + } + else + { + dollarUnder = CurrentPipelineObject; + _input.Add(dollarUnder); + } if (_scriptBlock.HasProcessBlock) { - var dollarUnder = this.CurrentPipelineObject == AutomationNull.Value ? null : this.CurrentPipelineObject; - RunClause(_runOptimized ? _scriptBlock.ProcessBlock : _scriptBlock.UnoptimizedProcessBlock, dollarUnder, _input); + RunClause(_runOptimized ? _scriptBlock.ProcessBlock : _scriptBlock.UnoptimizedProcessBlock, dollarUnder, _input.GetEnumerator()); _input.Clear(); } } @@ -1919,7 +1927,7 @@ namespace System.Management.Automation if (_scriptBlock.HasEndBlock) { - RunClause(_runOptimized ? _scriptBlock.EndBlock : _scriptBlock.UnoptimizedEndBlock, AutomationNull.Value, _input.ToArray()); + RunClause(_runOptimized ? _scriptBlock.EndBlock : _scriptBlock.UnoptimizedEndBlock, AutomationNull.Value, _input.ToArray().GetEnumerator()); } } diff --git a/src/System.Management.Automation/help/CommandHelpProvider.cs b/src/System.Management.Automation/help/CommandHelpProvider.cs index 6f9806584..8d3c8b666 100644 --- a/src/System.Management.Automation/help/CommandHelpProvider.cs +++ b/src/System.Management.Automation/help/CommandHelpProvider.cs @@ -467,7 +467,7 @@ namespace System.Management.Automation if (cmdletInfo.ImplementingType == null) return null; - return Path.GetDirectoryName(ClrFacade.GetAssemblyLocation(cmdletInfo.ImplementingType.GetTypeInfo().Assembly)); + return Path.GetDirectoryName(cmdletInfo.ImplementingType.GetTypeInfo().Assembly.Location); } /// diff --git a/src/System.Management.Automation/help/ProviderHelpProvider.cs b/src/System.Management.Automation/help/ProviderHelpProvider.cs index 737467f16..85828b109 100644 --- a/src/System.Management.Automation/help/ProviderHelpProvider.cs +++ b/src/System.Management.Automation/help/ProviderHelpProvider.cs @@ -128,7 +128,7 @@ namespace System.Management.Automation if (providerInfo.ImplementingType == null) return null; - return Path.GetDirectoryName(ClrFacade.GetAssemblyLocation(providerInfo.ImplementingType.GetTypeInfo().Assembly)); + return Path.GetDirectoryName(providerInfo.ImplementingType.GetTypeInfo().Assembly.Location); } /// diff --git a/src/System.Management.Automation/minishell/api/FormatAndTypeDataHelper.cs b/src/System.Management.Automation/minishell/api/FormatAndTypeDataHelper.cs index e8e49c18a..fa2e385a3 100644 --- a/src/System.Management.Automation/minishell/api/FormatAndTypeDataHelper.cs +++ b/src/System.Management.Automation/minishell/api/FormatAndTypeDataHelper.cs @@ -91,7 +91,7 @@ namespace System.Management.Automation.Runspaces returnValue = Path.GetDirectoryName(returnValue); if (!Directory.Exists(returnValue)) { - string newReturnValue = Path.GetDirectoryName(ClrFacade.GetAssemblyLocation(typeof(FormatAndTypeDataHelper).GetTypeInfo().Assembly)); + string newReturnValue = Path.GetDirectoryName(typeof(FormatAndTypeDataHelper).GetTypeInfo().Assembly.Location); string error = StringUtil.Format(TypesXmlStrings.CannotFindRegistryKeyPath, returnValue, Utils.GetRegistryConfigurationPath(runspaceConfiguration.ShellId), "\\Path", newReturnValue); independentErrors.Add(error); diff --git a/src/System.Management.Automation/minishell/api/RunspaceConfiguration.cs b/src/System.Management.Automation/minishell/api/RunspaceConfiguration.cs index fdb07b22f..8ebc0bfd7 100644 --- a/src/System.Management.Automation/minishell/api/RunspaceConfiguration.cs +++ b/src/System.Management.Automation/minishell/api/RunspaceConfiguration.cs @@ -103,9 +103,14 @@ namespace System.Management.Automation.Runspaces /// 6. ETS will use type information. /// 7. Format and output will use format information. /// --> - public abstract class RunspaceConfiguration +#if CORECLR + internal +#else + public +#endif + abstract class RunspaceConfiguration { - #region RunspaceConfiguration Factory +#region RunspaceConfiguration Factory #if V2 @@ -281,9 +286,9 @@ namespace System.Management.Automation.Runspaces return (RunspaceConfiguration)method.Invoke(null, null); } - #endregion RunspaceConfiguration Factory +#endregion RunspaceConfiguration Factory - #region Shell Id +#region Shell Id /// /// Gets the shell id for current runspace configuration. @@ -293,9 +298,9 @@ namespace System.Management.Automation.Runspaces get; } - #endregion +#endregion - #region PSSnapin Api's +#region PSSnapin Api's /// /// Add a PSSnapin to runspace configuration. @@ -340,9 +345,9 @@ namespace System.Management.Automation.Runspaces throw PSTraceSource.NewNotSupportedException(); } - #endregion +#endregion - #region Cmdlet, Provider, Relationship +#region Cmdlet, Provider, Relationship private RunspaceConfigurationEntryCollection _cmdlets; @@ -396,9 +401,9 @@ namespace System.Management.Automation.Runspaces } */ - #endregion +#endregion - #region Types and Formats +#region Types and Formats /// /// types.ps1xml information @@ -465,9 +470,9 @@ namespace System.Management.Automation.Runspaces get { return formatDBManger; } } - #endregion +#endregion - #region Script Data +#region Script Data private RunspaceConfigurationEntryCollection _scripts; @@ -491,9 +496,9 @@ namespace System.Management.Automation.Runspaces } } - #endregion +#endregion - #region Profile configuration +#region Profile configuration private RunspaceConfigurationEntryCollection _initializationScripts; @@ -517,9 +522,9 @@ namespace System.Management.Automation.Runspaces } } - #endregion +#endregion - #region Assemblies +#region Assemblies private RunspaceConfigurationEntryCollection _assemblies; @@ -543,9 +548,9 @@ namespace System.Management.Automation.Runspaces } } - #endregion +#endregion - #region Security Manager +#region Security Manager private AuthorizationManager _authorizationManager = null; @@ -569,9 +574,9 @@ namespace System.Management.Automation.Runspaces } } - #endregion +#endregion - #region Configuration Update +#region Configuration Update private PSHost _host = null; internal void Bind(ExecutionContext executionContext) @@ -790,7 +795,7 @@ namespace System.Management.Automation.Runspaces } } - #endregion +#endregion [TraceSource("RunspaceInit", "Initialization code for Runspace")] static private PSTraceSource runspaceInitTracer = PSTraceSource.GetTracer("RunspaceInit", "Initialization code for Runspace", false); diff --git a/src/System.Management.Automation/minishell/api/RunspaceConfigurationEntry.cs b/src/System.Management.Automation/minishell/api/RunspaceConfigurationEntry.cs index 6828d519e..0a1878c01 100644 --- a/src/System.Management.Automation/minishell/api/RunspaceConfigurationEntry.cs +++ b/src/System.Management.Automation/minishell/api/RunspaceConfigurationEntry.cs @@ -26,7 +26,12 @@ namespace System.Management.Automation.Runspaces /// runspace configuration entries only. Developers should not derive from /// this class. /// - public abstract class RunspaceConfigurationEntry +#if CORECLR + internal +#else + public +#endif + abstract class RunspaceConfigurationEntry { /// /// Initiate an instance of runspace configuration entry. @@ -125,7 +130,12 @@ namespace System.Management.Automation.Runspaces /// /// Defines class for type configuration entry. /// - public sealed class TypeConfigurationEntry : RunspaceConfigurationEntry +#if CORECLR + internal +#else + public +#endif + sealed class TypeConfigurationEntry : RunspaceConfigurationEntry { /// /// Initiate an instance for type configuration entry. @@ -233,7 +243,12 @@ namespace System.Management.Automation.Runspaces /// /// Defines class for type configuration entry. /// - public sealed class FormatConfigurationEntry : RunspaceConfigurationEntry +#if CORECLR + internal +#else + public +#endif + sealed class FormatConfigurationEntry : RunspaceConfigurationEntry { /// /// Initiate an instance for type configuration entry. @@ -327,7 +342,12 @@ namespace System.Management.Automation.Runspaces /// /// Class to define configuration data for cmdlets /// - public sealed class CmdletConfigurationEntry : RunspaceConfigurationEntry // Naming: fix +#if CORECLR + internal +#else + public +#endif + sealed class CmdletConfigurationEntry : RunspaceConfigurationEntry { /// /// Initiate an instance for cmdlet configuration entry. @@ -415,7 +435,12 @@ namespace System.Management.Automation.Runspaces /// /// Define class for provider configuration entry /// - public sealed class ProviderConfigurationEntry : RunspaceConfigurationEntry // Naming: fix +#if CORECLR + internal +#else + public +#endif + sealed class ProviderConfigurationEntry : RunspaceConfigurationEntry { /// /// Initiate an instance for provider configuration entry. @@ -500,7 +525,12 @@ namespace System.Management.Automation.Runspaces /// /// Define class for script configuration entry /// - public sealed class ScriptConfigurationEntry : RunspaceConfigurationEntry // Naming: fix +#if CORECLR + internal +#else + public +#endif + sealed class ScriptConfigurationEntry : RunspaceConfigurationEntry { /// /// Initiate an instance for script configuration entry. @@ -535,7 +565,12 @@ namespace System.Management.Automation.Runspaces /// /// Configuration data for assemblies. /// - public sealed class AssemblyConfigurationEntry : RunspaceConfigurationEntry +#if CORECLR + internal +#else + public +#endif + sealed class AssemblyConfigurationEntry : RunspaceConfigurationEntry { /// /// Initiate an instance for assembly configuration entry. diff --git a/src/System.Management.Automation/minishell/api/RunspaceConfigurationEntryCollection.cs b/src/System.Management.Automation/minishell/api/RunspaceConfigurationEntryCollection.cs index f4bb5f7ac..2960a0d5b 100644 --- a/src/System.Management.Automation/minishell/api/RunspaceConfigurationEntryCollection.cs +++ b/src/System.Management.Automation/minishell/api/RunspaceConfigurationEntryCollection.cs @@ -31,7 +31,12 @@ namespace System.Management.Automation.Runspaces /// components. For example, if cmdlets/providers list is updated, it /// has to be communicated to engine. /// --> - public sealed class RunspaceConfigurationEntryCollection : IEnumerable where T : RunspaceConfigurationEntry +#if CORECLR + internal +#else + public +#endif + sealed class RunspaceConfigurationEntryCollection : IEnumerable where T : RunspaceConfigurationEntry { /// /// Constructor diff --git a/src/System.Management.Automation/minishell/api/RunspaceConfigurationTypeAttribute.cs b/src/System.Management.Automation/minishell/api/RunspaceConfigurationTypeAttribute.cs index 77269d2aa..3d736bfe0 100644 --- a/src/System.Management.Automation/minishell/api/RunspaceConfigurationTypeAttribute.cs +++ b/src/System.Management.Automation/minishell/api/RunspaceConfigurationTypeAttribute.cs @@ -23,7 +23,12 @@ namespace System.Management.Automation.Runspaces /// the type name for MiniShellConguration derived class. /// --> [AttributeUsage(AttributeTargets.Assembly)] - public sealed class RunspaceConfigurationTypeAttribute: Attribute +#if CORECLR + internal +#else + public +#endif + sealed class RunspaceConfigurationTypeAttribute: Attribute { /// /// Initiate an instance of RunspaceConfigurationTypeAttribute. diff --git a/src/System.Management.Automation/minishell/api/RunspaceConfigurationTypeException.cs b/src/System.Management.Automation/minishell/api/RunspaceConfigurationTypeException.cs index 01068261f..b0173a0cb 100644 --- a/src/System.Management.Automation/minishell/api/RunspaceConfigurationTypeException.cs +++ b/src/System.Management.Automation/minishell/api/RunspaceConfigurationTypeException.cs @@ -26,7 +26,12 @@ namespace System.Management.Automation.Runspaces /// 2. ISerializable /// --> [Serializable] - public class RunspaceConfigurationTypeException : SystemException, IContainsErrorRecord +#if CORECLR + internal +#else + public +#endif + class RunspaceConfigurationTypeException : SystemException, IContainsErrorRecord { /// /// Initiate an instance for RunspaceConfigurationTypeException diff --git a/src/System.Management.Automation/resources/ParserStrings.resx b/src/System.Management.Automation/resources/ParserStrings.resx index 807450a9d..695cdc596 100644 --- a/src/System.Management.Automation/resources/ParserStrings.resx +++ b/src/System.Management.Automation/resources/ParserStrings.resx @@ -1447,4 +1447,7 @@ ModuleVersion : Version of module to import. If used, ModuleName must represent Cannot assign automatic variable '{0}' with type '{1}' - + + Conflict in using PsDscRunAsCredential for Resource {0} because it already specifies PsDscRunAsCredential value. We can only use one PsDscRunAsCredential for the composite resource. + + \ No newline at end of file diff --git a/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx b/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx index ac45d36d2..cabb67a5f 100644 --- a/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx +++ b/src/System.Management.Automation/resources/RemotingErrorIdStrings.resx @@ -1611,4 +1611,8 @@ All WinRM sessions connected to Windows PowerShell session configurations, such Invalid role key type: {0}. Role keys must be strings that identify a security group. + + Other Possible Cause: + -The domain or computer name was not included with the specified credential, for example: DOMAIN\UserName or COMPUTER\UserName. + \ No newline at end of file diff --git a/src/System.Management.Automation/security/Authenticode.cs b/src/System.Management.Automation/security/Authenticode.cs index e93270e6c..f175379e9 100644 --- a/src/System.Management.Automation/security/Authenticode.cs +++ b/src/System.Management.Automation/security/Authenticode.cs @@ -121,7 +121,6 @@ namespace System.Management.Automation /// /// /// - [ArchitectureSensitive] internal static Signature SignFile(SigningOption option, string fileName, X509Certificate2 certificate, @@ -313,7 +312,6 @@ namespace System.Management.Automation /// /// /// - [ArchitectureSensitive] internal static Signature GetSignature(string fileName, string fileContent) { Signature signature = null; @@ -505,7 +503,6 @@ namespace System.Management.Automation return signature; } - [ArchitectureSensitive] private static DWORD GetWinTrustData(string fileName, string fileContent, out NativeMethods.WINTRUST_DATA wtData) { @@ -562,7 +559,6 @@ namespace System.Management.Automation return dwResult; } - [ArchitectureSensitive] private static X509Certificate2 GetCertFromChain(IntPtr pSigner) { X509Certificate2 signerCert = null; @@ -585,7 +581,6 @@ namespace System.Management.Automation return signerCert; } - [ArchitectureSensitive] private static Signature GetSignatureFromWintrustData( string filePath, DWORD error, @@ -658,7 +653,6 @@ namespace System.Management.Automation return signature; } - [ArchitectureSensitive] private static DWORD GetLastWin32Error() { int error = Marshal.GetLastWin32Error(); diff --git a/src/System.Management.Automation/security/SecureStringHelper.cs b/src/System.Management.Automation/security/SecureStringHelper.cs index 50948e91f..7761b5ae6 100644 --- a/src/System.Management.Automation/security/SecureStringHelper.cs +++ b/src/System.Management.Automation/security/SecureStringHelper.cs @@ -76,7 +76,6 @@ namespace Microsoft.PowerShell /// /// contents of s (char[]) converted to byte[] /// - [ArchitectureSensitive] internal static byte[] GetData(SecureString s) { // diff --git a/src/System.Management.Automation/security/SecuritySupport.cs b/src/System.Management.Automation/security/SecuritySupport.cs index 755b1df4c..f0af41a6e 100644 --- a/src/System.Management.Automation/security/SecuritySupport.cs +++ b/src/System.Management.Automation/security/SecuritySupport.cs @@ -466,7 +466,6 @@ namespace System.Management.Automation /// /// The path to the file in question /// A file handle to the file in question, if available. - [ArchitectureSensitive] [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods")] internal static SaferPolicy GetSaferPolicy(string path, SafeHandle handle) { @@ -759,7 +758,6 @@ namespace System.Management.Automation /// /// /// - [ArchitectureSensitive] internal static Collection GetCertEKU(X509Certificate2 cert) { Collection ekus = new Collection(); diff --git a/src/System.Management.Automation/security/nativeMethods.cs b/src/System.Management.Automation/security/nativeMethods.cs index 4481b26d1..2f374e918 100644 --- a/src/System.Management.Automation/security/nativeMethods.cs +++ b/src/System.Management.Automation/security/nativeMethods.cs @@ -587,7 +587,6 @@ namespace System.Management.Automation.Security internal IntPtr psUnauthenticatedNotUsed; // PCRYPT_ATTRIBUTES }; - [ArchitectureSensitive] internal static CRYPTUI_WIZ_DIGITAL_SIGN_EXTENDED_INFO InitSignInfoExtendedStruct(string description, string moreInfoUrl, @@ -693,7 +692,6 @@ namespace System.Management.Automation.Security uint dwGroupId); - [ArchitectureSensitive] internal static DWORD GetCertChoiceFromSigningOption( SigningOption option) { @@ -721,7 +719,6 @@ namespace System.Management.Automation.Security return cc; } - [ArchitectureSensitive] internal static CRYPTUI_WIZ_DIGITAL_SIGN_INFO InitSignInfoStruct(string fileName, X509Certificate2 signingCert, @@ -818,7 +815,6 @@ namespace System.Management.Automation.Security internal byte[] Data4; } - [ArchitectureSensitive] internal static WINTRUST_FILE_INFO InitWintrustFileInfoStruct(string fileName) { WINTRUST_FILE_INFO fi = new WINTRUST_FILE_INFO(); @@ -831,7 +827,6 @@ namespace System.Management.Automation.Security return fi; } - [ArchitectureSensitive] internal static WINTRUST_BLOB_INFO InitWintrustBlobInfoStruct(string fileName, string content) { WINTRUST_BLOB_INFO bi = new WINTRUST_BLOB_INFO(); @@ -964,7 +959,6 @@ namespace System.Management.Automation.Security internal uint dwUIContext; } - [ArchitectureSensitive] internal static WINTRUST_DATA InitWintrustDataStructFromFile(WINTRUST_FILE_INFO wfi) { WINTRUST_DATA wtd = new WINTRUST_DATA(); @@ -988,7 +982,6 @@ namespace System.Management.Automation.Security return wtd; } - [ArchitectureSensitive] internal static WINTRUST_DATA InitWintrustDataStructFromBlob(WINTRUST_BLOB_INFO wbi) { WINTRUST_DATA wtd = new WINTRUST_DATA(); @@ -1012,7 +1005,6 @@ namespace System.Management.Automation.Security return wtd; } - [ArchitectureSensitive] internal static DWORD DestroyWintrustDataStruct(WINTRUST_DATA wtd) { DWORD dwResult = Win32Errors.E_FAIL; @@ -2107,6 +2099,13 @@ namespace System.Management.Automation.Security IntPtr pCDF ); + [DllImport("wintrust.dll", CharSet = CharSet.Unicode)] + internal static extern IntPtr CryptCATCDFEnumCatAttributes( + IntPtr pCDF, + IntPtr pPrevAttr, + CryptCATCDFOpenCallBack pfnParseError + ); + [DllImport("wintrust.dll", CharSet = CharSet.Unicode)] internal static extern IntPtr CryptCATCDFEnumMembersByCDFTagEx( IntPtr pCDF, @@ -2182,6 +2181,12 @@ namespace System.Management.Automation.Security DWORD dwFlags ); + [DllImport("wintrust.dll", CharSet = CharSet.Unicode)] + internal static extern IntPtr CryptCATEnumerateCatAttr( + IntPtr hCatalog, + IntPtr pPrevAttr + ); + [DllImport("wintrust.dll", CharSet = CharSet.Unicode)] internal static extern IntPtr CryptCATEnumerateMember( IntPtr hCatalog, @@ -2211,8 +2216,7 @@ namespace System.Management.Automation.Security void CryptCATCDFEnumMembersByCDFTagExErrorCallBack(DWORD NotUsedDWORD1, DWORD NotUsedDWORD2, [MarshalAs(UnmanagedType.LPWStr)] - string NotUsedString); - + string NotUsedString); } } diff --git a/src/System.Management.Automation/singleshell/config/RunspaceConfigForSingleShell.cs b/src/System.Management.Automation/singleshell/config/RunspaceConfigForSingleShell.cs index 6a05afde1..0cc1f1ad6 100644 --- a/src/System.Management.Automation/singleshell/config/RunspaceConfigForSingleShell.cs +++ b/src/System.Management.Automation/singleshell/config/RunspaceConfigForSingleShell.cs @@ -425,7 +425,7 @@ namespace System.Management.Automation.Runspaces Dictionary> aliases = null; Dictionary providers = null; string throwAwayHelpFile = null; - PSSnapInHelpers.AnalyzePSSnapInAssembly(assembly, ClrFacade.GetAssemblyLocation(assembly), mshsnapinInfo, null, false, out cmdlets, out aliases, out providers, out throwAwayHelpFile); + PSSnapInHelpers.AnalyzePSSnapInAssembly(assembly, assembly.Location, mshsnapinInfo, null, false, out cmdlets, out aliases, out providers, out throwAwayHelpFile); if (cmdlets != null) { foreach (var c in cmdlets) diff --git a/src/System.Management.Automation/utils/ClrFacade.cs b/src/System.Management.Automation/utils/ClrFacade.cs index 744e2bb5e..d2d72851d 100644 --- a/src/System.Management.Automation/utils/ClrFacade.cs +++ b/src/System.Management.Automation/utils/ClrFacade.cs @@ -20,9 +20,7 @@ using System.Runtime.InteropServices.ComTypes; #if CORECLR using System.Runtime.Loader; /* used in facade APIs related to assembly operations */ -using System.Text.RegularExpressions; /* used in facade API 'GetFileSecurityZone' */ using System.Management.Automation.Host; /* used in facade API 'GetUninitializedObject' */ -using System.Management.Automation.Internal; /* used in facade API 'GetFileSecurityZone' */ using Microsoft.PowerShell.CoreClr.Stubs; /* used in facade API 'GetFileSecurityZone' */ #else using Microsoft.PowerShell.Commands.Internal; /* used in the facade APIs related to 'SafeProcessHandle' */ @@ -233,17 +231,6 @@ namespace System.Management.Automation #endregion Marshal #region Assembly - - /// - /// Facade for Assembly.Location - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static string GetAssemblyLocation(Assembly assembly) - { - // Porting note: Asembly.Location is in recent CoreCLR - return assembly.Location; - } - /// /// Facade for AssemblyName.GetAssemblyName(string) /// @@ -276,8 +263,7 @@ namespace System.Management.Automation internal static IEnumerable GetAssemblies(string namespaceQualifiedTypeName = null) { #if CORECLR - var psAssemblyLoader = GetAssemblyLoader(); - return psAssemblyLoader.GetAssemblies(namespaceQualifiedTypeName); + return PSAssemblyLoadContext.GetAssemblies(namespaceQualifiedTypeName); #else return AppDomain.CurrentDomain.GetAssemblies().Where(a => !(a.FullName.Length > 0 && a.FullName[0] == FIRST_CHAR_PSASSEMBLY_MARK)); #endif @@ -290,24 +276,12 @@ namespace System.Management.Automation internal static Assembly LoadFrom(string assemblyPath) { #if CORECLR - var psAssemblyLoader = GetAssemblyLoader(); - return psAssemblyLoader.LoadFrom(assemblyPath); + return PSAssemblyLoadContext.LoadFrom(assemblyPath); #else return Assembly.LoadFrom(assemblyPath); #endif } -#if CORECLR - /// - /// Load assemlby from byte stream. - /// - internal static Assembly LoadFrom(Stream assembly) - { - var psAssemblyLoader = GetAssemblyLoader(); - return psAssemblyLoader.LoadFrom(assembly); - } -#endif - /// /// Porting note: Load assembly by name through the AssemblyLoadContext. /// This is to ensure that the types get cached. @@ -315,8 +289,7 @@ namespace System.Management.Automation internal static Assembly Load(AssemblyName assembly) { #if CORECLR - var psAssemblyLoader = GetAssemblyLoader(); - return psAssemblyLoader.LoadFromAssemblyName(assembly); + return PSAssemblyLoadContext.LoadFromAssemblyName(assembly); #else return Assembly.Load(assembly); #endif @@ -328,8 +301,7 @@ namespace System.Management.Automation internal static Assembly Load(string assembly) { #if CORECLR - var psAssemblyLoader = GetAssemblyLoader(); - return psAssemblyLoader.LoadFromAssemblyName(new AssemblyName(assembly)); + return PSAssemblyLoadContext.LoadFromAssemblyName(new AssemblyName(assembly)); #else return Assembly.Load(assembly); #endif @@ -347,8 +319,7 @@ namespace System.Management.Automation #if CORECLR // Create the enum type and add the dynamic assembly to assembly cache. TypeInfo enumTypeinfo = enumBuilder.CreateTypeInfo(); - var psAssemblyLoader = GetAssemblyLoader(); - psAssemblyLoader.TryAddAssemblyToCache(enumTypeinfo.Assembly); + PSAssemblyLoadContext.TryAddAssemblyToCache(enumTypeinfo.Assembly); #else enumBuilder.CreateTypeInfo(); #endif @@ -370,8 +341,7 @@ namespace System.Management.Automation throw new ArgumentNullException("assemblyShortName"); } - var psAssemblyLoader = GetAssemblyLoader(); - return psAssemblyLoader.ProbeAssemblyFileForMetadataAnalysis(assemblyShortName, additionalSearchPath); + return PSAssemblyLoadContext.ProbeAssemblyFileForMetadataAnalysis(assemblyShortName, additionalSearchPath); } /// @@ -380,22 +350,33 @@ namespace System.Management.Automation /// internal static IEnumerable GetAvailableCoreClrDotNetTypes() { - var psAssemblyLoader = GetAssemblyLoader(); - return psAssemblyLoader.GetAvailableDotNetTypes(); + return PSAssemblyLoadContext.GetAvailableDotNetTypes(); } /// - /// Get the powershell custom AssemblyLoadContext. + /// Load assemlby from byte stream. /// - internal static PowerShellAssemblyLoader GetAssemblyLoader() + internal static Assembly LoadFrom(Stream assembly) { - if (_psLoadContext == null) + return PSAssemblyLoadContext.LoadFrom(assembly); + } + + /// + /// Add the AssemblyLoad handler + /// + // Porting note: disabled until full solution comes + // internal static void AddAssemblyLoadHandler(Action handler) + // { + // PSAssemblyLoadContext.AssemblyLoad += handler; + // } + + private static PowerShellAssemblyLoader PSAssemblyLoadContext + { + get { - _psLoadContext = PowerShellAssemblyLoader.Instance; + return PowerShellAssemblyLoader.Instance; } - return _psLoadContext; } - private static volatile PowerShellAssemblyLoader _psLoadContext; #endif /// diff --git a/src/System.Management.Automation/utils/PsUtils.cs b/src/System.Management.Automation/utils/PsUtils.cs index 78b0b54c1..574a4704e 100644 --- a/src/System.Management.Automation/utils/PsUtils.cs +++ b/src/System.Management.Automation/utils/PsUtils.cs @@ -14,7 +14,6 @@ using System.Security; using System.Text; using System.Xml; using Microsoft.Win32; -using Dbg = System.Management.Automation.Diagnostics; using System.Collections.Generic; using System.Management.Automation.Language; using Microsoft.Management.Infrastructure; @@ -146,6 +145,7 @@ namespace System.Management.Automation } } +#if !CORECLR // .NET Frmework Version is not applicable to CoreCLR /// /// Detects the installation of Frmework Versions 1.1, 2.0, 3.0 and 3.5 and 4.0 through /// the official registry instalation keys. @@ -334,7 +334,7 @@ namespace System.Management.Automation private static Version V3_0_00 = new Version(3, 0, 0, 0); private static Version V2_0_00 = new Version(2, 0, 0, 0); private static Version V1_1_00 = new Version(1, 1, 0, 0); - + // Dictionary holding compatible .NET framework versions // This is used in verifying the .NET framework version for loading module manifest internal static Dictionary> CompatibleNetFrameworkVersions = new Dictionary>() { @@ -349,7 +349,6 @@ namespace System.Management.Automation // .NET 4.5 is the highest known .NET version for PowerShell 3.0 internal static Version KnownHighestNetFrameworkVersion = new Version(4,5); - /// /// Returns true if IsFrameworkInstalled will be able to check for this framework version. /// @@ -532,6 +531,7 @@ namespace System.Management.Automation return true; } } +#endif /// /// Returns processor architecture for the current process. diff --git a/src/System.Management.Automation/utils/ResourceManagerCache.cs b/src/System.Management.Automation/utils/ResourceManagerCache.cs index 9bb7f8958..d95e2bf64 100644 --- a/src/System.Management.Automation/utils/ResourceManagerCache.cs +++ b/src/System.Management.Automation/utils/ResourceManagerCache.cs @@ -63,7 +63,7 @@ namespace System.Management.Automation ResourceManager manager = null; Dictionary baseNameCache; - string assemblyManifestFileLocation = ClrFacade.GetAssemblyLocation(assembly); + string assemblyManifestFileLocation = assembly.Location; lock (syncRoot) { // First do the lookup based on the assembly location diff --git a/src/System.Management.Automation/utils/StructuredTraceSource.cs b/src/System.Management.Automation/utils/StructuredTraceSource.cs index 3f4184907..f2c218aa3 100644 --- a/src/System.Management.Automation/utils/StructuredTraceSource.cs +++ b/src/System.Management.Automation/utils/StructuredTraceSource.cs @@ -434,12 +434,12 @@ namespace System.Management.Automation OutputLine( PSTraceSourceOptions.All, "\tAssembly Location: {0}", - ClrFacade.GetAssemblyLocation(callingAssembly)); + callingAssembly.Location); // Assembly File timestamp FileInfo assemblyFileInfo = - new FileInfo(ClrFacade.GetAssemblyLocation(callingAssembly)); + new FileInfo(callingAssembly.Location); OutputLine( PSTraceSourceOptions.All, diff --git a/src/powershell-native/nativemsh/pwrshcommon/NativeMsh.h b/src/powershell-native/nativemsh/pwrshcommon/NativeMsh.h index 8e2dd0bf7..df477f4cc 100644 --- a/src/powershell-native/nativemsh/pwrshcommon/NativeMsh.h +++ b/src/powershell-native/nativemsh/pwrshcommon/NativeMsh.h @@ -16,7 +16,6 @@ #include #include "NativeMshConstants.h" #include "ClrHostWrapper.h" -#include "ConfigFileReader.h" #include "SystemCallFacade.h" #include "IPwrshCommonOutput.h" @@ -26,7 +25,6 @@ namespace NativeMsh { private: IPwrshCommonOutput* output; - ConfigFileReader* reader; // TODO: Remove if we are no longer supporting a config file SystemCallFacade* sysCalls; public: @@ -39,7 +37,6 @@ namespace NativeMsh // allocate them with "new". PwrshCommon( IPwrshCommonOutput* outObj, // Enables clients to specify how error messages are displayed or suppressed - ConfigFileReader* rdr, // Specifies actions to take when processing config files SystemCallFacade* systemCalls); // Wraps all calls to Windows APIs to allow for dependency injection via unit test ~PwrshCommon(); diff --git a/src/powershell-native/nativemsh/pwrshcommon/pwrshcommon.cpp b/src/powershell-native/nativemsh/pwrshcommon/pwrshcommon.cpp index b5215d15d..0f9deb37e 100644 --- a/src/powershell-native/nativemsh/pwrshcommon/pwrshcommon.cpp +++ b/src/powershell-native/nativemsh/pwrshcommon/pwrshcommon.cpp @@ -860,21 +860,7 @@ namespace NativeMsh hostPath[lastBackslashIndex + 1] = '\0'; hostEnvironment.SetHostPath(hostPath); - unsigned int result = EXIT_CODE_SUCCESS; - - result = reader->Read(hostPath); // Is this OK? Should I first try the default location? - if (EXIT_CODE_SUCCESS == result) - { - // The config file was successfully parsed. Use that directory. - hostEnvironment.SetHostDirectoryPath(reader->GetPathToPowerShell().c_str()); - } - else - { - // There was an issue accessing or parsing the config file OR - // we are working for the EXE. - // Fall back to the default PowerShell install directory. - hostEnvironment.SetHostDirectoryPath(powerShellInstallPath); - } + hostEnvironment.SetHostDirectoryPath(powerShellInstallPath); return EXIT_CODE_SUCCESS; } @@ -1037,26 +1023,20 @@ namespace NativeMsh // PwrshCommon::PwrshCommon() - : output(new PwrshCommonOutputDefault()), reader(new ConfigFileReader()), sysCalls(new WinSystemCallFacade()) + : output(new PwrshCommonOutputDefault()), sysCalls(new WinSystemCallFacade()) { } PwrshCommon::PwrshCommon( IPwrshCommonOutput* outObj, - ConfigFileReader* rdr, SystemCallFacade* systemCalls) - : output(outObj), reader(rdr), sysCalls(systemCalls) + : output(outObj), sysCalls(systemCalls) { if (NULL == output) { output = new PwrshCommonOutputDefault(); } - if (NULL == reader) - { - reader = new ConfigFileReader(); - } - if (NULL == sysCalls) { sysCalls = new WinSystemCallFacade(); @@ -1071,12 +1051,6 @@ namespace NativeMsh output = NULL; } - if (reader) - { - delete reader; - reader = NULL; - } - if (sysCalls) { delete sysCalls; diff --git a/src/powershell-native/nativemsh/pwrshexe/MainEntry.cpp b/src/powershell-native/nativemsh/pwrshexe/MainEntry.cpp index 5c9b5ea81..e85bed577 100644 --- a/src/powershell-native/nativemsh/pwrshexe/MainEntry.cpp +++ b/src/powershell-native/nativemsh/pwrshexe/MainEntry.cpp @@ -49,7 +49,7 @@ WCHAR g_IconApp[MAX_PATH+1]; // All these objects will be destroyed when pwrshCommon goes out of scope. PwrshExeOutput* pwrshExeOutput = new PwrshExeOutput(); -PwrshCommon pwrshCommon(pwrshExeOutput, new ConfigFileReader(), new WinSystemCallFacade()); +PwrshCommon pwrshCommon(pwrshExeOutput, new WinSystemCallFacade()); bool ConvertArgvToSafeArray( IN int argc,