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