Skip to content

Commit

Permalink
Fix interop for RTL_OSVERSIONINFOEX
Browse files Browse the repository at this point in the history
- Ensure that the OS version string is marshaled as Unicode
- Avoid allocating the version string when it is not needed

Fixes #32423
  • Loading branch information
jkotas committed Sep 24, 2018
1 parent 7eff72b commit a264e1e
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ internal partial class Interop
{
internal partial class NtDll
{
[StructLayout(LayoutKind.Sequential)]
internal struct RTL_OSVERSIONINFOEX
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
internal unsafe struct RTL_OSVERSIONINFOEX
{
internal uint dwOSVersionInfoSize;
internal uint dwMajorVersion;
internal uint dwMinorVersion;
internal uint dwBuildNumber;
internal uint dwPlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
internal string szCSDVersion;
internal fixed char szCSDVersion[128];
}
}
}
12 changes: 6 additions & 6 deletions src/Common/src/Interop/Windows/NtDll/Interop.RtlGetVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ internal partial class Interop
internal partial class NtDll
{
[DllImport(Libraries.NtDll, ExactSpelling=true)]
private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation);
private static extern int RtlGetVersion(ref RTL_OSVERSIONINFOEX lpVersionInformation);

internal static string RtlGetVersion()
internal static unsafe string RtlGetVersion()
{
RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX();
osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi);
var osvi = new RTL_OSVERSIONINFOEX();
osvi.dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX);
const string version = "Microsoft Windows";
if (RtlGetVersion(out osvi) == 0)
if (RtlGetVersion(ref osvi) == 0)
{
return string.Format("{0} {1}.{2}.{3} {4}",
version, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, osvi.szCSDVersion);
version, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, new string(&(osvi.szCSDVersion[0])));
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,19 +197,19 @@ private static int GetWindowsProductType()
return productType;
}

private static int GetWindowsMinorVersion()
private static unsafe int GetWindowsMinorVersion()
{
RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX();
osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi);
Assert.Equal(0, RtlGetVersion(out osvi));
var osvi = new RTL_OSVERSIONINFOEX();
osvi.dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX);
Assert.Equal(0, RtlGetVersion(ref osvi));
return (int)osvi.dwMinorVersion;
}

private static int GetWindowsBuildNumber()
private static unsafe int GetWindowsBuildNumber()
{
RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX();
osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi);
Assert.Equal(0, RtlGetVersion(out osvi));
var osvi = new RTL_OSVERSIONINFOEX();
osvi.dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX);
Assert.Equal(0, RtlGetVersion(ref osvi));
return (int)osvi.dwBuildNumber;
}

Expand Down Expand Up @@ -239,25 +239,24 @@ out int pdwReturnedProductType
);

[DllImport("ntdll.dll", ExactSpelling=true)]
private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation);
private static extern int RtlGetVersion(ref RTL_OSVERSIONINFOEX lpVersionInformation);

[StructLayout(LayoutKind.Sequential)]
private struct RTL_OSVERSIONINFOEX
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
private unsafe struct RTL_OSVERSIONINFOEX
{
internal uint dwOSVersionInfoSize;
internal uint dwMajorVersion;
internal uint dwMinorVersion;
internal uint dwBuildNumber;
internal uint dwPlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
internal string szCSDVersion;
internal fixed char szCSDVersion[128];
}

private static int GetWindowsVersion()
private static unsafe int GetWindowsVersion()
{
RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX();
osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi);
Assert.Equal(0, RtlGetVersion(out osvi));
var osvi = new RTL_OSVERSIONINFOEX();
osvi.dwOSVersionInfoSize = (uint)sizeof(RTL_OSVERSIONINFOEX);
Assert.Equal(0, RtlGetVersion(ref osvi));
return (int)osvi.dwMajorVersion;
}

Expand All @@ -273,5 +272,5 @@ private static int GetWindowsVersion()
// The process handle does NOT need closing
[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetCurrentProcess();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<PropertyGroup>
<RootNamespace>System.Runtime.InteropServices</RootNamespace>
<ProjectGuid>{1CBC030D-B5D3-4AB5-A9FD-24EC5F6F38D2}</ProjectGuid>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>netcoreapp-Unix-Debug;netcoreapp-Unix-Release;netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release;uapaot-Windows_NT-Debug;uapaot-Windows_NT-Release</Configurations>
</PropertyGroup>
<ItemGroup>
Expand Down

0 comments on commit a264e1e

Please sign in to comment.