Export (0) Print
Expand All

Marshal.ZeroFreeGlobalAllocUnicode Method

Frees an unmanaged string pointer that was allocated using the SecureStringToGlobalAllocUnicode method.

Namespace:  System.Runtime.InteropServices
Assembly:  mscorlib (in mscorlib.dll)

public static void ZeroFreeGlobalAllocUnicode(
	IntPtr s
)

Parameters

s
Type: System.IntPtr

The address of the unmanaged string to free.

The ZeroFreeGlobalAllocUnicode method first zeros out and then frees unmanaged memory that was allocated using the SecureStringToGlobalAllocUnicode method.

The following example demonstrates how to use the SecureStringToGlobalAllocUnicode method with the unmanaged LogonUser function to perform impersonation with the SecureString class. The example then uses the ZeroFreeGlobalAllocUnicode method to zero out and free the unmanaged string reference.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;
using System.Text;

namespace SecureStringImpersonationExample
{

    class ImpersonationExample
    {

        // PInvoke into the Win32 API to provide access to the  
        // LogonUser and CloseHandle functions.
        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        internal static extern bool LogonUser(String username, String domain, IntPtr password,
                int logonType, int logonProvider, ref IntPtr token);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public extern static bool CloseHandle(IntPtr handle);

        // Define the required LogonUser enumerations. 
        const int LOGON32_PROVIDER_DEFAULT = 0;
        const int LOGON32_LOGON_INTERACTIVE = 2;


        static void Main(string[] args)
        {
            try
            {
                // Display the current user before impersonation.
                Console.WriteLine("Before impersonation: "
                    + WindowsIdentity.GetCurrent().Name);

                // Ask the user for a network domain.
                Console.Write("Please enter your domain:");

                string domain = Console.ReadLine();

                // Ask the user for a user name.
                Console.Write("Please enter your user name:");

                string username = Console.ReadLine();

                // Ask the user for a password.
                Console.Write("Please enter your password:");

                SecureString passWord = GetPassword();

                // Impersonate the account provided by the user.
                WindowsImpersonationContext userContext = ImpersonateUser(passWord, username, domain);

                // Display the current user after impersonation.
                Console.WriteLine("After impersonation: "
                    + WindowsIdentity.GetCurrent().Name);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.ReadLine();


        }

        public static SecureString GetPassword()
        {
            SecureString password = new SecureString();

            // get the first character of the password
            ConsoleKeyInfo nextKey = Console.ReadKey(true);

            while (nextKey.Key != ConsoleKey.Enter)
            {
                if (nextKey.Key == ConsoleKey.Backspace)
                {
                    if (password.Length > 0)
                    {
                        password.RemoveAt(password.Length - 1);

                        // erase the last * as well
                        Console.Write(nextKey.KeyChar);
                        Console.Write(" ");
                        Console.Write(nextKey.KeyChar);
                    }
                }
                else
                {
                    password.AppendChar(nextKey.KeyChar);
                    Console.Write("*");
                }

                nextKey = Console.ReadKey(true);
            }

            Console.WriteLine();

            // lock the password down
            password.MakeReadOnly();
            return password;
        }


        public static WindowsImpersonationContext ImpersonateUser(SecureString password, string userName, string domainName)
        {
            IntPtr tokenHandle = IntPtr.Zero;

            IntPtr passwordPtr = IntPtr.Zero;

            bool returnValue = false;

            try
            {
                // Marshal the SecureString to unmanaged memory.
                passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password);

                // Call LogonUser, passing the unmanaged (and decrypted) copy of 
                // the SecureString password.
                returnValue = LogonUser(userName, domainName, passwordPtr, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);

            }
            finally
            {
                // Zero-out and free the unmanaged string reference.
                Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr);

                // Close the token handle.
                CloseHandle(tokenHandle);
            }

            // Get the Last win32 Error and throw an exception. 
            if (!returnValue && tokenHandle == IntPtr.Zero)
            {
                int error = Marshal.GetLastWin32Error();

                throw new System.ComponentModel.Win32Exception(error);

            }
            // The token that is passed to the following constructor must  
            // be a primary token in order to use it for impersonation.
            WindowsIdentity newId = new WindowsIdentity(tokenHandle);

            return newId.Impersonate();
        }
    }
}

.NET Framework

Supported in: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Portable Class Library

Supported in: Portable Class Library

.NET for Windows Store apps

Supported in: Windows 8

.NET for Windows Phone apps

Supported in: Windows Phone 8.1

  • SecurityCriticalAttribute 

    requires full trust for the immediate caller. This member cannot be used by partially trusted or transparent code.

Windows Phone 8.1, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Server Core Role not supported), Windows Server 2008 R2 (Server Core Role supported with SP1 or later; Itanium not supported)

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

Show:
© 2014 Microsoft