// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System;
using Microsoft.Win32.SafeHandles;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.Principal;
-namespace System.Diagnostics.Tests
+internal static partial class Interop
{
- internal static partial class Interop
+ [StructLayout(LayoutKind.Sequential, Size = 40)]
+ public struct PROCESS_MEMORY_COUNTERS
{
- [StructLayout(LayoutKind.Sequential, Size = 40)]
- public struct PROCESS_MEMORY_COUNTERS
- {
- public uint cb;
- public uint PageFaultCount;
- public uint PeakWorkingSetSize;
- public uint WorkingSetSize;
- public uint QuotaPeakPagedPoolUsage;
- public uint QuotaPagedPoolUsage;
- public uint QuotaPeakNonPagedPoolUsage;
- public uint QuotaNonPagedPoolUsage;
- public uint PagefileUsage;
- public uint PeakPagefileUsage;
- }
+ public uint cb;
+ public uint PageFaultCount;
+ public uint PeakWorkingSetSize;
+ public uint WorkingSetSize;
+ public uint QuotaPeakPagedPoolUsage;
+ public uint QuotaPagedPoolUsage;
+ public uint QuotaPeakNonPagedPoolUsage;
+ public uint QuotaNonPagedPoolUsage;
+ public uint PagefileUsage;
+ public uint PeakPagefileUsage;
+ }
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- internal struct USER_INFO_1
- {
- public string usri1_name;
- public string usri1_password;
- public uint usri1_password_age;
- public uint usri1_priv;
- public string usri1_home_dir;
- public string usri1_comment;
- public uint usri1_flags;
- public string usri1_script_path;
- }
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ internal struct USER_INFO_1
+ {
+ public string usri1_name;
+ public string usri1_password;
+ public uint usri1_password_age;
+ public uint usri1_priv;
+ public string usri1_home_dir;
+ public string usri1_comment;
+ public uint usri1_flags;
+ public string usri1_script_path;
+ }
- [StructLayout(LayoutKind.Sequential)]
- public struct TOKEN_USER
- {
- public SID_AND_ATTRIBUTES User;
- }
+ [StructLayout(LayoutKind.Sequential)]
+ public struct TOKEN_USER
+ {
+ public SID_AND_ATTRIBUTES User;
+ }
- [StructLayout(LayoutKind.Sequential)]
- public struct SID_AND_ATTRIBUTES
- {
- public IntPtr Sid;
- public int Attributes;
- }
+ [StructLayout(LayoutKind.Sequential)]
+ public struct SID_AND_ATTRIBUTES
+ {
+ public IntPtr Sid;
+ public int Attributes;
+ }
- [DllImport("kernel32.dll")]
- public static extern bool GetProcessWorkingSetSizeEx(SafeProcessHandle hProcess, out IntPtr lpMinimumWorkingSetSize, out IntPtr lpMaximumWorkingSetSize, out uint flags);
+ [DllImport("kernel32.dll")]
+ public static extern bool GetProcessWorkingSetSizeEx(SafeProcessHandle hProcess, out IntPtr lpMinimumWorkingSetSize, out IntPtr lpMaximumWorkingSetSize, out uint flags);
- [DllImport("kernel32.dll")]
- internal static extern bool ProcessIdToSessionId(uint dwProcessId, out uint pSessionId);
+ [DllImport("kernel32.dll")]
+ internal static extern bool ProcessIdToSessionId(uint dwProcessId, out uint pSessionId);
- [DllImport("kernel32.dll")]
- public static extern int GetProcessId(SafeProcessHandle nativeHandle);
+ [DllImport("kernel32.dll")]
+ public static extern int GetProcessId(SafeProcessHandle nativeHandle);
- [DllImport("kernel32.dll")]
- internal static extern int GetConsoleCP();
+ [DllImport("kernel32.dll")]
+ internal static extern int GetConsoleCP();
- [DllImport("kernel32.dll")]
- internal static extern int GetConsoleOutputCP();
+ [DllImport("kernel32.dll")]
+ internal static extern int GetConsoleOutputCP();
- [DllImport("kernel32.dll")]
- internal static extern int SetConsoleCP(int codePage);
+ [DllImport("kernel32.dll")]
+ internal static extern int SetConsoleCP(int codePage);
- [DllImport("kernel32.dll")]
- internal static extern int SetConsoleOutputCP(int codePage);
+ [DllImport("kernel32.dll")]
+ internal static extern int SetConsoleOutputCP(int codePage);
- [DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern uint NetUserAdd(string servername, uint level, ref USER_INFO_1 buf, out uint parm_err);
+ [DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
+ internal static extern uint NetUserAdd(string servername, uint level, ref USER_INFO_1 buf, out uint parm_err);
- [DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
- internal static extern uint NetUserDel(string servername, string username);
+ [DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
+ internal static extern uint NetUserDel(string servername, string username);
- [DllImport("advapi32.dll")]
- internal static extern bool OpenProcessToken(SafeProcessHandle ProcessHandle, uint DesiredAccess, out SafeProcessHandle TokenHandle);
+ [DllImport("advapi32.dll")]
+ internal static extern bool OpenProcessToken(SafeProcessHandle ProcessHandle, uint DesiredAccess, out SafeProcessHandle TokenHandle);
- [DllImport("advapi32.dll")]
- internal static extern bool GetTokenInformation(SafeProcessHandle TokenHandle, uint TokenInformationClass, IntPtr TokenInformation, int TokenInformationLength, ref int ReturnLength);
+ [DllImport("advapi32.dll")]
+ internal static extern bool GetTokenInformation(SafeProcessHandle TokenHandle, uint TokenInformationClass, IntPtr TokenInformation, int TokenInformationLength, ref int ReturnLength);
- [DllImport("shell32.dll")]
- internal static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
+ [DllImport("shell32.dll")]
+ internal static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
- internal static void NetUserAdd(string username, string password)
- {
- USER_INFO_1 userInfo = new USER_INFO_1();
- userInfo.usri1_name = username;
- userInfo.usri1_password = password;
- userInfo.usri1_priv = 1;
+ internal static void NetUserAdd(string username, string password)
+ {
+ USER_INFO_1 userInfo = new USER_INFO_1();
+ userInfo.usri1_name = username;
+ userInfo.usri1_password = password;
+ userInfo.usri1_priv = 1;
- uint parm_err;
- uint result = NetUserAdd(null, 1, ref userInfo, out parm_err);
+ uint parm_err;
+ uint result = NetUserAdd(null, 1, ref userInfo, out parm_err);
- if (result != ExitCodes.NERR_Success)
- {
- // most likely result == ERROR_ACCESS_DENIED
- // due to running without elevated privileges
- throw new Win32Exception((int)result);
- }
+ if (result != ExitCodes.NERR_Success)
+ {
+ // most likely result == ERROR_ACCESS_DENIED
+ // due to running without elevated privileges
+ throw new Win32Exception((int)result);
}
+ }
- internal static bool ProcessTokenToSid(SafeProcessHandle token, out SecurityIdentifier sid)
+ internal static bool ProcessTokenToSid(SafeProcessHandle token, out SecurityIdentifier sid)
+ {
+ bool ret = false;
+ sid = null;
+ IntPtr tu = IntPtr.Zero;
+ try
{
- bool ret = false;
- sid = null;
- IntPtr tu = IntPtr.Zero;
- try
- {
- TOKEN_USER tokUser;
- const int bufLength = 256;
-
- tu = Marshal.AllocHGlobal(bufLength);
- int cb = bufLength;
- ret = GetTokenInformation(token, 1, tu, cb, ref cb);
- if (ret)
- {
- tokUser = Marshal.PtrToStructure<TOKEN_USER>(tu);
- sid = new SecurityIdentifier(tokUser.User.Sid);
- }
- return ret;
- }
- catch (Exception)
- {
- return false;
- }
- finally
+ TOKEN_USER tokUser;
+ const int bufLength = 256;
+
+ tu = Marshal.AllocHGlobal(bufLength);
+ int cb = bufLength;
+ ret = GetTokenInformation(token, 1, tu, cb, ref cb);
+ if (ret)
{
- if (tu != IntPtr.Zero)
- Marshal.FreeHGlobal(tu);
+ tokUser = Marshal.PtrToStructure<TOKEN_USER>(tu);
+ sid = new SecurityIdentifier(tokUser.User.Sid);
}
+ return ret;
}
-
- internal static class ExitCodes
+ catch (Exception)
+ {
+ return false;
+ }
+ finally
{
- internal const uint NERR_Success = 0;
- internal const uint NERR_UserNotFound = 2221;
+ if (tu != IntPtr.Zero)
+ Marshal.FreeHGlobal(tu);
}
}
+
+ internal static class ExitCodes
+ {
+ internal const uint NERR_Success = 0;
+ internal const uint NERR_UserNotFound = 2221;
+ }
}
--- /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 System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using Xunit;
+
+namespace System.Diagnostics.Tests
+{
+ public partial class ProcessModuleTests : ProcessTestBase
+ {
+ [ConditionalFact(typeof(PathFeatures), nameof(PathFeatures.AreAllLongPathsAvailable))]
+ public void LongModuleFileNamesAreSupported()
+ {
+ // To be able to test Long Path support for ProcessModule.FileName we need a .dll that has a path > 260 chars.
+ // Since Long Paths support can be disabled (see the ConditionalFact attribute usage above),
+ // we just copy "LongName.dll" from bin to a temp directory with a long name and load it from there.
+ // Loading from new path is possible because the type exposed by the assembly is not referenced in any explicit way.
+ const string libraryName = "LongPath.dll";
+ const int minPathLength = 261;
+
+ string testBinPath = Path.GetDirectoryName(typeof(ProcessModuleTests).Assembly.Location);
+ string libraryToCopy = Path.Combine(testBinPath, libraryName);
+ Assert.True(File.Exists(libraryToCopy), $"{libraryName} was not present in bin folder '{testBinPath}'");
+
+ string directoryWithLongName = Path.Combine(TestDirectory, new string('a', Math.Max(1, minPathLength - TestDirectory.Length)));
+ Directory.CreateDirectory(directoryWithLongName);
+
+ string longNamePath = Path.Combine(directoryWithLongName, libraryName);
+ Assert.True(longNamePath.Length > minPathLength);
+
+ File.Copy(libraryToCopy, longNamePath);
+ Assert.True(File.Exists(longNamePath));
+
+ IntPtr moduleHandle = Interop.Kernel32.LoadLibrary(longNamePath);
+ if (moduleHandle == IntPtr.Zero)
+ {
+ Assert.Equal(126, Marshal.GetLastWin32Error()); // ERROR_MOD_NOT_FOUND
+ Assert.Equal(Architecture.X86, RuntimeInformation.ProcessArchitecture);
+ return; // we have failed to load the module on x86, we skip the rest of the test (it's best effort)
+ }
+
+ try
+ {
+ string[] modulePaths = Process.GetCurrentProcess().Modules.Cast<ProcessModule>().Select(module => module.FileName).ToArray();
+ Assert.Contains(longNamePath, modulePaths);
+ }
+ finally
+ {
+ Interop.Kernel32.FreeLibrary(moduleHandle);
+ }
+ }
+ }
+}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.IO;
using System.Linq;
-using System.Reflection;
using Microsoft.DotNet.RemoteExecutor;
using Xunit;
namespace System.Diagnostics.Tests
{
- public class ProcessModuleTests : ProcessTestBase
+ public partial class ProcessModuleTests : ProcessTestBase
{
[Fact]
public void TestModuleProperties()
process.Dispose();
Assert.Equal(expectedCount, disposedCount);
}
-
- public static bool Is_LongModuleFileNamesAreSupported_TestEnabled
- => PathFeatures.AreAllLongPathsAvailable() // we want to test long paths
- && !PlatformDetection.IsMonoRuntime // Assembly.LoadFile used the way this test is implemented fails on Mono
- && OperatingSystem.IsWindowsVersionAtLeast(8); // it's specific to Windows and does not work on Windows 7
-
- [ConditionalFact(typeof(ProcessModuleTests), nameof(Is_LongModuleFileNamesAreSupported_TestEnabled))]
- public void LongModuleFileNamesAreSupported()
- {
- // To be able to test Long Path support for ProcessModule.FileName we need a .dll that has a path > 260 chars.
- // Since Long Paths support can be disabled (see the ConditionalFact attribute usage above),
- // we just copy "LongName.dll" from bin to a temp directory with a long name and load it from there.
- // Loading from new path is possible because the type exposed by the assembly is not referenced in any explicit way.
- const string libraryName = "LongPath.dll";
- const int minPathLength = 261;
-
- string testBinPath = Path.GetDirectoryName(typeof(ProcessModuleTests).Assembly.Location);
- string libraryToCopy = Path.Combine(testBinPath, libraryName);
- Assert.True(File.Exists(libraryToCopy), $"{libraryName} was not present in bin folder '{testBinPath}'");
-
- string directoryWithLongName = Path.Combine(TestDirectory, new string('a', Math.Max(1, minPathLength - TestDirectory.Length)));
- Directory.CreateDirectory(directoryWithLongName);
-
- string longNamePath = Path.Combine(directoryWithLongName, libraryName);
- Assert.True(longNamePath.Length > minPathLength);
-
- File.Copy(libraryToCopy, longNamePath);
- Assert.True(File.Exists(longNamePath));
-
- Assembly loaded = Assembly.LoadFile(longNamePath);
- Assert.Equal(longNamePath, loaded.Location);
-
- string[] modulePaths = Process.GetCurrentProcess().Modules.Cast<ProcessModule>().Select(module => module.FileName).ToArray();
- Assert.Contains(longNamePath, modulePaths);
- }
}
}