Skip to content
This repository has been archived by the owner on Jul 26, 2023. It is now read-only.

Add Kernel32.GetNativeSystemInfo #499

Merged
merged 2 commits into from Jul 8, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/Kernel32.Tests/Kernel32Facts.cs
Expand Up @@ -70,4 +70,17 @@ public void GetVolumeInformationTest()
Assert.NotEqual((FileSystemFlags)0, flags);
Assert.NotEmpty(new string(fileSystemNameBuffer));
}

[Fact]
public unsafe void GetNativeSystemInfo_Works()
{
GetNativeSystemInfo(out SYSTEM_INFO systemInfo);

Assert.True(Enum.IsDefined(typeof(Kernel32.ProcessorArchitecture), systemInfo.wProcessorArchitecture));
Assert.NotEqual(0, systemInfo.dwPageSize);
Assert.NotEqual(0, (int)systemInfo.dwActiveProcessorMask);
Assert.Equal(Environment.ProcessorCount, systemInfo.dwNumberOfProcessors);
Assert.True(Enum.IsDefined(typeof(Kernel32.ProcessorType), systemInfo.dwProcessorType));
Assert.NotEqual(0, systemInfo.dwAllocationGranularity);
}
}
49 changes: 49 additions & 0 deletions src/Kernel32/Kernel32+ProcessorArchitecture.cs
@@ -0,0 +1,49 @@
// Copyright © .NET Foundation and Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace PInvoke
{
using System;

/// <content>
/// Contains the <see cref="ProcessorArchitecture"/> nested type.
/// </content>
public partial class Kernel32
{
/// <summary>
/// The processor architecture of the installed operating system.
/// </summary>
public enum ProcessorArchitecture : ushort
{
/// <summary>
/// x64 (AMD or Intel)
/// </summary>
PROCESSOR_ARCHITECTURE_AMD64 = 9,

/// <summary>
/// ARM
/// </summary>
PROCESSOR_ARCHITECTURE_ARM = 5,

/// <summary>
/// ARM64
/// </summary>
PROCESSOR_ARCHITECTURE_ARM64 = 12,

/// <summary>
/// Intel Itanium-based
/// </summary>
PROCESSOR_ARCHITECTURE_IA64 = 6,

/// <summary>
/// x86
/// </summary>
PROCESSOR_ARCHITECTURE_INTEL = 0,

/// <summary>
/// Unknown architecture.
/// </summary>
PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF
}
}
}
22 changes: 22 additions & 0 deletions src/Kernel32/Kernel32+ProcessorType.cs
@@ -0,0 +1,22 @@
// Copyright © .NET Foundation and Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace PInvoke
{
using System;

/// <content>
/// Contains the <see cref="ProcessorType"/> nested type.
/// </content>
public partial class Kernel32
{
public enum ProcessorType
{
PROCESSOR_INTEL_386 = 386,
PROCESSOR_INTEL_486 = 486,
PROCESSOR_INTEL_PENTIUM = 586,
PROCESSOR_INTEL_IA64 = 2200,
PROCESSOR_AMD_X8664 = 8664,
}
}
}
75 changes: 75 additions & 0 deletions src/Kernel32/Kernel32+SYSTEM_INFO.cs
@@ -0,0 +1,75 @@
// Copyright © .NET Foundation and Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace PInvoke
{
/// <content>
/// Contains the <see cref="SYSTEM_INFO"/> nested type.
/// </content>
public partial class Kernel32
{
/// <summary>
/// Contains information about the current computer system. This includes the architecture and type of
/// the processor, the number of processors in the system, the page size, and other such information.
/// </summary>
public unsafe struct SYSTEM_INFO
{
/// <summary>
/// The processor architecture of the installed operating system.
/// </summary>
public ProcessorArchitecture wProcessorArchitecture;

/// <summary>
/// This member is reserved for future use.
/// </summary>
public short wReserved;

/// <summary>
/// The page size and the granularity of page protection and commitment.
/// This is the page size used by the <c>VirtualAlloc</c> function.
/// </summary>
public int dwPageSize;

/// <summary>
/// A pointer to the lowest memory address accessible to applications and dynamic-link libraries (DLLs).
/// </summary>
public void* lpMinimumApplicationAddress;

/// <summary>
/// A pointer to the highest memory address accessible to applications and DLLs.
/// </summary>
public void* lpMaximumApplicationAddress;

/// <summary>
/// A mask representing the set of processors configured into the system.
/// Bit 0 is processor 0; bit 31 is processor 31.
/// </summary>
public int* dwActiveProcessorMask;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really a pointer. It's just a pointer-sized field. Let's use IntPtr here to make that clear.


/// <summary>
/// The number of logical processors in the current group.
/// </summary>
public int dwNumberOfProcessors;

/// <summary>
/// An obsolete member that is retained for compatibility.
/// </summary>
public ProcessorType dwProcessorType;

/// <summary>
/// The granularity for the starting address at which virtual memory can be allocated.
/// </summary>
public int dwAllocationGranularity;

/// <summary>
/// The architecture-dependent processor level. It should be used only for display purposes.
/// </summary>
public short wProcessorLevel;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ushort is more appropriate here since it's an (unsigned) WORD in native code. We'll sometimes use int instead of uint where the value is likely to be used in other .NET APIs that take int, but as a short/ushort, it's already non-standard. And I suspect ushort is accepted by int APIs implicitly anyway since the range just grows.


/// <summary>
/// The architecture-dependent processor revision.
/// </summary>
public short wProcessorRevision;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ushort is more appropriate here since it's an (unsigned) WORD in native code.

}
}
}
10 changes: 10 additions & 0 deletions src/Kernel32/Kernel32.cs
Expand Up @@ -991,6 +991,16 @@ public static partial class Kernel32
[DllImport(api_ms_win_core_processthreads_l1_1_1, SetLastError = true)]
public static extern ProcessPriorityClass GetPriorityClass(SafeObjectHandle hProcess);

