From 515b6199636ff2cfc64daf13808130752bc585eb Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 24 May 2019 12:49:32 +0500 Subject: [PATCH 1/3] Remove LCIDToLocaleName P/Invoke from GetComputerInfoCommand --- .../management/GetComputerInfoCommand.cs | 87 ++++++------------- 1 file changed, 27 insertions(+), 60 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs index d43641997f8..33ee20d3c87 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs @@ -5,11 +5,12 @@ using System; using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Reflection; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Linq.Expressions; using System.Management.Automation; -using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using System.Runtime.InteropServices; using Microsoft.Management.Infrastructure; using Microsoft.Win32; @@ -887,9 +888,8 @@ private static ComputerInfo CreateFullOutputObject(SystemInfoGroup systemInfo, O // we display info for only one string layout = otherInfo.keyboards[0].Layout; - var culture = Conversion.MakeLocale(layout); - output.KeyboardLayout = culture == null ? layout : culture.Name; + output.KeyboardLayout = Conversion.GetLocaleName(layout); } if (otherInfo.hyperV != null) @@ -1097,29 +1097,6 @@ internal static bool TryParseHex(string hexString, out uint value) } } - public static string LocaleIdToLocaleName(uint localeID) - { - // CoreCLR's System.Globalization.Culture does not appear to have a constructor - // that accepts an integer LocalID (LCID) value, so we'll PInvoke native code - // to get a locale name from an LCID value - - try - { - var sbName = new System.Text.StringBuilder(Native.LOCALE_NAME_MAX_LENGTH); - var len = Native.LCIDToLocaleName(localeID, sbName, sbName.Capacity, 0); - - if (len > 0 && sbName.Length > 0) - return sbName.ToString(); - } - catch (Exception) - { - // Probably failed to load the DLL or to file the function entry point. - // Fail silently - } - - return null; - } - /// /// Attempt to create a /// object from a locale string as retrieved from WMI. @@ -1136,38 +1113,36 @@ public static string LocaleIdToLocaleName(uint localeID) /// Failing that it attempts to retrieve the CultureInfo object /// using the locale string as passed. /// - internal static System.Globalization.CultureInfo MakeLocale(string locale) + internal static string GetLocaleName(string locale) { - System.Globalization.CultureInfo culture = null; + CultureInfo culture = null; if (locale != null) { try { - uint localeNum; - - if (TryParseHex(locale, out localeNum)) + // The "locale" must contain a hexadecimal value, with no + // base-indication prefix. For example, the string "0409" will be + // parsed into the base-10 integer value 1033, while the string "0x0409" + // will fail to parse due to the "0x" base-indication prefix. + if (UInt32.TryParse(locale, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint localeNum)) { - string localeName = LocaleIdToLocaleName(localeNum); - - if (localeName != null) - culture = new System.Globalization.CultureInfo(localeName); + culture = CultureInfo.GetCultureInfo((int)localeNum); } if (culture == null) { - // either the TryParseHex failed, or the LocaleIdToLocaleName - // failed, so we'll try using the original string - culture = new System.Globalization.CultureInfo(locale); + // If TryParse failed we'll try using the original string as culture name + culture = CultureInfo.GetCultureInfo(locale); } } - catch (Exception/* ex*/) + catch (Exception) { culture = null; } } - return culture; + return culture == null ? null : culture.Name; } /// @@ -1347,7 +1322,15 @@ internal abstract class WmiClassBase protected static string GetLanguageName(uint? language) { if (language != null) - return Conversion.LocaleIdToLocaleName(language.Value); + { + try + { + return CultureInfo.GetCultureInfo((int)language.Value).Name; + } + catch + { + } + } return null; } @@ -1896,12 +1879,7 @@ public OSProductSuite[] Suites #region Public Methods public string GetLocale() { - System.Globalization.CultureInfo culture = null; - - if (Locale != null) - culture = Conversion.MakeLocale(Locale); - - return culture == null ? null : culture.Name; + return Conversion.GetLocaleName(Locale); } #endregion Public Methods @@ -5152,17 +5130,6 @@ private static class PInvokeDllNames [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetFirmwareType(out FirmwareType firmwareType); - /// - /// Convert a Local Identifier to a Locale name. - /// - /// The Locale ID (LCID) to be converted. - /// Destination of the Locale name. - /// Capacity of - /// - /// - [DllImport(PInvokeDllNames.LCIDToLocaleNameDllName, SetLastError = true, CharSet = CharSet.Unicode)] - public static extern int LCIDToLocaleName(uint localeID, System.Text.StringBuilder localeName, int localeNameSize, int flags); - /// /// Gets the data specified for the passed in property name from the /// Software Licensing API. From 620ca23d6fe7fdf3e445de5d7f4c651478bfc0a6 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 24 May 2019 23:25:40 +0500 Subject: [PATCH 2/3] Remove unneeded const --- .../commands/management/GetComputerInfoCommand.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs index 33ee20d3c87..3df51fb572f 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs @@ -5090,7 +5090,6 @@ internal static class Native private static class PInvokeDllNames { public const string GetPhysicallyInstalledSystemMemoryDllName = "api-ms-win-core-sysinfo-l1-2-1.dll"; - public const string LCIDToLocaleNameDllName = "kernelbase.dll"; public const string PowerDeterminePlatformRoleExDllName = "api-ms-win-power-base-l1-1-0.dll"; public const string GetFirmwareTypeDllName = "api-ms-win-core-kernel32-legacy-l1-1-1"; } From a87e61448d5f24ddb10387629f66204fabf43fb4 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 24 May 2019 23:32:29 +0500 Subject: [PATCH 3/3] Add check LCID >=0 --- .../commands/management/GetComputerInfoCommand.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs index 3df51fb572f..dbf1c1bca09 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/GetComputerInfoCommand.cs @@ -1311,7 +1311,7 @@ internal abstract class WmiClassBase /// /// Get a language name from a language identifier. /// - /// + /// /// A nullable integer containing the language ID for the desired language. /// /// @@ -1319,13 +1319,13 @@ internal abstract class WmiClassBase /// the language parameter. If the language parameter is null or has a /// value that is not a valid language ID, the method returns null. /// - protected static string GetLanguageName(uint? language) + protected static string GetLanguageName(uint? lcid) { - if (language != null) + if (lcid != null && lcid >= 0) { try { - return CultureInfo.GetCultureInfo((int)language.Value).Name; + return CultureInfo.GetCultureInfo((int)lcid.Value).Name; } catch {