openthreadtoken (advapi32)
Last changed: anfortas.geo@yahoo.com-216.204.61.86

.
Summary
Opens the access token associated with a thread

C# Signature:

[DllImport("advapi32.dll", SetLastError=true)]
static extern bool OpenThreadToken(
    IntPtr ThreadHandle,
    uint DesiredAccess,
    bool OpenAsSelf,
    out IntPtr TokenHandle);

VB Signature:

Declare Function OpenThreadToken Lib "advapi32.dll" (
   ThreadHandle As IntPtr,
   DesiredAccess As Integer,
   OpenAsSelf As Boolean,
   ByRef TokenHandle As IntPtr) As Boolean

User-Defined Types:

None.

Notes:

None.

Tips & Tricks:

Please add some!

Sample Code:

/// <summary>

/// HoldImpersonationCloak enables temporarily dropping the 'cloak' of

/// impersonation to access items as the process identity, so hiding another

/// account/password pair is not required. Useful in double-hop

/// situations where the process ID can be safely used for remote access.

/// </summary>

/// <example>

/// using (HoldImpersonationCloak hic = new HoldImpersonationCloak())

/// {

/// //operate here as process identity

/// GC.KeepAlive(hic); //prevent over-eager garbage collection optimization from taking it too soon

/// }

/// </example>

public class HoldImpersonationCloak : IDisposable

{

    #region Constants

    //Some declarations and code taken from http://support.microsoft.com/kb/306158/,
    // http://pluralsight.com/wiki/default.aspx/Keith.GuideBook/HowToImpersonateAUserGivenHerToken.html,
    // http://pluralsight.com/wiki/default.aspx/Keith.GuideBook/HowToCreateAWindowsPrincipalGivenAToken.html,
    // http://www.pinvoke.net

    private const int TOKEN_READ = 0x00020008; //From VC\PlatformSDK\Include\Winnt.h
    private const int TOKEN_IMPERSONATE = 0x0004;
    private const int ERROR_NO_TOKEN = 1008; //From VC\PlatformSDK\Include\WinError.h

    #endregion

    #region External Declarations

    [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr GetCurrentThread();

    [System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool OpenThreadToken(IntPtr ThreadHandle,
    uint DesiredAccess,
    bool OpenAsSelf,
    out IntPtr TokenHandle);

    [System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool SetThreadToken(IntPtr pHandle,
    IntPtr hToken);

    [System.Runtime.InteropServices.DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool RevertToSelf();

    [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr handle);

    #endregion

    #region Variables

    private IntPtr hToken = IntPtr.Zero;
    private int dw;

    #endregion

    public HoldImpersonationCloak()
    {
    if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ | TOKEN_IMPERSONATE, true, out hToken))
    {
        dw = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
        if (ERROR_NO_TOKEN == dw) //
        {
        System.Diagnostics.Trace.WriteLine("Not impersonating, cloak is a no-op!", "Impersonation");
        }
        else
        {
        System.Diagnostics.Trace.WriteLine("Unexpected error 0x" + dw.ToString("x4") + " on OpenThreadToken", "Impersonation");
        }
        hToken = IntPtr.Zero;
    }
    else
    {
        if (!RevertToSelf())
        {
        dw = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
        System.Diagnostics.Trace.WriteLine("Failed to revert!, error 0x" + dw.ToString("x4"), "Impersonation");
        }
    }
    }

   //Implement IDisposable. (from Implementing Finalize and Dispose to Clean Up Unmanaged Resources )
   public void Dispose()
   {
    Dispose(true);
    GC.SuppressFinalize(this);
   }

   protected virtual void Dispose(bool disposing)
   {
      if (disposing)
      {
     // Free other state (managed objects).
      if (IntPtr.Zero != hToken)
      {
          if (!SetThreadToken(IntPtr.Zero, hToken))
          {
          dw = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
          System.Diagnostics.Trace.WriteLine("Could not reset cloak!, error 0x" + dw.ToString("x4"), "Impersonation");
          }
      }

      }
      // Free your own state (unmanaged objects).
      if (IntPtr.Zero != hToken)
      {
      if (!CloseHandle(hToken))
      {
          dw = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
          System.Diagnostics.Trace.WriteLine("Could not close cloak token!, error 0x" + dw.ToString("x4"), "Impersonation"); ;
      }
      hToken = IntPtr.Zero;
      }
     // Set large fields to null.
   }

   // Use C# destructor syntax for finalization code.
    ~HoldImpersonationCloak()
   {
      // Simply call Dispose(false).
      Dispose (false);
   }

}

Alternative Managed API:

Do you know one? Please contribute it!

Documentation