private Impersonation(String userName, String domain, String password, LogOnType logonType, BuiltInUser builtinUser)
        {
            switch (builtinUser)
            {
            case BuiltInUser.None: if (String.IsNullOrEmpty(userName))
                {
                    return;
                }
                break;

            case BuiltInUser.LocalService: userName = "******"; break;

            case BuiltInUser.NetworkService: userName = "******"; break;

            case BuiltInUser.LocalSystem: userName = "******"; break;
            }

            IntPtr userToken            = IntPtr.Zero;
            IntPtr userTokenDuplication = IntPtr.Zero;

            // Logon with user and get token.
            bool loggedOn = LogonUser(userName, domain, password,
                                      logonType, LogOnProvider.Default,
                                      out userToken);

            if (loggedOn)
            {
                try
                {
                    // Create a duplication of the usertoken, this is a solution
                    // for the known bug that is published under KB article Q319615.
                    if (DuplicateToken(userToken, 2, ref userTokenDuplication))
                    {
                        // Create windows identity from the token and impersonate the user.
                        WindowsIdentity identity = new WindowsIdentity(userTokenDuplication);
                        _impersonationContext = identity.Impersonate();
                    }
                    else
                    {
                        // Token duplication failed!
                        // Use the default ctor overload
                        // that will use Mashal.GetLastWin32Error();
                        // to create the exceptions details.
                        throw new Win32Exception();
                    }
                }
                finally
                {
                    // Close usertoken handle duplication when created.
                    if (!userTokenDuplication.Equals(IntPtr.Zero))
                    {
                        // Closes the handle of the user.
                        CloseHandle(userTokenDuplication);
                        userTokenDuplication = IntPtr.Zero;
                    }

                    // Close usertoken handle when created.
                    if (!userToken.Equals(IntPtr.Zero))
                    {
                        // Closes the handle of the user.
                        CloseHandle(userToken);
                        userToken = IntPtr.Zero;
                    }
                }
            }
            else
            {
                // Logon failed!
                // Use the default ctor overload that
                // will use Mashal.GetLastWin32Error();
                // to create the exceptions details.
                throw new Win32Exception();
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="Impersonation"/> class and
 /// impersonates as a built in service account.
 /// </summary>
 /// <param name="builtinUser">The built in user to impersonate - either
 /// Local Service or Network Service. These users can only be impersonated
 /// by code running as System.</param>
 public Impersonation(BuiltInUser builtinUser)
     : this(String.Empty, "NT AUTHORITY", String.Empty, LogOnType.Service, builtinUser)
 {
 }