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

//***************************************************************************
//
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
//
// CreateMutexAsProcess.CPP
//
// Purpose: Create a mutex NOT using impersonation
//
//***************************************************************************
#include "precomp.h"
#include <brodcast.h>
#include <CreateMutexAsProcess.h>
#include "MultiPlat.h"
CreateMutexAsProcess::CreateMutexAsProcess(const WCHAR *cszMutexName)
{
m_hMutex = NULL;
bool bUseMutex = false;
DWORD dwOSMajorVersion;
dwOSMajorVersion = CWbemProviderGlue::GetOSMajorVersion();
// HACK HACK HACK - special case for security mutex.
// TODO: remove special case, make special class, see RAID 38371
if (wcscmp(cszMutexName, SECURITYAPIMUTEXNAME) == 0)
{
//Work out if we need the mutex...
if (CWbemProviderGlue::GetPlatform() == VER_PLATFORM_WIN32_NT)
{
if (dwOSMajorVersion < 5)
//if (dwOSMajorVersion < 4) // see comment below
{
bUseMutex = true;
}
// Code changed from using the mutex if nt4sp4 or earlier, to plain old use it if less
// than nt5 because some security issues have not been fixed in nt4, even up to sp6.
/*
else if (dwOSMajorVersion == 4)
{
LPCWSTR pcwstrCSDVersion = CWbemProviderGlue::GetCSDVersion();
if ((pcwstrCSDVersion == NULL) || (pcwstrCSDVersion == L'\0'))
{
bUseMutex = true;
}
else
{
//Need to determine if we are SP4 or above as there is no need to use the
//mutex if this is the case...
bUseMutex = true;
for (int i = 0; pcwstrCSDVersion[i] != '\0'; i++)
{
if (isdigit(pcwstrCSDVersion[i]))
{
if (_wtoi(&(pcwstrCSDVersion[i])) >= 4)
{
bUseMutex = false;
}
break;
}
}
}
}
else
{
bUseMutex = true;
}
*/
}
}
else
{
bUseMutex = true;
}
if (bUseMutex)
{
HANDLE hThreadToken = INVALID_HANDLE_VALUE;
// The mutex will need to be opened in the process's context. If two impersonated
// threads need the mutex, we can't have the second one get an access denied when
// opening the mutex.
// If the OpenThreadToken fails, it is most likely due to already having reverted
// to self. If so, no RevertToSelf is necessary.
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, TRUE, &hThreadToken))
{
LONG lRet = GetLastError(); // Get the value while the gettins good.
LogMessage2(L"Failed to open thread token: (%d)", lRet);
hThreadToken = INVALID_HANDLE_VALUE;
}
else
{
RevertToSelf();
}
m_hMutex = FRCreateMutex(NULL, FALSE, cszMutexName);
LONG lRet = GetLastError(); // Get the value while the gettins good.
LogMessage2(L"Status of mutex creation: (%d)", lRet);
// Back to the original user. Apparently, security is only checked on the open.
if (hThreadToken != INVALID_HANDLE_VALUE)
{
if (!ImpersonateLoggedOnUser(hThreadToken))
{
LogErrorMessage2(L"Failed to return to impersonation (0x%x)", GetLastError());
}
CloseHandle(hThreadToken);
}
if (m_hMutex)
{
WaitForSingleObject(m_hMutex, INFINITE);
}
else
{
LogErrorMessage3(L"Failed to open mutex: %s (%d)", cszMutexName, lRet);
}
}
}
CreateMutexAsProcess::~CreateMutexAsProcess()
{
if (m_hMutex)
{
ReleaseMutex(m_hMutex);
CloseHandle(m_hMutex);
}
}