using System.Text; namespace Daybreak.Shared.Utils; /// /// Helpers for producing Windows compatible computer names. /// public static class ComputerNameUtils { /// /// Maximum length of a Windows NetBIOS computer name, matching the Win32 MAX_COMPUTERNAME_LENGTH constant. /// public const int MaxComputerNameLength = 15; /// /// Name used when no valid computer name can be derived from the host. /// public const string FallbackComputerName = "DAYBREAK"; /// /// Converts an arbitrary host name into a name that Win32 GetComputerName can return. /// /// /// GetComputerNameW is documented to fill a buffer of MAX_COMPUTERNAME_LENGTH + 1 characters, so callers /// size their buffers accordingly. When the configured name is longer, the call fails with /// ERROR_BUFFER_OVERFLOW and leaves the caller's buffer untouched, which applications such as GWToolbox /// observe as an empty computer name. Wine's own wineboot upper-cases and truncates the Linux host name /// for the same reason, so this method reproduces that behaviour. /// /// The host name to sanitize. /// An upper-case, at most characters long, non-empty computer name. public static string SanitizeComputerName(string? name) { if (name is null) { return FallbackComputerName; } var builder = new StringBuilder(MaxComputerNameLength); foreach (var c in name) { if (builder.Length >= MaxComputerNameLength) { break; } if (char.IsAsciiLetterOrDigit(c)) { builder.Append(char.ToUpperInvariant(c)); } else if (c is '-' or '_') { builder.Append(c); } } // A computer name may not start or end with a separator. while (builder.Length > 0 && builder[^1] is '-' or '_') { builder.Length--; } var sanitized = builder.ToString().TrimStart('-', '_'); return sanitized.Length is 0 ? FallbackComputerName : sanitized; } }