Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.ComponentModel;
- using System.Runtime.InteropServices;
- [module: DefaultCharSet(CharSet.Unicode)]
- public static class CredentialPrompt
- {
- public readonly struct Result
- {
- public Result(string userName, string domain, string password)
- {
- UserName = userName;
- Domain = domain;
- Password = password;
- }
- public string UserName { get; }
- public string Domain { get; }
- public string Password { get; }
- }
- public static Result? ShowDialog(HandleRef owner, string caption, string message, bool previousAttemptFailed)
- {
- var authPackage = (uint)0;
- var r = CredUIPromptForWindowsCredentials(
- new CREDUI_INFO(owner.Handle, message, caption),
- previousAttemptFailed ? (uint)WinErrorCode.LogonFailure : 0,
- ref authPackage,
- pvInAuthBuffer: IntPtr.Zero,
- ulInAuthBufferSize: 0,
- out var packedResultBuffer,
- out var packedResultBufferSize,
- pfSave: IntPtr.Zero,
- CREDUIWIN.GENERIC);
- using (packedResultBuffer)
- {
- switch ((WinErrorCode)r)
- {
- case WinErrorCode.Cancelled:
- return null;
- case WinErrorCode.Success:
- break;
- default:
- throw new Win32Exception(r);
- }
- unsafe
- {
- var userNameBufferSize = 128 * sizeof(char);
- var userNameBuffer = new char[userNameBufferSize];
- var domainBufferSize = 128 * sizeof(char);
- var domainBuffer = new char[domainBufferSize];
- var passwordBufferSize = 128 * sizeof(char);
- var passwordBuffer = new char[passwordBufferSize];
- fixed (char* usernamePointer = userNameBuffer)
- fixed (char* domainPointer = domainBuffer)
- fixed (char* passwordPointer = passwordBuffer)
- {
- try
- {
- if (!CredUnPackAuthenticationBuffer(CRED_PACK.GENERIC_CREDENTIALS, packedResultBuffer, packedResultBufferSize, usernamePointer, ref userNameBufferSize, domainPointer, ref domainBufferSize, passwordPointer, ref passwordBufferSize))
- throw new Win32Exception();
- GC.KeepAlive(owner.Wrapper);
- return new Result(
- new string(usernamePointer),
- new string(domainPointer),
- new string(passwordPointer));
- }
- finally
- {
- Array.Clear(passwordBuffer, 0, passwordBuffer.Length);
- }
- }
- }
- }
- }
- #pragma warning disable IDE0052 // Remove unread private members
- private enum WinErrorCode : ushort
- {
- Success = 0,
- Cancelled = 1223,
- LogonFailure = 1326
- }
- [DllImport("credui.dll", SetLastError = true)]
- private static extern unsafe bool CredUnPackAuthenticationBuffer(CRED_PACK dwFlags, CoTaskMemSafeHandle pAuthBuffer, uint cbAuthBuffer, char* pszUserName, ref int pcchMaxUserName, char* pszDomainName, ref int pcchMaxDomainame, char* pszPassword, ref int pcchMaxPassword);
- private sealed class CoTaskMemSafeHandle : SafeHandle
- {
- private CoTaskMemSafeHandle()
- : base(invalidHandleValue: IntPtr.Zero, ownsHandle: true)
- {
- }
- public override bool IsInvalid => handle == IntPtr.Zero;
- protected override bool ReleaseHandle()
- {
- Marshal.FreeCoTaskMem(handle);
- return true;
- }
- }
- private enum CRED_PACK : uint
- {
- PROTECTED_CREDENTIALS = 0x1,
- WOW_BUFFER = 0x2,
- GENERIC_CREDENTIALS = 0x4,
- ID_PROVIDER_CREDENTIALS = 0x8
- }
- private readonly struct CREDUI_INFO
- {
- private readonly int cbSize;
- private readonly IntPtr hwndParent;
- private readonly string pszMessageText;
- private readonly string pszCaptionText;
- private readonly IntPtr hbmBanner;
- public CREDUI_INFO(IntPtr hwndParent, string pszMessageText, string pszCaptionText)
- {
- cbSize = Marshal.SizeOf<CREDUI_INFO>();
- this.hwndParent = hwndParent;
- this.pszMessageText = pszMessageText;
- this.pszCaptionText = pszCaptionText;
- hbmBanner = IntPtr.Zero;
- }
- }
- [DllImport("credui.dll")]
- private static extern int CredUIPromptForWindowsCredentials(in CREDUI_INFO pUiInfo, uint dwAuthError, ref uint pulAuthPackage, IntPtr pvInAuthBuffer, uint ulInAuthBufferSize, out CoTaskMemSafeHandle ppvOutAuthBuffer, out uint pulOutAuthBufferSize, IntPtr pfSave, CREDUIWIN dwFlags);
- private enum CREDUIWIN : uint
- {
- GENERIC = 0x00000001,
- CHECKBOX = 0x00000002,
- AUTHPACKAGE_ONLY = 0x00000010,
- IN_CRED_ONLY = 0x00000020,
- ENUMERATE_ADMINS = 0x00000100,
- ENUMERATE_CURRENT_USER = 0x00000200,
- SECURE_PROMPT = 0x00001000,
- PREPROMPTING = 0x00002000,
- PACK_32_WOW = 0x10000000
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement