-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
don't run LongModuleFileNamesAreSupported test on x86 #57471
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
80392a9
don't run LongModuleFileNamesAreSupported test on x86 (for some reaso…
adamsitnik 97c2857
apply code review suggestion
adamsitnik ee99091
ensure type called "Interop" has no namespace, so Interop files from …
adamsitnik 14c02bc
try JanK suggestion and use LoadLibrary instead of Assembly.LoadFile
adamsitnik 487748d
don't try to check module file path if we can't load the module itsel…
adamsitnik File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
12 changes: 3 additions & 9 deletions
12
src/libraries/System.Diagnostics.Process/tests/Interop.Unix.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,10 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
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 | ||
{ | ||
[DllImport("libc")] | ||
internal static extern int getsid(int pid); | ||
} | ||
[DllImport("libc")] | ||
internal static extern int getsid(int pid); | ||
} |
212 changes: 105 additions & 107 deletions
212
src/libraries/System.Diagnostics.Process/tests/Interop.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,145 +1,143 @@ | ||
// 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; | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
src/libraries/System.Diagnostics.Process/tests/ProcessModuleTests.Windows.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// 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); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this
Interop
type was causing a conflict with the otherInterop
that we use in product code and because of that I was not able to callInterop.Kernel32.LoadLibrary
in the test code. I decided to just remove the namespace so it de-facto becames a singleInterop
type.