/// <summary>Converts the value of a security identifier (SID) to its equivalent string representation according to the provided format specifier.</summary> /// <param name="pSid">A pointer to a valid SID structure.</param> /// <param name="format"> /// A single format specifier that indicates how to format the value of this security identifier (SID). The format parameter can be /// "B" (binary), "D" (sddl), "N" (name), or "P" (upn). If format is null or an empty string (""), "D" is used. /// </param> /// <returns>The value of this security identifier (SID), in the specified format.</returns> /// <exception cref="ArgumentException">SID value is not a valid SID. - pSid</exception> /// <exception cref="FormatException">The value of format is not null, an empty string (""), "B", "D", "N", or "P".</exception> /// <remarks> /// <para>The following table shows the accepted format specifiers for the format parameter.</para> /// <list type="table"> /// <item> /// <description>Specifier</description> /// <description>Format of return value</description> /// </item> /// <item> /// <description>"B"</description> /// <description> /// <para>Binary hex dump representation of the SID.</para> /// </description> /// </item> /// <item> /// <description>"D"</description> /// <description>SDDL representation of the SID.</description> /// </item> /// <item> /// <description>"N"</description> /// <description>The NT4 style name (domain\username) corresponding to the SID.</description> /// </item> /// <item> /// <description>"P"</description> /// <description>The internet style name (UPN) corresponding to the SID.</description> /// </item> /// </list> /// </remarks> public static string ToString(this PSID pSid, string format) { if (!pSid.IsValidSid()) { throw new ArgumentException("SID value is not a valid SID.", nameof(pSid)); } switch (format) { case "B": var len = pSid.Length(); return(pSid.GetBinaryForm().ToHexDumpString(len, len, 0).Trim(' ', '\r', '\n')); case "D": case null: case "": try { return(AdvApi32.ConvertSidToStringSid(pSid)); } catch { goto case "B"; } case "N": case "P": using (var hPol = AdvApi32.LsaOpenPolicy(AdvApi32.LsaPolicyRights.POLICY_ALL_ACCESS)) { var flag = format == "P" ? AdvApi32.LsaLookupSidsFlags.LSA_LOOKUP_PREFER_INTERNET_NAMES : 0; try { AdvApi32.LsaLookupSids2(hPol, flag, 1, new[] { pSid }, out var memDoms, out var memNames).ThrowIfFailed(); memDoms.Dispose(); using (memNames) { return(memNames.ToStructure <AdvApi32.LSA_TRANSLATED_NAME>().Name); } } catch (Exception) { goto case "D"; } } default: throw new FormatException(); } }