}
}
+ public static bool CanRunImpersonatedTests => PlatformDetection.IsNotWindowsNanoServer && PlatformDetection.IsWindowsAndElevated;
+
private static int s_isWindowsElevated = -1;
public static bool IsWindowsAndElevated
{
using System.Security.Principal;
using System.Threading.Tasks;
using Microsoft.Win32.SafeHandles;
+using Xunit;
namespace System
{
public WindowsTestAccount(string userName)
{
+ Assert.True(PlatformDetection.IsWindowsAndElevated);
+
_userName = userName;
CreateUser();
}
throw new Win32Exception((int)result);
}
}
+ else if (result != 0)
+ {
+ throw new Win32Exception((int)result);
+ }
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_INTERACTIVE = 2;
{
// Files that begin with periods are considered hidden on Unix
string[] paths = GetNames(TestDirectory, new EnumerationOptions { ReturnSpecialDirectories = true, AttributesToSkip = 0 });
- Assert.Contains(".", paths);
+
+ if (!PlatformDetection.IsWindows10Version22000OrGreater)
+ {
+ // Sometimes this is not returned - presumably an OS bug.
+ // This occurs often on Windows 11, very rarely otherwise.
+ Assert.Contains(".", paths);
+ }
+
Assert.Contains("..", paths);
}
}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using Microsoft.DotNet.XUnitExtensions;
+using System.Diagnostics;
+using System.Diagnostics.Eventing.Reader;
+using System.Linq;
+using System.Security;
+using System.ServiceProcess;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace System.IO.Tests
+{
+ public partial class EncryptDecrypt
+ {
+ partial void EnsureEFSServiceStarted()
+ {
+ try
+ {
+ using var sc = new ServiceController("EFS");
+ _output.WriteLine($"EFS service is: {sc.Status}");
+ if (sc.Status != ServiceControllerStatus.Running)
+ {
+ _output.WriteLine("Trying to start EFS service");
+ sc.Start();
+ _output.WriteLine($"EFS service is now: {sc.Status}");
+ }
+ }
+ catch (Exception e)
+ {
+ _output.WriteLine(e.ToString());
+ }
+ }
+
+ partial void LogEFSDiagnostics()
+ {
+ int hours = 1; // how many hours to look backwards
+ string query = @$"
+ <QueryList>
+ <Query Id='0' Path='System'>
+ <Select Path='System'>
+ *[System[Provider/@Name='Server']]
+ </Select>
+ <Select Path='System'>
+ *[System[Provider/@Name='Service Control Manager']]
+ </Select>
+ <Select Path='System'>
+ *[System[Provider/@Name='Microsoft-Windows-EFS']]
+ </Select>
+ <Suppress Path='System'>
+ *[System[TimeCreated[timediff(@SystemTime) >= {hours * 60 * 60 * 1000L}]]]
+ </Suppress>
+ </Query>
+ </QueryList> ";
+
+ var eventQuery = new EventLogQuery("System", PathType.LogName, query);
+
+ using var eventReader = new EventLogReader(eventQuery);
+
+ EventRecord record = eventReader.ReadEvent();
+ var garbage = new string[] { "Background Intelligent", "Intel", "Defender", "Intune", "BITS", "NetBT"};
+
+ _output.WriteLine("===== Dumping recent relevant events: =====");
+ while (record != null)
+ {
+ string description = "";
+ try
+ {
+ description = record.FormatDescription();
+ }
+ catch (EventLogException) { }
+
+ if (!garbage.Any(term => description.Contains(term, StringComparison.OrdinalIgnoreCase)))
+ {
+ _output.WriteLine($"{record.TimeCreated} {record.ProviderName} [{record.LevelDisplayName} {record.Id}] {description.Replace("\r\n", " ")}");
+ }
+
+ record = eventReader.ReadEvent();
+ }
+
+ _output.WriteLine("==== Finished dumping =====");
+ }
+ }
+}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using Microsoft.DotNet.XUnitExtensions;
using System.Diagnostics;
+using System.Diagnostics.Eventing.Reader;
using System.Security;
+using System.ServiceProcess;
using Xunit;
+using Xunit.Abstractions;
namespace System.IO.Tests
{
[ActiveIssue("https://github.com/dotnet/runtime/issues/34582", TestPlatforms.Windows, TargetFrameworkMonikers.Netcoreapp, TestRuntimes.Mono)]
- public class EncryptDecrypt : FileSystemTest
+ public partial class EncryptDecrypt : FileSystemTest
{
+ private readonly ITestOutputHelper _output;
+
+ public EncryptDecrypt(ITestOutputHelper output)
+ {
+ _output = output;
+ }
+
[Fact]
- public static void NullArg_ThrowsException()
+ public void NullArg_ThrowsException()
{
AssertExtensions.Throws<ArgumentNullException>("path", () => File.Encrypt(null));
AssertExtensions.Throws<ArgumentNullException>("path", () => File.Decrypt(null));
[SkipOnTargetFramework(TargetFrameworkMonikers.Netcoreapp)]
[Fact]
- public static void EncryptDecrypt_NotSupported()
+ public void EncryptDecrypt_NotSupported()
{
Assert.Throws<PlatformNotSupportedException>(() => File.Encrypt("path"));
Assert.Throws<PlatformNotSupportedException>(() => File.Decrypt("path"));
// because EFS (Encrypted File System), its underlying technology, is not available on these operating systems.
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer), nameof(PlatformDetection.IsNotWindowsHomeEdition))]
[PlatformSpecific(TestPlatforms.Windows)]
- public static void EncryptDecrypt_Read()
+ [OuterLoop] // Occasional failures: https://github.com/dotnet/runtime/issues/12339
+ public void EncryptDecrypt_Read()
{
string tmpFileName = Path.GetTempFileName();
string textContentToEncrypt = "Content to encrypt";
string fileContentRead = File.ReadAllText(tmpFileName);
Assert.Equal(textContentToEncrypt, fileContentRead);
+ EnsureEFSServiceStarted();
+
try
{
File.Encrypt(tmpFileName);
}
- catch (IOException e) when (e.HResult == unchecked((int)0x80070490))
+ catch (IOException e) when (e.HResult == unchecked((int)0x80070490) ||
+ e.HResult == unchecked((int)0x80071776) ||
+ e.HResult == unchecked((int)0x800701AE))
{
// Ignore ERROR_NOT_FOUND 1168 (0x490). It is reported when EFS is disabled by domain policy.
- return;
+ // Ignore ERROR_NO_USER_KEYS (0x1776). This occurs when no user key exists to encrypt with.
+ // Ignore ERROR_ENCRYPTION_DISABLED (0x1AE). This occurs when EFS is disabled by group policy on the volume.
+ throw new SkipTestException($"Encrypt not available. Error 0x{e.HResult:X}");
+ }
+ catch (IOException e)
+ {
+ _output.WriteLine($"Encrypt failed with {e.Message} 0x{e.HResult:X}");
+ LogEFSDiagnostics();
+ throw;
}
Assert.Equal(fileContentRead, File.ReadAllText(tmpFileName));
File.Delete(tmpFileName);
}
}
+
+ partial void EnsureEFSServiceStarted(); // no-op on Unix
+
+ partial void LogEFSDiagnostics(); // no-op on Unix currently
}
}
<Compile Include="$(CommonPath)System\Text\ValueStringBuilder.cs" Link="Common\System\Text\ValueStringBuilder.cs" />
<Compile Include="$(CoreLibSharedDir)System\IO\PathInternal.cs" Link="Common\System\IO\PathInternal.cs" />
<Compile Include="$(CoreLibSharedDir)System\IO\PathInternal.Windows.cs" Link="Common\System\IO\PathInternal.Windows.cs" />
+ <ProjectReference Include="$(LibrariesProjectRoot)System.ServiceProcess.ServiceController\src\System.ServiceProcess.ServiceController.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsBrowser)' == 'true'">
<Compile Remove="..\**\*.Unix.cs" />
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
<Compile Include="Base\SymbolicLinks\BaseSymbolicLinks.Windows.cs" />
<Compile Include="Directory\Delete.Windows.cs" />
+ <Compile Include="File\EncryptDecrypt.Windows.cs" />
<Compile Include="FileSystemTest.Windows.cs" />
<Compile Include="FileStream\ctor_options.Windows.cs" />
<Compile Include="FileStream\FileStreamConformanceTests.Windows.cs" />
using System.Collections;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Runtime.InteropServices;
namespace System.IO.Ports.Tests
buffer = new char[buffer.Length * 2];
dataSize = QueryDosDevice(null, buffer, buffer.Length);
}
+ else if (lastError == ERROR_ACCESS_DENIED) // Access denied eg for "MSSECFLTSYS" - just skip
+ {
+ dataSize = 0;
+ break;
+ }
else
{
- throw new Exception("Unknown Win32 Error: " + lastError);
+ throw new Exception($"Error {lastError} calling QueryDosDevice for '{name}' with buffer size {buffer.Length}. {new Win32Exception((int)lastError).Message}");
}
}
return buffer;
}
+ public const int ERROR_ACCESS_DENIED = 5;
public const int ERROR_INSUFFICIENT_BUFFER = 122;
public const int ERROR_MORE_DATA = 234;
{
public class ImpersonatedAuthTests: IClassFixture<WindowsIdentityFixture>
{
- public static bool CanRunImpersonatedTests = PlatformDetection.IsWindows && PlatformDetection.IsNotWindowsNanoServer;
private readonly WindowsIdentityFixture _fixture;
private readonly ITestOutputHelper _output;
}
[OuterLoop]
- [ConditionalTheory(nameof(CanRunImpersonatedTests))]
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.CanRunImpersonatedTests))]
[InlineData(true)]
[InlineData(false)]
[PlatformSpecific(TestPlatforms.Windows)]
- public async Task DefaultHandler_ImpersonificatedUser_Success(bool useNtlm)
+ public async Task DefaultHandler_ImpersonatedUser_Success(bool useNtlm)
{
await LoopbackServer.CreateClientAndServerAsync(
async uri =>
options.Ttl = 1;
// This should always fail unless host is one IP hop away.
pingReply = await ping.SendPingAsync(host, TestSettings.PingTimeout, TestSettings.PayloadAsBytesShort, options);
- Assert.NotEqual(IPStatus.Success, pingReply.Status);
+
+ Assert.True(pingReply.Status == IPStatus.TimeExceeded || pingReply.Status == IPStatus.TtlExpired);
+ Assert.NotEqual(IPAddress.Any, pingReply.Address);
}
[Fact]
Assert.False(string.IsNullOrEmpty(_fixture.TestAccount.AccountName));
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+ [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.CanRunImpersonatedTests))]
[OuterLoop]
public async Task RunImpersonatedAsync_TaskAndTaskOfT()
{
}
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+ [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.CanRunImpersonatedTests))]
[OuterLoop]
public void RunImpersonated_NameResolution()
{
});
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsNanoServer))]
+ [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.CanRunImpersonatedTests))]
[OuterLoop]
public async Task RunImpersonatedAsync_NameResolution()
{