tag:blogger.com,1999:blog-6698224.post-1097257664552456162004-10-08T13:32:00.000-05:002004-10-08T13:09:26.773-05:00The ExecutionContext class in the .NET Framework 2.0<span style="font-family:trebuchet ms;">The following example shows a basic use of the new ExecutionContext class. This class allows you to capture the current context where the code is executing in (e.g. security, syncronization, call context, etc.)</span> <br /><span style="font-family:trebuchet ms;"></span> <br /><span style="font-family:Trebuchet MS;">If you use both ThreadPool.UnsafeQueueUserWorkItem and ThreadPool.UnsafeRegisterForWaitForSingleObject methods, you will notice that in your callback method you don't have access to a bunch of context data like the the security context. If you impersonate an User before calling any of the ThreadPool.Unsafe* methods, the identity that will use your callback method will be the process identity, not the impersonated one. </span> <br /><span style="font-family:Trebuchet MS;"></span> <br /><span style="font-family:Trebuchet MS;">This example shows you how to access the impersonated identity from the callback executed by ThreadPoolUnsafeQueueUserWorkItem.</span><span style="font-family:Trebuchet MS;"></span> <br /><span style="font-family:Trebuchet MS;"></span><span style="font-family:Trebuchet MS;"></span> <br /><span style="font-family:courier new;font-size:78%;">// Author: danielvl(removethis)@microsoft.com <br /> <br />using System; <br />using System.Text; <br />using System.Threading; <br />using System.Security.Principal; <br />using System.Runtime.InteropServices; <br />class Program <br />{ <br /> [DllImport("advapi32.dll")] <br /> public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken); <br />static void Main(string[] args) <br />{ <br /> WindowsImpersonationContext ctxt = null; <br /> try <br /> { <br /> // Impersonate other user <br /> IntPtr userToken; <br /> LogonUser("SimpleUser", "MyLocalMachine", "T.hisIsMy.Secret0", 2, 0, out userToken); <br /> // At this point I am MyDomain\danielvl <br /> ctxt = WindowsIdentity.Impersonate(userToken); <br /> // At this point I am MyLocalMachine\SimpleUser <br /> // Save my current context (MyLocalMachine\SimpleUser) <br /> ExecutionContext savedContext = ExecutionContext.Capture(); <br /> // Call the unsafe version of ThreadPool.QueueUserWorkItem <br /> ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(MyUserWorkItem), savedContext); <br /> } <br /> finally <br /> { <br /> // Revert identity to MyDomain\danielvl <br /> if (ctxt != null) <br /> ctxt.Undo(); <br /> } <br /> Console.Read(); <br />} <br />/// <summary> <br />/// Method invoked from ThreadPool.UnsafeQueueUserWorkItem <br />/// </summary> <br />static void MyUserWorkItem(object state) <br />{ <br /> // Restore the ExecutionContext object <br /> ExecutionContext context = (ExecutionContext)state; <br /> // Get the curren username where ThreadPool.UnsafeQueueUserWorkItem is executing <br /> string userNameFromUnsafeContext = WindowsIdentity.GetCurrent().Name; <br /> // Execute myContextCallbackHandler in the context saved <br /> ExecutionContext.Run(context.CreateCopy(), myContextCallbackHandler, userNameFromUnsafeContext); <br />} <br />/// <summary> <br />/// The handler to the ContextCallback delegate <br />/// </summary> <br />static ContextCallback myContextCallbackHandler = new ContextCallback(MyContextCallback); <br />/// <summary> <br />/// Method invoked from ExecutionContext.Run <br />/// </summary> <br />static void MyContextCallback(object state) <br />{ <br /> string userNameFromUnsafeContext = (string)state; <br /> string userNameFormSavedContext = WindowsIdentity.GetCurrent().Name; <br /> Console.WriteLine("Username from unsafe context is {0}", userNameFromUnsafeContext); <br /> Console.WriteLine("Username from context saved is {0}", userNameFormSavedContext); <br />} <br />}</span> <br /><span style="font-family:courier new;font-size:78%;"></span> <br /><span style="font-family:courier new;font-size:78%;">- Output - <br />Username from unsafe context is MyDomain\danielvl <br />Username from context saved is MyLocalMachine\SimpleUser</span> <br />Danielhttp://www.blogger.com/profile/11219787932132490222noreply@blogger.com