362 lines
7.8 KiB
C++
362 lines
7.8 KiB
C++
|
//***************************************************************************
|
||
|
//
|
||
|
// Copyright (c) 1998-1999 Microsoft Corporation
|
||
|
//
|
||
|
// ERROR.CPP
|
||
|
//
|
||
|
// alanbos 28-Jun-98 Created.
|
||
|
//
|
||
|
// Defines the WBEM error cache implementation
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
#define NULLBSTR(x) \
|
||
|
SysFreeString (x);\
|
||
|
x = NULL;
|
||
|
|
||
|
#define FREECOAUTH(x) \
|
||
|
if (x)\
|
||
|
{\
|
||
|
WbemFreeAuthIdentity (x);\
|
||
|
x = NULL;\
|
||
|
}
|
||
|
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CWbemErrorCache::CWbemErrorCache
|
||
|
//
|
||
|
// DESCRIPTION:
|
||
|
//
|
||
|
// Constructor
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
CWbemErrorCache::CWbemErrorCache ()
|
||
|
{
|
||
|
InitializeCriticalSection (&m_cs);
|
||
|
headPtr = NULL;
|
||
|
}
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CWbemErrorCache::~CWbemErrorCache
|
||
|
//
|
||
|
// DESCRIPTION:
|
||
|
//
|
||
|
// Destructor
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
CWbemErrorCache::~CWbemErrorCache ()
|
||
|
{
|
||
|
EnterCriticalSection (&m_cs);
|
||
|
|
||
|
ThreadError *pPtr = headPtr;
|
||
|
|
||
|
while (pPtr)
|
||
|
{
|
||
|
if (pPtr->pErrorObject)
|
||
|
{
|
||
|
pPtr->pErrorObject->Release ();
|
||
|
pPtr->pErrorObject = NULL;
|
||
|
}
|
||
|
|
||
|
if (pPtr->pService)
|
||
|
{
|
||
|
pPtr->pService->Release ();
|
||
|
pPtr->pService = NULL;
|
||
|
}
|
||
|
|
||
|
NULLBSTR (pPtr->strNamespacePath);
|
||
|
NULLBSTR (pPtr->strAuthority);
|
||
|
NULLBSTR (pPtr->strPrincipal);
|
||
|
FREECOAUTH (pPtr->pCoAuthIdentity)
|
||
|
|
||
|
ThreadError *pTmp = pPtr;
|
||
|
pPtr = pPtr->pNext;
|
||
|
delete pTmp;
|
||
|
}
|
||
|
|
||
|
headPtr = NULL;
|
||
|
|
||
|
LeaveCriticalSection (&m_cs);
|
||
|
DeleteCriticalSection (&m_cs);
|
||
|
}
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CWbemErrorCache::GetAndResetCurrentThreadError
|
||
|
//
|
||
|
// DESCRIPTION:
|
||
|
//
|
||
|
// Extract the WBEM error object (if any) from the current thread. This
|
||
|
// is a once-only operation as the entry for that thread is cleared by this
|
||
|
// read.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
CSWbemObject *CWbemErrorCache::GetAndResetCurrentThreadError ()
|
||
|
{
|
||
|
CSWbemObject *pObject = NULL;
|
||
|
DWORD threadId = GetCurrentThreadId ();
|
||
|
|
||
|
EnterCriticalSection (&m_cs);
|
||
|
|
||
|
ThreadError *pPtr = headPtr;
|
||
|
|
||
|
while (pPtr)
|
||
|
{
|
||
|
if (threadId == pPtr->dwThreadId)
|
||
|
{
|
||
|
if (pPtr->pErrorObject)
|
||
|
{
|
||
|
CSWbemServices *pService = NULL;
|
||
|
|
||
|
// Try and create a services object
|
||
|
if (pPtr->pService)
|
||
|
{
|
||
|
pService = new CSWbemServices (pPtr->pService, pPtr->strNamespacePath,
|
||
|
pPtr->pCoAuthIdentity, pPtr->strPrincipal,
|
||
|
pPtr->strAuthority);
|
||
|
|
||
|
if (pService)
|
||
|
pService->AddRef ();
|
||
|
}
|
||
|
|
||
|
if (pPtr->pService)
|
||
|
{
|
||
|
pPtr->pService->Release ();
|
||
|
pPtr->pService = NULL;
|
||
|
}
|
||
|
|
||
|
NULLBSTR (pPtr->strNamespacePath);
|
||
|
NULLBSTR (pPtr->strAuthority);
|
||
|
NULLBSTR (pPtr->strPrincipal);
|
||
|
FREECOAUTH (pPtr->pCoAuthIdentity)
|
||
|
|
||
|
pObject = new CSWbemObject (pService, pPtr->pErrorObject, NULL, true);
|
||
|
pPtr->pErrorObject->Release ();
|
||
|
pPtr->pErrorObject = NULL;
|
||
|
|
||
|
if (pService)
|
||
|
pService->Release ();
|
||
|
|
||
|
// Unhook and delete the ThreadError
|
||
|
|
||
|
if (pPtr == headPtr)
|
||
|
headPtr = pPtr->pNext;
|
||
|
|
||
|
if (pPtr->pNext)
|
||
|
pPtr->pNext->pPrev = pPtr->pPrev;
|
||
|
|
||
|
if (pPtr->pPrev)
|
||
|
pPtr->pPrev->pNext = pPtr->pNext;
|
||
|
|
||
|
delete pPtr;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
pPtr = pPtr->pNext;
|
||
|
}
|
||
|
|
||
|
|
||
|
LeaveCriticalSection (&m_cs);
|
||
|
|
||
|
return pObject;
|
||
|
}
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CWbemErrorCache::SetCurrentThreadError
|
||
|
//
|
||
|
// DESCRIPTION:
|
||
|
//
|
||
|
// Set the WBEM error object (if any) for the current thread.
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
void CWbemErrorCache::SetCurrentThreadError (CSWbemServices *pService)
|
||
|
{
|
||
|
IErrorInfo * pInfo = NULL;
|
||
|
|
||
|
if(SUCCEEDED(GetErrorInfo(0, &pInfo)) && pInfo)
|
||
|
{
|
||
|
// Is this a WBEM Error Object?
|
||
|
IWbemClassObject * pObj = NULL;
|
||
|
|
||
|
if(SUCCEEDED(pInfo->QueryInterface(IID_IWbemClassObject, (void **)&pObj)) && pObj)
|
||
|
{
|
||
|
DWORD threadId = GetCurrentThreadId ();
|
||
|
EnterCriticalSection (&m_cs);
|
||
|
|
||
|
ThreadError *pPtr = headPtr;
|
||
|
|
||
|
// Find the current entry (if any)
|
||
|
|
||
|
while (pPtr)
|
||
|
{
|
||
|
if (threadId == pPtr->dwThreadId)
|
||
|
break;
|
||
|
|
||
|
pPtr = pPtr->pNext;
|
||
|
}
|
||
|
// Have a new error object - chain it into the list
|
||
|
if (!pPtr)
|
||
|
{
|
||
|
// No entry for this thread - create one at the head
|
||
|
ThreadError *pTmp = headPtr;
|
||
|
headPtr = new ThreadError;
|
||
|
|
||
|
if (headPtr)
|
||
|
{
|
||
|
headPtr->pPrev = NULL;
|
||
|
headPtr->pNext = pTmp;
|
||
|
|
||
|
if (pTmp)
|
||
|
pTmp->pPrev = headPtr;
|
||
|
|
||
|
headPtr->dwThreadId = threadId;
|
||
|
headPtr->pErrorObject = pObj;
|
||
|
headPtr->pService = NULL;
|
||
|
headPtr->strAuthority = NULL;
|
||
|
headPtr->strPrincipal = NULL;
|
||
|
headPtr->pCoAuthIdentity = NULL;
|
||
|
headPtr->strNamespacePath = NULL;
|
||
|
|
||
|
if (pService)
|
||
|
{
|
||
|
headPtr->pService = pService->GetIWbemServices ();
|
||
|
CSWbemSecurity *pSecurity = pService->GetSecurityInfo ();
|
||
|
|
||
|
if (pSecurity)
|
||
|
{
|
||
|
headPtr->strAuthority = SysAllocString (pSecurity->GetAuthority ());
|
||
|
headPtr->strPrincipal = SysAllocString (pSecurity->GetPrincipal ());
|
||
|
headPtr->pCoAuthIdentity = pSecurity->GetCoAuthIdentity ();
|
||
|
pSecurity->Release ();
|
||
|
}
|
||
|
|
||
|
headPtr->strNamespacePath = SysAllocString(pService->GetPath ());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// pPtr addresses the current entry for the thread
|
||
|
/***************************************************
|
||
|
* We should not actually do this any more as we
|
||
|
* remove the entry both when it is read and at the
|
||
|
* start of the API call. So at this point there should
|
||
|
* not be any entries left for this thread
|
||
|
****************************************************/
|
||
|
if (pPtr->pErrorObject)
|
||
|
pPtr->pErrorObject->Release ();
|
||
|
|
||
|
pPtr->pErrorObject = pObj;
|
||
|
|
||
|
if (pPtr->pService)
|
||
|
{
|
||
|
pPtr->pService->Release ();
|
||
|
pPtr->pService = NULL;
|
||
|
}
|
||
|
|
||
|
NULLBSTR (pPtr->strNamespacePath);
|
||
|
NULLBSTR (pPtr->strAuthority);
|
||
|
NULLBSTR (pPtr->strPrincipal);
|
||
|
FREECOAUTH (pPtr->pCoAuthIdentity)
|
||
|
|
||
|
if (pService)
|
||
|
{
|
||
|
pPtr->pService = pService->GetIWbemServices ();
|
||
|
|
||
|
CSWbemSecurity *pSecurity = pService->GetSecurityInfo ();
|
||
|
|
||
|
if (pSecurity)
|
||
|
{
|
||
|
pPtr->strAuthority = SysAllocString (pSecurity->GetAuthority ());
|
||
|
pPtr->strPrincipal = SysAllocString (pSecurity->GetPrincipal ());
|
||
|
pPtr->pCoAuthIdentity = pSecurity->GetCoAuthIdentity ();
|
||
|
pSecurity->Release ();
|
||
|
}
|
||
|
|
||
|
pPtr->strNamespacePath = SysAllocString(pService->GetPath ());
|
||
|
}
|
||
|
}
|
||
|
LeaveCriticalSection (&m_cs);
|
||
|
}
|
||
|
|
||
|
pInfo->Release (); // To balance the GetErrorInfo call
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//***************************************************************************
|
||
|
//
|
||
|
// CWbemErrorCache::ResetCurrentThreadError
|
||
|
//
|
||
|
// DESCRIPTION:
|
||
|
//
|
||
|
// If there is an entry for the current thread then remove it
|
||
|
//
|
||
|
//***************************************************************************
|
||
|
|
||
|
void CWbemErrorCache::ResetCurrentThreadError ()
|
||
|
{
|
||
|
DWORD threadId = GetCurrentThreadId ();
|
||
|
EnterCriticalSection (&m_cs);
|
||
|
|
||
|
ThreadError *pPtr = headPtr;
|
||
|
|
||
|
// Find the current entry (if any)
|
||
|
|
||
|
while (pPtr)
|
||
|
{
|
||
|
if (threadId == pPtr->dwThreadId)
|
||
|
break;
|
||
|
|
||
|
pPtr = pPtr->pNext;
|
||
|
}
|
||
|
|
||
|
if (pPtr)
|
||
|
{
|
||
|
// pPtr addresses the current entry for the thread
|
||
|
if (pPtr->pErrorObject)
|
||
|
{
|
||
|
pPtr->pErrorObject->Release ();
|
||
|
pPtr->pErrorObject = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
if (pPtr->pService)
|
||
|
{
|
||
|
pPtr->pService->Release ();
|
||
|
pPtr->pService = NULL;
|
||
|
}
|
||
|
|
||
|
NULLBSTR (pPtr->strNamespacePath);
|
||
|
NULLBSTR (pPtr->strAuthority);
|
||
|
NULLBSTR (pPtr->strPrincipal);
|
||
|
FREECOAUTH (pPtr->pCoAuthIdentity)
|
||
|
|
||
|
// Unhook and delete the ErrorInfo
|
||
|
|
||
|
if (pPtr == headPtr)
|
||
|
headPtr = pPtr->pNext;
|
||
|
|
||
|
if (pPtr->pNext)
|
||
|
pPtr->pNext->pPrev = pPtr->pPrev;
|
||
|
|
||
|
if (pPtr->pPrev)
|
||
|
pPtr->pPrev->pNext = pPtr->pNext;
|
||
|
|
||
|
delete pPtr;
|
||
|
}
|
||
|
|
||
|
|
||
|
LeaveCriticalSection (&m_cs);
|
||
|
}
|