/// <summary>
/// Retrieves information about the current system.
/// </summary>
/// <param name="lpSystemInfo">
/// A pointer to a <see cref="SYSTEM_INFO"/> structure that receives the information.
/// </param>
[DllImport(nameof(Kernel32))]
public static unsafe extern void GetNativeSystemInfo(
[Friendly(FriendlyFlags.Out)] SYSTEM_INFO* lpSystemInfo);

/// <summary>
/// Closes a file search handle opened by the FindFirstFile, FindFirstFileEx, FindFirstFileNameW,
/// FindFirstFileNameTransactedW, FindFirstFileTransacted, FindFirstStreamTransactedW, or FindFirstStreamW functions.
Expand Down
29 changes: 29 additions & 0 deletions src/Kernel32/PublicAPI.Unshipped.txt
Expand Up @@ -80,6 +80,19 @@ PInvoke.Kernel32.ProcessPriorityClass.HIGH_PRIORITY_CLASS = 128 -> PInvoke.Kerne
PInvoke.Kernel32.ProcessPriorityClass.IDLE_PRIORITY_CLASS = 64 -> PInvoke.Kernel32.ProcessPriorityClass
PInvoke.Kernel32.ProcessPriorityClass.NORMAL_PRIORITY_CLASS = 32 -> PInvoke.Kernel32.ProcessPriorityClass
PInvoke.Kernel32.ProcessPriorityClass.REALTIME_PRIORITY_CLASS = 256 -> PInvoke.Kernel32.ProcessPriorityClass
PInvoke.Kernel32.ProcessorArchitecture
PInvoke.Kernel32.ProcessorArchitecture.PROCESSOR_ARCHITECTURE_AMD64 = 9 -> PInvoke.Kernel32.ProcessorArchitecture
PInvoke.Kernel32.ProcessorArchitecture.PROCESSOR_ARCHITECTURE_ARM = 5 -> PInvoke.Kernel32.ProcessorArchitecture
PInvoke.Kernel32.ProcessorArchitecture.PROCESSOR_ARCHITECTURE_ARM64 = 12 -> PInvoke.Kernel32.ProcessorArchitecture
PInvoke.Kernel32.ProcessorArchitecture.PROCESSOR_ARCHITECTURE_IA64 = 6 -> PInvoke.Kernel32.ProcessorArchitecture
PInvoke.Kernel32.ProcessorArchitecture.PROCESSOR_ARCHITECTURE_INTEL = 0 -> PInvoke.Kernel32.ProcessorArchitecture
PInvoke.Kernel32.ProcessorArchitecture.PROCESSOR_ARCHITECTURE_UNKNOWN = 65535 -> PInvoke.Kernel32.ProcessorArchitecture
PInvoke.Kernel32.ProcessorType
PInvoke.Kernel32.ProcessorType.PROCESSOR_AMD_X8664 = 8664 -> PInvoke.Kernel32.ProcessorType
PInvoke.Kernel32.ProcessorType.PROCESSOR_INTEL_386 = 386 -> PInvoke.Kernel32.ProcessorType
PInvoke.Kernel32.ProcessorType.PROCESSOR_INTEL_486 = 486 -> PInvoke.Kernel32.ProcessorType
PInvoke.Kernel32.ProcessorType.PROCESSOR_INTEL_IA64 = 2200 -> PInvoke.Kernel32.ProcessorType
PInvoke.Kernel32.ProcessorType.PROCESSOR_INTEL_PENTIUM = 586 -> PInvoke.Kernel32.ProcessorType
PInvoke.Kernel32.STARTUPINFO.Desktop.get -> string
PInvoke.Kernel32.STARTUPINFO.Title.get -> string
PInvoke.Kernel32.STARTUPINFO.hStdError -> System.IntPtr
Expand All @@ -94,6 +107,19 @@ PInvoke.Kernel32.STARTUPINFO.lpReserved_IntPtr.set -> void
PInvoke.Kernel32.STARTUPINFO.lpTitle -> char*
PInvoke.Kernel32.STARTUPINFO.lpTitle_IntPtr.get -> System.IntPtr
PInvoke.Kernel32.STARTUPINFO.lpTitle_IntPtr.set -> void
PInvoke.Kernel32.SYSTEM_INFO
PInvoke.Kernel32.SYSTEM_INFO.SYSTEM_INFO() -> void
PInvoke.Kernel32.SYSTEM_INFO.dwActiveProcessorMask -> int*
PInvoke.Kernel32.SYSTEM_INFO.dwAllocationGranularity -> int
PInvoke.Kernel32.SYSTEM_INFO.dwNumberOfProcessors -> int
PInvoke.Kernel32.SYSTEM_INFO.dwPageSize -> int
PInvoke.Kernel32.SYSTEM_INFO.dwProcessorType -> PInvoke.Kernel32.ProcessorType
PInvoke.Kernel32.SYSTEM_INFO.lpMaximumApplicationAddress -> void*
PInvoke.Kernel32.SYSTEM_INFO.lpMinimumApplicationAddress -> void*
PInvoke.Kernel32.SYSTEM_INFO.wProcessorArchitecture -> PInvoke.Kernel32.ProcessorArchitecture
PInvoke.Kernel32.SYSTEM_INFO.wProcessorLevel -> short
PInvoke.Kernel32.SYSTEM_INFO.wProcessorRevision -> short
PInvoke.Kernel32.SYSTEM_INFO.wReserved -> short
PInvoke.Kernel32.SafePseudoConsoleHandle
PInvoke.Kernel32.SafePseudoConsoleHandle.SafePseudoConsoleHandle() -> void
PInvoke.Kernel32.SafePseudoConsoleHandle.SafePseudoConsoleHandle(System.IntPtr preexistingHandle, bool ownsHandle = true) -> void
Expand Down Expand Up @@ -153,6 +179,8 @@ static PInvoke.Kernel32.GetCurrentProcessorNumberEx(System.IntPtr ProcNumber) ->
static PInvoke.Kernel32.GetCurrentProcessorNumberEx(out PInvoke.Kernel32.PROCESSOR_NUMBER ProcNumber) -> void
static PInvoke.Kernel32.GetHandleInformation(System.Runtime.InteropServices.SafeHandle hObject, System.IntPtr lpdwFlags) -> bool
static PInvoke.Kernel32.GetHandleInformation(System.Runtime.InteropServices.SafeHandle hObject, out PInvoke.Kernel32.HandleFlags lpdwFlags) -> bool
static PInvoke.Kernel32.GetNativeSystemInfo(System.IntPtr lpSystemInfo) -> void
static PInvoke.Kernel32.GetNativeSystemInfo(out PInvoke.Kernel32.SYSTEM_INFO lpSystemInfo) -> void
static PInvoke.Kernel32.GetStartupInfo(System.IntPtr lpStartupInfo) -> void
static PInvoke.Kernel32.GetStartupInfo(ref PInvoke.Kernel32.STARTUPINFO lpStartupInfo) -> void
static PInvoke.Kernel32.GetVolumeInformation(string lpRootPathName, System.IntPtr lpVolumeNameBuffer, int nVolumeNameSize, out uint lpVolumeSerialNumber, out int lpMaximumComponentLength, out PInvoke.Kernel32.FileSystemFlags lpFileSystemFlags, System.IntPtr lpFileSystemNameBuffer, int nFileSystemNameSize) -> bool
Expand Down Expand Up @@ -186,6 +214,7 @@ static extern PInvoke.Kernel32.GetCurrentThreadEffectiveToken() -> PInvoke.Kerne
static extern PInvoke.Kernel32.GetCurrentThreadStackLimits(out System.UIntPtr LowLimit, out System.UIntPtr HighLimit) -> void
static extern PInvoke.Kernel32.GetCurrentThreadToken() -> PInvoke.Kernel32.SafeObjectHandle
static extern PInvoke.Kernel32.GetHandleInformation(System.Runtime.InteropServices.SafeHandle hObject, PInvoke.Kernel32.HandleFlags* lpdwFlags) -> bool
static extern PInvoke.Kernel32.GetNativeSystemInfo(PInvoke.Kernel32.SYSTEM_INFO* lpSystemInfo) -> void
static extern PInvoke.Kernel32.GetPriorityClass(PInvoke.Kernel32.SafeObjectHandle hProcess) -> PInvoke.Kernel32.ProcessPriorityClass
static extern PInvoke.Kernel32.GetProcessHandleCount(PInvoke.Kernel32.SafeObjectHandle hProcess, out uint pdwHandleCount) -> bool
static extern PInvoke.Kernel32.GetProcessId(System.IntPtr Process) -> int
Expand Down