Source code of Windows XP (NT5)
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.

134 lines
4.2 KiB

  1. //***************************************************************************
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. // CreateMutexAsProcess.CPP
  6. //
  7. // Purpose: Create a mutex NOT using impersonation
  8. //
  9. //***************************************************************************
  10. #include "precomp.h"
  11. #include <brodcast.h>
  12. #include <CreateMutexAsProcess.h>
  13. #include "MultiPlat.h"
  14. CreateMutexAsProcess::CreateMutexAsProcess(const WCHAR *cszMutexName)
  15. {
  16. m_hMutex = NULL;
  17. bool bUseMutex = false;
  18. DWORD dwOSMajorVersion;
  19. dwOSMajorVersion = CWbemProviderGlue::GetOSMajorVersion();
  20. // HACK HACK HACK - special case for security mutex.
  21. // TODO: remove special case, make special class, see RAID 38371
  22. if (wcscmp(cszMutexName, SECURITYAPIMUTEXNAME) == 0)
  23. {
  24. //Work out if we need the mutex...
  25. if (CWbemProviderGlue::GetPlatform() == VER_PLATFORM_WIN32_NT)
  26. {
  27. if (dwOSMajorVersion < 5)
  28. //if (dwOSMajorVersion < 4) // see comment below
  29. {
  30. bUseMutex = true;
  31. }
  32. // Code changed from using the mutex if nt4sp4 or earlier, to plain old use it if less
  33. // than nt5 because some security issues have not been fixed in nt4, even up to sp6.
  34. /*
  35. else if (dwOSMajorVersion == 4)
  36. {
  37. LPCWSTR pcwstrCSDVersion = CWbemProviderGlue::GetCSDVersion();
  38. if ((pcwstrCSDVersion == NULL) || (pcwstrCSDVersion == L'\0'))
  39. {
  40. bUseMutex = true;
  41. }
  42. else
  43. {
  44. //Need to determine if we are SP4 or above as there is no need to use the
  45. //mutex if this is the case...
  46. bUseMutex = true;
  47. for (int i = 0; pcwstrCSDVersion[i] != '\0'; i++)
  48. {
  49. if (isdigit(pcwstrCSDVersion[i]))
  50. {
  51. if (_wtoi(&(pcwstrCSDVersion[i])) >= 4)
  52. {
  53. bUseMutex = false;
  54. }
  55. break;
  56. }
  57. }
  58. }
  59. }
  60. else
  61. {
  62. bUseMutex = true;
  63. }
  64. */
  65. }
  66. }
  67. else
  68. {
  69. bUseMutex = true;
  70. }
  71. if (bUseMutex)
  72. {
  73. HANDLE hThreadToken = INVALID_HANDLE_VALUE;
  74. // The mutex will need to be opened in the process's context. If two impersonated
  75. // threads need the mutex, we can't have the second one get an access denied when
  76. // opening the mutex.
  77. // If the OpenThreadToken fails, it is most likely due to already having reverted
  78. // to self. If so, no RevertToSelf is necessary.
  79. if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, TRUE, &hThreadToken))
  80. {
  81. LONG lRet = GetLastError(); // Get the value while the gettins good.
  82. LogMessage2(L"Failed to open thread token: (%d)", lRet);
  83. hThreadToken = INVALID_HANDLE_VALUE;
  84. }
  85. else
  86. {
  87. RevertToSelf();
  88. }
  89. m_hMutex = FRCreateMutex(NULL, FALSE, cszMutexName);
  90. LONG lRet = GetLastError(); // Get the value while the gettins good.
  91. LogMessage2(L"Status of mutex creation: (%d)", lRet);
  92. // Back to the original user. Apparently, security is only checked on the open.
  93. if (hThreadToken != INVALID_HANDLE_VALUE)
  94. {
  95. if (!ImpersonateLoggedOnUser(hThreadToken))
  96. {
  97. LogErrorMessage2(L"Failed to return to impersonation (0x%x)", GetLastError());
  98. }
  99. CloseHandle(hThreadToken);
  100. }
  101. if (m_hMutex)
  102. {
  103. WaitForSingleObject(m_hMutex, INFINITE);
  104. }
  105. else
  106. {
  107. LogErrorMessage3(L"Failed to open mutex: %s (%d)", cszMutexName, lRet);
  108. }
  109. }
  110. }
  111. CreateMutexAsProcess::~CreateMutexAsProcess()
  112. {
  113. if (m_hMutex)
  114. {
  115. ReleaseMutex(m_hMutex);
  116. CloseHandle(m_hMutex);
  117. }
  118. }