Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
2.5 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright � Microsoft Corporation. All rights reserved.
  4. //
  5. // ImpersonateRevert.h
  6. //
  7. // Purpose: revert impersonated thread token
  8. //
  9. //***************************************************************************
  10. #if _MSC_VER > 1000
  11. #pragma once
  12. #endif
  13. #ifndef __IMPERSONATE_REVERT__
  14. #define __IMPERSONATE_REVERT__
  15. class ProviderImpersonationRevert
  16. {
  17. HANDLE hThreadToken;
  18. BOOL bImpersonated;
  19. BOOL bReverted;
  20. public:
  21. ProviderImpersonationRevert ( BOOL bThreadCall = TRUE ) :
  22. hThreadToken ( INVALID_HANDLE_VALUE ),
  23. bImpersonated ( TRUE ),
  24. bReverted ( FALSE )
  25. {
  26. BOOL bDone = TRUE;
  27. BOOL bThreadCall_Local = bThreadCall;
  28. do
  29. {
  30. bDone = TRUE;
  31. if ( OpenThreadToken (
  32. GetCurrentThread(),
  33. TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE,
  34. bThreadCall_Local,
  35. &hThreadToken
  36. )
  37. )
  38. {
  39. if ( RevertToSelf() )
  40. {
  41. bReverted = TRUE;
  42. }
  43. else
  44. {
  45. #if DBG == 1
  46. // for testing purpose I will let process break
  47. ::DebugBreak();
  48. #endif
  49. }
  50. }
  51. else
  52. {
  53. DWORD dwError = ::GetLastError ();
  54. if ( ERROR_ACCESS_DENIED == dwError )
  55. {
  56. if ( bThreadCall_Local )
  57. {
  58. #if DBG == 1
  59. // for testing purpose I will let process break
  60. ::DebugBreak();
  61. #endif
  62. }
  63. else
  64. {
  65. bThreadCall_Local = TRUE;
  66. bDone = FALSE;
  67. }
  68. }
  69. else if ( ERROR_NO_TOKEN == dwError || ERROR_NO_IMPERSONATION_TOKEN == dwError )
  70. {
  71. bImpersonated = FALSE;
  72. }
  73. }
  74. }
  75. while ( ! bDone );
  76. }
  77. ~ProviderImpersonationRevert ()
  78. {
  79. // impersonate back (if not already)
  80. Impersonate ();
  81. if ( hThreadToken != INVALID_HANDLE_VALUE )
  82. {
  83. CloseHandle(hThreadToken);
  84. hThreadToken = INVALID_HANDLE_VALUE;
  85. }
  86. }
  87. BOOL Reverted ()
  88. {
  89. return ( bImpersonated && bReverted );
  90. }
  91. BOOL Impersonate ()
  92. {
  93. if ( Reverted () )
  94. {
  95. if ( ! ImpersonateLoggedOnUser ( hThreadToken ) )
  96. {
  97. #if DBG == 1
  98. // for testing purpose I will let process break
  99. ::DebugBreak();
  100. #endif
  101. // we need to throw here to avoid running as process
  102. throw CFramework_Exception( L"ImpersonateLoggedOnUser failed", HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ;
  103. }
  104. else
  105. {
  106. bReverted = FALSE;
  107. }
  108. }
  109. return !bReverted;
  110. }
  111. };
  112. #endif __IMPERSONATE_REVERT__