135 lines
4.2 KiB
C++
135 lines
4.2 KiB
C++
//***************************************************************************
|
|
|
|
//
|
|
|
|
// 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);
|
|
}
|
|
}
|