/// <summary> /// Performs a user impersonation based on a logon token. /// </summary> /// <param name="token"> The logon token. </param> /// <param name="loadUserProfile"> Specifies whether the users profile is to be loaded. </param> /// <param name="func"> The code to run under the impersonated user. </param> /// <returns> /// The return value from <paramref name="func" />. /// </returns> /// <exception cref="ArgumentNullException"> <paramref name="func" /> is null. </exception> /// <exception cref="ArgumentException"> <paramref name="token" /> is zero. </exception> /// <exception cref="SecurityException"> The current user does not have sufficient permissions. </exception> /// <exception cref="Win32Exception"> /// The current user does not have sufficient permissions or the impersonation could not /// be completed. /// </exception> public static Task <TResult> RunImpersonatedAsync <TResult> (IntPtr token, bool loadUserProfile, ImpersonatedFuncAsync <TResult> func) { if (func == null) { throw new ArgumentNullException(nameof(func)); } if (token == IntPtr.Zero) { throw new ArgumentException("The token is zero.", nameof(token)); } Task <TResult> result = WindowsIdentity.RunImpersonatedAsync(new SafeAccessTokenHandle(token), async() => { WindowsIdentity identity = null; WindowsUserProfile profile = null; try { identity = new WindowsIdentity(token); if (loadUserProfile) { USERPROFILE profileInfo = new USERPROFILE(); profileInfo.dwSize = Marshal.SizeOf(profileInfo); profileInfo.lpUserName = identity.Name; profileInfo.dwFlags = 1; bool loadSuccess = WindowsUser.LoadUserProfile(token, ref profileInfo); if (!loadSuccess) { int errorCode = WindowsApi.GetLastErrorCode(); string errorMessage = WindowsApi.GetErrorMessage(errorCode); throw new Win32Exception(errorCode, errorMessage); } profile = new WindowsUserProfile(profileInfo); } return(await func(token, identity, profile)); } finally { if (profile != null) { WindowsUser.UnloadUserProfile(token, profile.NativeUserProfile.hProfile); } if (identity != null) { identity.Dispose(); } } }); return(result); }
private static extern bool LoadUserProfile(IntPtr hToken, ref USERPROFILE lpProfileInfo);