Search
Module:
Directory

   Desktop Functions:

   Smart Device Functions:


Show Recent Changes
Subscribe (RSS)
Misc. Pages
Comments
FAQ
Helpful Tools
Playground
Suggested Reading
Website TODO List
Download Visual Studio Add-In

OpenThreadToken (advapi32)
 
.
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

Please edit this page!

Do you have...

  • helpful tips or sample code to share for using this API in managed code?
  • corrections to the existing content?
  • variations of the signature you want to share?
  • additional languages you want to include?

Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing supporting types needed for this API (structures, delegates, and more).

 
Access PInvoke.net directly from VS:
Terms of Use
Edit This Page
Find References
Show Printable Version
Revisions