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.
4308 lines
115 KiB
4308 lines
115 KiB
//***************************************************************************
|
|
|
|
//
|
|
|
|
// NTEVTQUERY.CPP
|
|
|
|
//
|
|
|
|
// Module: WBEM NT EVENT PROVIDER
|
|
|
|
//
|
|
|
|
// Purpose: Contains the ExecQuery implementation
|
|
|
|
//
|
|
|
|
// Copyright (c) 1996-2001 Microsoft Corporation, All Rights Reserved
|
|
//
|
|
//***************************************************************************
|
|
|
|
#include "precomp.h"
|
|
#include <wbemtime.h>
|
|
|
|
#define NTEVT_DECPOS 14
|
|
#define NTEVT_SGNPOS 21
|
|
#define NTEVT_DMTFLEN 25
|
|
|
|
wchar_t* CheckForSpecialCharacters(const wchar_t* wstr)
|
|
{
|
|
if (wstr == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
int wstrlen = wcslen(wstr) * 2;
|
|
wchar_t* ret = new wchar_t[wstrlen + 1];
|
|
const wchar_t* tmp = wstr;
|
|
int x = 0;
|
|
|
|
while ((*tmp != L'\0') && (x < wstrlen))
|
|
{
|
|
if (*tmp == L'\\')
|
|
{
|
|
ret[x++] = L'\\';
|
|
}
|
|
|
|
ret[x++] = *tmp;
|
|
tmp++;
|
|
}
|
|
|
|
ret[x] = L'\0';
|
|
return ret;
|
|
}
|
|
|
|
|
|
BOOL GenerateAssocInstance ( WbemProvErrorObject &a_ErrorObject,
|
|
const wchar_t* objPath1,
|
|
const wchar_t* objPath2,
|
|
wchar_t* prop1,
|
|
wchar_t* prop2,
|
|
IWbemClassObject* pClassObject,
|
|
IWbemObjectSink* pNtfcnHandler,
|
|
BOOL *pbIndicated)
|
|
{
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"GenerateAssocInstance\r\n"
|
|
);
|
|
)
|
|
|
|
IWbemClassObject* pInst = NULL;
|
|
HRESULT result = pClassObject->SpawnInstance(0, &pInst);
|
|
BOOL retVal = TRUE;
|
|
|
|
if (pbIndicated)
|
|
{
|
|
*pbIndicated = FALSE;
|
|
}
|
|
|
|
if (FAILED(result))
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to spawn association instance." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"GenerateAssocInstance:Failed to spawn association instance.\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
VARIANT v;
|
|
VariantInit (&v);
|
|
v.vt = VT_BSTR;
|
|
|
|
HRESULT result = WBEM_E_OUT_OF_MEMORY ;
|
|
|
|
v.bstrVal = SysAllocString(objPath1);
|
|
if ( v.bstrVal )
|
|
{
|
|
result = pInst->Put(prop1, 0, &v, 0);
|
|
}
|
|
|
|
VariantClear(&v);
|
|
|
|
if (FAILED(result))
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to set association key property." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"GenerateAssocInstance:Failed to set association key property\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
VariantInit (&v);
|
|
v.vt = VT_BSTR;
|
|
|
|
HRESULT result = WBEM_E_OUT_OF_MEMORY ;
|
|
|
|
v.bstrVal = SysAllocString(objPath2);
|
|
if ( v.bstrVal )
|
|
{
|
|
result = pInst->Put(prop2, 0, &v, 0);
|
|
}
|
|
|
|
VariantClear(&v);
|
|
|
|
if (FAILED(result))
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to set association key property." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"GenerateAssocInstance:Failed to set association key property\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
result = pNtfcnHandler->Indicate ( 1, & pInst );
|
|
|
|
if (FAILED(result))
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to indicate association instance." );
|
|
}
|
|
else
|
|
{
|
|
if (pbIndicated)
|
|
{
|
|
*pbIndicated = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pInst->Release();
|
|
}
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"GenerateAssocInstance:returning %lx\r\n",
|
|
retVal
|
|
);
|
|
)
|
|
return retVal;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL ExecQueryAsyncEventObject :: OptimizeAssocQuery (
|
|
|
|
WbemProvErrorObject &a_ErrorObject,
|
|
BSTR *a_ObjectPath
|
|
)
|
|
{
|
|
*a_ObjectPath = NULL;
|
|
|
|
BOOL t_Status = FALSE;
|
|
|
|
SQL_LEVEL_1_TOKEN *pArrayOfTokens = m_RPNExpression->pArrayOfTokens;
|
|
int nNumTokens = m_RPNExpression->nNumTokens;
|
|
|
|
if ( ! pArrayOfTokens )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if (( nNumTokens != 3 ) && ( nNumTokens != 1 ))
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( pArrayOfTokens [ 0 ].dwPropertyFunction != SQL_LEVEL_1_TOKEN :: IFUNC_NONE )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( pArrayOfTokens [ 0 ].dwConstFunction != SQL_LEVEL_1_TOKEN :: IFUNC_NONE )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( pArrayOfTokens [ 0 ].nTokenType != SQL_LEVEL_1_TOKEN :: OP_EXPRESSION )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( pArrayOfTokens [ 0 ].vConstValue.vt != VT_BSTR )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( pArrayOfTokens [ 0 ].vConstValue.bstrVal == NULL )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( nNumTokens == 3 )
|
|
{
|
|
if ( pArrayOfTokens [ 1 ].dwPropertyFunction != SQL_LEVEL_1_TOKEN :: IFUNC_NONE )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( pArrayOfTokens [ 1 ].dwConstFunction != SQL_LEVEL_1_TOKEN :: IFUNC_NONE )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( pArrayOfTokens [ 1 ].nTokenType != SQL_LEVEL_1_TOKEN :: OP_EXPRESSION )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( pArrayOfTokens [ 1 ].vConstValue.vt != VT_BSTR )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( pArrayOfTokens [ 1 ].vConstValue.bstrVal == NULL )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if ( pArrayOfTokens [ 2 ].nTokenType != SQL_LEVEL_1_TOKEN :: TOKEN_OR )
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
if (_wcsicmp(pArrayOfTokens[0].vConstValue.bstrVal, pArrayOfTokens[1].vConstValue.bstrVal) != 0)
|
|
{
|
|
return t_Status;
|
|
}
|
|
|
|
*a_ObjectPath = SysAllocString ( pArrayOfTokens [ 0 ].vConstValue.bstrVal );
|
|
if ( *a_ObjectPath )
|
|
{
|
|
t_Status = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*a_ObjectPath = SysAllocString ( pArrayOfTokens [ 0 ].vConstValue.bstrVal );
|
|
if ( *a_ObjectPath )
|
|
{
|
|
t_Status = TRUE;
|
|
}
|
|
}
|
|
|
|
return t_Status;
|
|
}
|
|
|
|
wchar_t* ExecQueryAsyncEventObject :: GetClassFromPath(wchar_t* path)
|
|
{
|
|
wchar_t* retVal = NULL;
|
|
CObjectPathParser pathParser;
|
|
ParsedObjectPath *parsedObjectPath = NULL;
|
|
|
|
if (!pathParser.Parse(path, &parsedObjectPath))
|
|
{
|
|
retVal = UnicodeStringDuplicate(parsedObjectPath->m_pClass);
|
|
}
|
|
|
|
delete parsedObjectPath;
|
|
return retVal;
|
|
}
|
|
|
|
BOOL ExecQueryAsyncEventObject :: Query_LogRecord ( WbemProvErrorObject &a_ErrorObject )
|
|
{
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord\r\n"
|
|
);
|
|
)
|
|
|
|
BSTR t_ObjectPath = NULL;
|
|
BOOL retVal = TRUE;
|
|
BOOL bGenAll = FALSE;
|
|
|
|
if (OptimizeAssocQuery (a_ErrorObject, &t_ObjectPath))
|
|
{
|
|
GetObjectAsyncEventObject *t_getObj = new GetObjectAsyncEventObject (
|
|
m_Provider, t_ObjectPath,
|
|
0, m_NotificationHandler, m_Ctx, FALSE);
|
|
|
|
BOOL t_Status = t_getObj->GetObject(t_getObj->m_ErrorObject);
|
|
if (! t_Status )
|
|
{
|
|
bGenAll = TRUE;
|
|
//a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
//a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
//a_ErrorObject.SetMessage ( L"Failed to verify object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord:Failed to verify object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
VARIANT v;
|
|
VariantInit(&v);
|
|
HRESULT result = t_getObj->m_Out->Get(CLASS_PROP, 0, &v, NULL, NULL);
|
|
|
|
if ((FAILED(result)) || (v.vt != VT_BSTR))
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get class name of object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord:Failed to get class name of object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
if (_wcsicmp(v.bstrVal, NTEVTLOG_CLASS) == 0)
|
|
{
|
|
VARIANT vLog;
|
|
VariantInit(&vLog);
|
|
result = t_getObj->m_Out->Get(PROP_LOGNAME, 0, &vLog, NULL, NULL);
|
|
|
|
if ((FAILED(result)) || (vLog.vt != VT_BSTR))
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get log file name of object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord:Failed to get log file name of object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
//get all records for this log
|
|
retVal = GenerateLogAssocs(a_ErrorObject, t_ObjectPath, vLog.bstrVal, TRUE, NULL);
|
|
}
|
|
|
|
VariantClear(&vLog);
|
|
}
|
|
else if (_wcsicmp(v.bstrVal, NTEVT_CLASS) == 0)
|
|
{
|
|
VARIANT vLog;
|
|
VariantInit(&vLog);
|
|
result = t_getObj->m_Out->Get(LOGFILE_PROP, 0, &vLog, NULL, NULL);
|
|
|
|
if ((FAILED(result)) || (vLog.vt != VT_BSTR))
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get log file name of object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord:Failed to get log file name of object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
//get log for this record
|
|
CStringW logNameVal(EVENTLOG_BASE);
|
|
logNameVal += L"\\";
|
|
logNameVal += CStringW(vLog.bstrVal);
|
|
HKEY hkResult;
|
|
LONG res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, logNameVal, 0,
|
|
KEY_READ, &hkResult);
|
|
|
|
if (res != ERROR_SUCCESS)
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((res == ERROR_ACCESS_DENIED) || (res == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed to get log file associated to object given in query");
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord:Failed to get log file associated to object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
CStringW logPath(PROP_START_LOG);
|
|
wchar_t* spchrs = CheckForSpecialCharacters(CEventLogFile::GetFileName(hkResult));
|
|
RegCloseKey(hkResult);
|
|
logPath += CStringW(spchrs);
|
|
delete [] spchrs;
|
|
logPath += PROP_END_QUOTE;
|
|
retVal = GenerateAssocInstance(a_ErrorObject, t_ObjectPath, logPath, REF_REC, REF_LOG,
|
|
m_ClassObject, m_NotificationHandler, NULL);
|
|
}
|
|
}
|
|
|
|
VariantClear(&vLog);
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_PROVIDER_NOT_CAPABLE );
|
|
a_ErrorObject.SetMessage ( L"Class name of object given in query is not a property of Association class" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord:Class name of object given in query is not a property of Association class\r\n"
|
|
);
|
|
)
|
|
}
|
|
}
|
|
|
|
VariantClear(&v);
|
|
}
|
|
|
|
SysFreeString (t_ObjectPath);
|
|
delete t_getObj;
|
|
|
|
if ( FAILED ( WbemCoImpersonateClient() ) )
|
|
{
|
|
m_ErrorObject.SetStatus (WBEM_PROV_E_ACCESS_DENIED);
|
|
m_ErrorObject.SetWbemStatus (WBEM_E_ACCESS_DENIED);
|
|
m_ErrorObject.SetMessage (L"Access denied, impersonation level too low");
|
|
return FALSE ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bGenAll = TRUE;
|
|
}
|
|
|
|
if (bGenAll)
|
|
{
|
|
//get all instances...
|
|
// open registry for log names
|
|
HKEY hkResult;
|
|
LONG status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
EVENTLOG_BASE, 0,
|
|
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
|
|
&hkResult);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
// indicate error
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((status == ERROR_ACCESS_DENIED) || (status == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed to open the Eventlog registry for logfiles." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord:Failed to open the Eventlog registry for logfiles - Returning FALSE.\r\n"
|
|
);
|
|
)
|
|
|
|
retVal = FALSE;
|
|
return retVal;
|
|
}
|
|
|
|
DWORD iValue = 0;
|
|
WCHAR t_logname[MAX_PATH+1];
|
|
DWORD t_lognameSize = MAX_PATH+1;
|
|
BOOL bContinue = TRUE;
|
|
|
|
// read all entries under this key to find all logfiles...
|
|
while (bContinue && ((status = RegEnumKey(hkResult, iValue, t_logname, t_lognameSize)) != ERROR_NO_MORE_ITEMS))
|
|
{
|
|
// if error during read
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
// indicate error
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((status == ERROR_ACCESS_DENIED) || (status == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed while enumerating the Eventlog registry for logfiles." );
|
|
retVal = FALSE;
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord:Failed while enumerating the Eventlog registry for logfiles.\r\n"
|
|
);
|
|
)
|
|
break;
|
|
}
|
|
|
|
//create the associations for this logfile...
|
|
HKEY hkLog;
|
|
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(hkResult, t_logname, 0, KEY_QUERY_VALUE, &hkLog))
|
|
{
|
|
CStringW t_logPath(PROP_START_LOG);
|
|
CStringW t_evtlognamestr = CEventLogFile::GetFileName(hkLog);
|
|
|
|
if (!t_evtlognamestr.IsEmpty())
|
|
{
|
|
wchar_t* spchrs = CheckForSpecialCharacters(t_evtlognamestr);
|
|
t_logPath += CStringW(spchrs);
|
|
delete [] spchrs;
|
|
t_logPath += PROP_END_QUOTE;
|
|
|
|
if (!GenerateLogAssocs(a_ErrorObject, t_logPath, t_logname, FALSE, &bContinue))
|
|
{
|
|
retVal = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord:Failed to get file for the %s logfile.\r\n",
|
|
t_logname
|
|
);
|
|
)
|
|
|
|
}
|
|
|
|
RegCloseKey(hkLog);
|
|
}
|
|
|
|
// read next parameter
|
|
iValue++;
|
|
|
|
} // end while
|
|
|
|
RegCloseKey(hkResult);
|
|
}
|
|
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_LogRecord:returning %lx\r\n",
|
|
retVal
|
|
);
|
|
)
|
|
|
|
return retVal;
|
|
}
|
|
|
|
BOOL ExecQueryAsyncEventObject :: GenerateLogAssocs( WbemProvErrorObject &a_ErrorObject,
|
|
const wchar_t* logPath,
|
|
const wchar_t* logName,
|
|
BOOL bVerifyLogname,
|
|
BOOL *pbContinue)
|
|
{
|
|
BOOL retVal = TRUE;
|
|
|
|
if (pbContinue)
|
|
{
|
|
*pbContinue = TRUE;
|
|
}
|
|
|
|
CEventLogFile evtLog(logName, bVerifyLogname);
|
|
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: GenerateLogAssocs\r\n"
|
|
);
|
|
)
|
|
|
|
if (!evtLog.IsValid())
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((evtLog.GetReason() == ERROR_ACCESS_DENIED) || (evtLog.GetReason() == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed to open eventlog to enumerate records for Log Association." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: GenerateLogAssocs:Failed to open eventlog to enumerate records for Log Association\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
DWORD recId;
|
|
DWORD numRecs;
|
|
|
|
if (evtLog.GetLastRecordID(recId, numRecs))
|
|
{
|
|
for (DWORD x = recId; (x > (recId - numRecs)); x--)
|
|
{
|
|
CStringW recPath(PROP_START_REC);
|
|
recPath += CStringW(logName);
|
|
recPath += PROP_MID_REC;
|
|
wchar_t buff[40];
|
|
recPath += CStringW(_ultow((ULONG)x, buff, 10));
|
|
|
|
if (!GenerateAssocInstance(a_ErrorObject, recPath,
|
|
logPath, REF_REC, REF_LOG,
|
|
m_ClassObject, m_NotificationHandler, pbContinue))
|
|
{
|
|
retVal = FALSE;
|
|
}
|
|
|
|
if (pbContinue && !(*pbContinue))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to determine number of records in eventlog for log associations" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: GenerateLogAssocs:Failed to determine number of records in eventlog for log associations\r\n"
|
|
);
|
|
)
|
|
}
|
|
}
|
|
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: GenerateLogAssocs:Returning %lx\r\n",
|
|
retVal
|
|
);
|
|
)
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
BOOL ExecQueryAsyncEventObject :: Query_UserRecord ( WbemProvErrorObject &a_ErrorObject )
|
|
{
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_UserRecord\r\n"
|
|
);
|
|
)
|
|
|
|
BSTR t_ObjectPath = NULL;
|
|
BOOL retVal = TRUE;
|
|
BOOL bGenAll = FALSE;
|
|
|
|
if (OptimizeAssocQuery (a_ErrorObject, &t_ObjectPath))
|
|
{
|
|
wchar_t* str_classname = GetClassFromPath(t_ObjectPath);
|
|
|
|
if (str_classname == NULL)
|
|
{
|
|
bGenAll = TRUE;
|
|
//a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
//a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
//a_ErrorObject.SetMessage ( L"Failed to verify object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_UserRecord:Failed to verify object given in query\r\n"
|
|
);
|
|
)
|
|
|
|
}
|
|
else if (_wcsicmp(str_classname, USER_CLASS) == 0)
|
|
{
|
|
IWbemClassObject* pObj = NULL;
|
|
IWbemServices *t_Server = m_Provider->GetServer();
|
|
HRESULT result = t_Server->GetObject(t_ObjectPath, 0, m_Ctx, &pObj, NULL);
|
|
|
|
t_Server->Release();
|
|
|
|
if (FAILED(result))
|
|
{
|
|
retVal = FALSE;
|
|
//a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
//a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
//a_ErrorObject.SetMessage ( L"Failed to verify object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_UserRecord:Failed to verify object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
pObj->Release ();
|
|
|
|
//get all records...
|
|
retVal = GenerateCompUserAssocs(a_ErrorObject, FALSE);
|
|
}
|
|
|
|
delete [] str_classname;
|
|
}
|
|
else if (_wcsicmp(str_classname, NTEVT_CLASS) == 0)
|
|
{
|
|
GetObjectAsyncEventObject *t_getRec = new GetObjectAsyncEventObject (
|
|
m_Provider, t_ObjectPath,
|
|
0, m_NotificationHandler,
|
|
m_Ctx, FALSE );
|
|
|
|
if (t_getRec->GetObject(t_getRec->m_ErrorObject))
|
|
{
|
|
VARIANT vUser;
|
|
CIMTYPE cT;
|
|
VariantInit(&vUser);
|
|
HRESULT result = t_getRec->m_Out->Get(USER_PROP, 0, &vUser, &cT, NULL);
|
|
|
|
if ((FAILED(result)) || (cT != CIM_STRING))
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_UserRecord:Failed to get user name of object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
if ((vUser.vt == VT_BSTR) && (vUser.bstrVal != NULL))
|
|
{
|
|
//get user for this record
|
|
CStringW userVal(vUser.bstrVal);
|
|
int pos = userVal.Find(L'\\');
|
|
|
|
if (pos != -1)
|
|
{
|
|
CStringW dom = userVal.Left(pos);
|
|
CStringW nm = userVal.Right(userVal.GetLength() - 1 - pos);
|
|
|
|
if (!nm.IsEmpty() && !dom.IsEmpty())
|
|
{
|
|
wchar_t userPath[1024];
|
|
if ( SUCCEEDED ( StringCchCopyW ( userPath, 1024, PROP_START_USER ) ) )
|
|
{
|
|
if ( SUCCEEDED ( StringCchCatW ( userPath, 1024, dom ) ) )
|
|
{
|
|
if ( SUCCEEDED ( StringCchCatW ( userPath, 1024, PROP_MID_USER ) ) )
|
|
{
|
|
if ( SUCCEEDED ( StringCchCatW ( userPath, 1024, nm ) ) )
|
|
{
|
|
if ( SUCCEEDED ( StringCchCatW ( userPath, 1024, PROP_END_QUOTE ) ) )
|
|
{
|
|
IWbemClassObject* pUObj = NULL;
|
|
IWbemServices *t_Server = m_Provider->GetServer();
|
|
HRESULT result = WBEM_E_OUT_OF_MEMORY ;
|
|
BSTR userStr = SysAllocString(userPath);
|
|
if ( userStr )
|
|
{
|
|
result = t_Server->GetObject(userStr, 0, m_Ctx, &pUObj, NULL);
|
|
SysFreeString(userStr);
|
|
}
|
|
|
|
t_Server->Release();
|
|
|
|
if (SUCCEEDED(result))
|
|
{
|
|
retVal = GenerateAssocInstance(a_ErrorObject, t_ObjectPath,
|
|
userPath, REF_REC, REF_USER,
|
|
m_ClassObject, m_NotificationHandler, NULL);
|
|
pUObj->Release();
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
VariantClear(&vUser);
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
//a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
//a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
//a_ErrorObject.SetMessage ( L"Failed to verify object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_UserRecord:Failed to verify object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
|
|
delete t_getRec;
|
|
delete [] str_classname;
|
|
|
|
if ( FAILED ( WbemCoImpersonateClient() ) )
|
|
{
|
|
m_ErrorObject.SetStatus (WBEM_PROV_E_ACCESS_DENIED);
|
|
m_ErrorObject.SetWbemStatus (WBEM_E_ACCESS_DENIED);
|
|
m_ErrorObject.SetMessage (L"Access denied, impersonation level too low");
|
|
|
|
SysFreeString (t_ObjectPath);
|
|
|
|
return FALSE ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bGenAll = TRUE;
|
|
delete [] str_classname;
|
|
}
|
|
|
|
SysFreeString (t_ObjectPath);
|
|
}
|
|
else
|
|
{
|
|
bGenAll = TRUE;
|
|
}
|
|
|
|
if (bGenAll)
|
|
{
|
|
//get all instances...
|
|
retVal = GenerateCompUserAssocs(a_ErrorObject, FALSE);
|
|
}
|
|
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_UserRecord:Returning %lx\r\n",
|
|
retVal
|
|
);
|
|
)
|
|
|
|
return retVal;
|
|
}
|
|
|
|
BOOL ExecQueryAsyncEventObject :: Query_ComputerRecord ( WbemProvErrorObject &a_ErrorObject )
|
|
{
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_ComputerRecord\r\n"
|
|
);
|
|
)
|
|
|
|
BSTR t_ObjectPath = NULL;
|
|
BOOL retVal = TRUE;
|
|
BOOL bGenAll = FALSE;
|
|
|
|
if (OptimizeAssocQuery (a_ErrorObject, &t_ObjectPath))
|
|
{
|
|
wchar_t* str_classname = GetClassFromPath(t_ObjectPath);
|
|
|
|
if (str_classname == NULL)
|
|
{
|
|
bGenAll = TRUE;
|
|
//a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
//a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
//a_ErrorObject.SetMessage ( L"Failed to verify object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_ComputerRecord:Failed to verify object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
else if (_wcsicmp(str_classname, COMP_CLASS) == 0)
|
|
{
|
|
IWbemClassObject* pObj = NULL;
|
|
IWbemServices *t_Server = m_Provider->GetServer();
|
|
HRESULT result = t_Server->GetObject(t_ObjectPath, 0, m_Ctx, &pObj, NULL);
|
|
t_Server->Release();
|
|
|
|
if (FAILED(result))
|
|
{
|
|
retVal = FALSE;
|
|
//a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
//a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
//a_ErrorObject.SetMessage ( L"Failed to verify object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_ComputerRecord:Failed to verify object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
pObj->Release ();
|
|
|
|
//get all records...
|
|
retVal = GenerateCompUserAssocs(a_ErrorObject, TRUE);
|
|
}
|
|
|
|
delete [] str_classname;
|
|
}
|
|
else if (_wcsicmp(str_classname, NTEVT_CLASS) == 0)
|
|
{
|
|
GetObjectAsyncEventObject *t_getRec = new GetObjectAsyncEventObject (
|
|
m_Provider, t_ObjectPath,
|
|
0, m_NotificationHandler,
|
|
m_Ctx, FALSE);
|
|
|
|
if (t_getRec->GetObject(t_getRec->m_ErrorObject))
|
|
{
|
|
VARIANT vComp;
|
|
CIMTYPE cT;
|
|
VariantInit(&vComp);
|
|
HRESULT result = t_getRec->m_Out->Get(COMPUTER_PROP, 0, &vComp, &cT, NULL);
|
|
|
|
if ((FAILED(result)) || (cT != CIM_STRING))
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get computer name of object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_ComputerRecord:Failed to get computer name of object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
else
|
|
{
|
|
if ((vComp.vt == VT_BSTR) && (vComp.bstrVal != NULL))
|
|
{
|
|
//get computer for this record
|
|
wchar_t compPath[1024];
|
|
if ( SUCCEEDED ( StringCchCopyW ( compPath, 1024, PROP_START_COMP ) ) )
|
|
{
|
|
if ( SUCCEEDED ( StringCchCatW ( compPath, 1024, vComp.bstrVal ) ) )
|
|
{
|
|
if ( SUCCEEDED ( StringCchCatW ( compPath, 1024, PROP_END_QUOTE ) ) )
|
|
{
|
|
IWbemClassObject* pCObj = NULL;
|
|
IWbemServices *t_Server = m_Provider->GetServer();
|
|
|
|
HRESULT result = WBEM_E_OUT_OF_MEMORY ;
|
|
BSTR compStr = SysAllocString(compPath);
|
|
if ( compStr )
|
|
{
|
|
result = t_Server->GetObject(compStr, 0, m_Ctx, &pCObj, NULL);
|
|
SysFreeString(compStr);
|
|
}
|
|
|
|
t_Server->Release();
|
|
|
|
if (SUCCEEDED(result))
|
|
{
|
|
retVal = GenerateAssocInstance(a_ErrorObject, t_ObjectPath,
|
|
compPath, REF_REC, REF_COMP,
|
|
m_ClassObject, m_NotificationHandler, NULL);
|
|
pCObj->Release();
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed to get user name of object given in query" );
|
|
}
|
|
}
|
|
}
|
|
|
|
VariantClear(&vComp);
|
|
}
|
|
else
|
|
{
|
|
retVal = FALSE;
|
|
//a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
//a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
//a_ErrorObject.SetMessage ( L"Failed to verify object given in query" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_ComputerRecord:Failed to verify object given in query\r\n"
|
|
);
|
|
)
|
|
}
|
|
|
|
delete t_getRec;
|
|
delete [] str_classname;
|
|
|
|
if ( FAILED ( WbemCoImpersonateClient() ) )
|
|
{
|
|
m_ErrorObject.SetStatus (WBEM_PROV_E_ACCESS_DENIED);
|
|
m_ErrorObject.SetWbemStatus (WBEM_E_ACCESS_DENIED);
|
|
m_ErrorObject.SetMessage (L"Access denied, impersonation level too low");
|
|
|
|
SysFreeString (t_ObjectPath);
|
|
|
|
return FALSE ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bGenAll = TRUE;
|
|
delete [] str_classname;
|
|
}
|
|
|
|
SysFreeString (t_ObjectPath);
|
|
}
|
|
else
|
|
{
|
|
bGenAll = TRUE;
|
|
}
|
|
|
|
if (bGenAll)
|
|
{
|
|
//get all instances...
|
|
retVal = GenerateCompUserAssocs(a_ErrorObject, TRUE);
|
|
}
|
|
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_ComputerRecord:Returning %lx\r\n",
|
|
retVal
|
|
);
|
|
)
|
|
|
|
return retVal;
|
|
}
|
|
|
|
|
|
BOOL ExecQueryAsyncEventObject :: GenerateCompUserAssocs ( WbemProvErrorObject &a_ErrorObject, BOOL bComp )
|
|
{
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: GenerateCompUserAssocs\r\n"
|
|
);
|
|
)
|
|
|
|
BOOL retVal = TRUE;
|
|
//just enumerate all logs and let cimom post filter...
|
|
// open registry for log names
|
|
HKEY hkResult;
|
|
LONG status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
EVENTLOG_BASE, 0,
|
|
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
|
|
&hkResult);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
// indicate error
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((status == ERROR_ACCESS_DENIED) || (status == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed to enumerate the Eventlog registry for logfiles." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: GenerateCompUserAssocs:Failed to enumerate the Eventlog registry for logfiles- Returning FALSE\r\n"
|
|
);
|
|
)
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
DWORD iValue = 0;
|
|
WCHAR logname[MAX_PATH+1];
|
|
DWORD lognameSize = MAX_PATH+1;
|
|
CMap<CStringW, LPCWSTR, HRESULT, HRESULT> pathMap;
|
|
BOOL bContinue = TRUE;
|
|
|
|
// read all entries under this key to find all logfiles...
|
|
while (bContinue && ((status = RegEnumKey(hkResult, iValue, logname, lognameSize)) != ERROR_NO_MORE_ITEMS))
|
|
{
|
|
// if error during read
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
RegCloseKey(hkResult);
|
|
|
|
// indicate error
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((status == ERROR_ACCESS_DENIED) || (status == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed while enumerating the Eventlog registry for logfiles." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: GenerateCompUserAssocs:Failed while enumerating the Eventlog registry for logfiles - Returning FALSE\r\n"
|
|
);
|
|
)
|
|
return FALSE;
|
|
}
|
|
|
|
//process this logfile
|
|
CEventLogFile evtLog(logname, FALSE);
|
|
|
|
if (evtLog.IsValid())
|
|
{
|
|
evtLog.ReadLastRecord();
|
|
}
|
|
|
|
while (bContinue && evtLog.IsValid())
|
|
{
|
|
DWORD dwEventSize = 0;
|
|
DWORD err = evtLog.ReadRecord(0, &dwEventSize, TRUE);
|
|
|
|
if (0 != err)
|
|
{
|
|
if (retVal && (err != ERROR_HANDLE_EOF))
|
|
{
|
|
retVal = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((err == ERROR_ACCESS_DENIED) || (err == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed while enumerating one of the logfiles." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: GenerateCompUserAssocs:Failed while enumerating one of the logfiles.\r\n"
|
|
);
|
|
)
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
PEVENTLOGRECORD EventBuffer = (PEVENTLOGRECORD)evtLog.GetBuffer();
|
|
|
|
while (bContinue && (dwEventSize != 0))
|
|
{
|
|
CStringW compPath;
|
|
BOOL bGenAssoc = FALSE;
|
|
|
|
if (bComp)
|
|
{
|
|
const wchar_t* src = (const wchar_t*)((UCHAR*)EventBuffer + sizeof(EVENTLOGRECORD));
|
|
const wchar_t* compName = (const wchar_t*)((UCHAR*)EventBuffer + sizeof(EVENTLOGRECORD))
|
|
+ wcslen(src) + 1;
|
|
|
|
if (compName != NULL)
|
|
{
|
|
//get computer for this record
|
|
compPath = PROP_START_COMP;
|
|
compPath += compName;
|
|
compPath += PROP_END_QUOTE;
|
|
bGenAssoc = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (EventBuffer->UserSidLength > 0)
|
|
{
|
|
PSID t_Sid = (PSID)((UCHAR*)EventBuffer + EventBuffer->UserSidOffset) ;
|
|
if ( IsValidSid ( t_Sid ) )
|
|
{
|
|
CStringW user = CEventlogRecord::GetUser(
|
|
(PSID)((UCHAR*)EventBuffer + EventBuffer->UserSidOffset));
|
|
|
|
if (!user.IsEmpty())
|
|
{
|
|
int index = user.Find(L'\\');
|
|
|
|
if (index > 0)
|
|
{
|
|
compPath = PROP_START_USER;
|
|
compPath += user.Left(index++);
|
|
compPath += PROP_MID_USER;
|
|
compPath += user.Right(user.GetLength() - index);
|
|
compPath += PROP_END_QUOTE;
|
|
bGenAssoc = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: GenerateCompUserAssocs:Invalid Sid.\r\n"
|
|
);
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bGenAssoc)
|
|
{
|
|
HRESULT result;
|
|
|
|
if (pathMap.IsEmpty() || !pathMap.Lookup(compPath, result))
|
|
{
|
|
IWbemClassObject* pCObj = NULL;
|
|
IWbemServices *t_Server = m_Provider->GetServer();
|
|
BSTR compPathStr = compPath.AllocSysString();
|
|
result = t_Server->GetObject(compPathStr, 0, m_Ctx, &pCObj, NULL);
|
|
SysFreeString(compPathStr);
|
|
t_Server->Release();
|
|
pathMap[compPath] = result;
|
|
|
|
if (SUCCEEDED(result))
|
|
{
|
|
pCObj->Release();
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(result))
|
|
{
|
|
CStringW recPath(PROP_START_REC);
|
|
recPath += CStringW(logname);
|
|
recPath += PROP_MID_REC;
|
|
wchar_t buff[40];
|
|
recPath += CStringW(_ultow((ULONG)EventBuffer->RecordNumber, buff, 10));
|
|
|
|
if (!GenerateAssocInstance(a_ErrorObject, recPath, compPath, REF_REC,
|
|
bComp ? REF_COMP : REF_USER,
|
|
m_ClassObject, m_NotificationHandler, &bContinue))
|
|
{
|
|
retVal = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// drop by length of this record and point to next record
|
|
dwEventSize -= EventBuffer->Length;
|
|
EventBuffer = (PEVENTLOGRECORD) ((UCHAR*) EventBuffer + EventBuffer->Length);
|
|
}
|
|
}
|
|
|
|
// read next parameter
|
|
iValue++;
|
|
|
|
} // end while
|
|
|
|
pathMap.RemoveAll();
|
|
RegCloseKey(hkResult);
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: GenerateCompUserAssocs:Returning %lx\r\n",
|
|
retVal
|
|
);
|
|
)
|
|
|
|
return retVal;
|
|
}
|
|
|
|
BOOL ExecQueryAsyncEventObject :: ExecQuery ( WbemProvErrorObject &a_ErrorObject )
|
|
{
|
|
BOOL t_Status;
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: ExecQuery\r\n"
|
|
);
|
|
)
|
|
if (FAILED(m_ErrorObject.GetWbemStatus()))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ( _wcsicmp ( m_QueryFormat, WBEM_QUERY_LANGUAGE_SQL1 ) == 0 )
|
|
{
|
|
CTextLexSource querySource ( m_Query );
|
|
SQL1_Parser sqlParser ( &querySource );
|
|
|
|
t_Status = ! sqlParser.Parse ( & m_RPNExpression );
|
|
|
|
if ( t_Status )
|
|
{
|
|
t_Status = GetClassObject ( m_RPNExpression->bsClassName );
|
|
|
|
if ( t_Status )
|
|
{
|
|
t_Status = DispatchQuery ( a_ErrorObject );
|
|
}
|
|
else
|
|
{
|
|
t_Status = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_CLASS );
|
|
a_ErrorObject.SetMessage ( L"Unknown Class" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: ExecQuery:Unknown Class\r\n"
|
|
);
|
|
)
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_QUERY );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_PROVIDER_NOT_CAPABLE );
|
|
a_ErrorObject.SetMessage ( L"WQL query was invalid for this provider" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: ExecQuery:WQL query was invalid for this provider\r\n"
|
|
);
|
|
)
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_QUERY_TYPE );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_QUERY_TYPE );
|
|
a_ErrorObject.SetMessage ( L"Query Language not supported" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: ExecQuery:Query Language not supported\r\n"
|
|
);
|
|
)
|
|
}
|
|
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: ExecQuery:Returning %lx\r\n",
|
|
t_Status
|
|
);
|
|
)
|
|
|
|
return t_Status;
|
|
}
|
|
|
|
ExecQueryAsyncEventObject :: ExecQueryAsyncEventObject (
|
|
|
|
CImpNTEvtProv *a_Provider,
|
|
BSTR a_QueryFormat,
|
|
BSTR a_Query,
|
|
ULONG a_OperationFlag,
|
|
IWbemObjectSink *a_NotificationHandler,
|
|
IWbemContext *a_Ctx
|
|
|
|
) : WbemTaskObject ( a_Provider, a_NotificationHandler, a_OperationFlag, a_Ctx ),
|
|
m_Query ( NULL ),
|
|
m_QueryFormat ( NULL ),
|
|
m_RPNExpression ( NULL )
|
|
{
|
|
m_Query = UnicodeStringDuplicate ( a_Query );
|
|
m_QueryFormat = UnicodeStringDuplicate ( a_QueryFormat );
|
|
}
|
|
|
|
ExecQueryAsyncEventObject :: ~ExecQueryAsyncEventObject ()
|
|
{
|
|
// Get Status object
|
|
|
|
delete [] m_Query;
|
|
delete [] m_QueryFormat;
|
|
delete m_RPNExpression;
|
|
|
|
IWbemClassObject *t_NotifyStatus = NULL;
|
|
BOOL t_Status = TRUE;
|
|
|
|
if (WBEM_NO_ERROR != m_ErrorObject.GetWbemStatus ())
|
|
{
|
|
t_Status = GetExtendedNotifyStatusObject ( &t_NotifyStatus );
|
|
}
|
|
|
|
if ( t_Status )
|
|
{
|
|
HRESULT t_Result = m_NotificationHandler->SetStatus ( 0, m_ErrorObject.GetWbemStatus (), 0, t_NotifyStatus );
|
|
|
|
if (t_NotifyStatus)
|
|
{
|
|
t_NotifyStatus->Release ();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HRESULT t_Result = m_NotificationHandler->SetStatus ( 0, m_ErrorObject.GetWbemStatus (), 0, NULL );
|
|
}
|
|
}
|
|
|
|
|
|
void ExecQueryAsyncEventObject :: Process ()
|
|
{
|
|
ExecQuery ( m_ErrorObject );
|
|
}
|
|
|
|
BOOL ExecQueryAsyncEventObject :: DispatchQuery ( WbemProvErrorObject &a_ErrorObject )
|
|
{
|
|
BOOL t_Status;
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: DispatchQuery\r\n"
|
|
);
|
|
)
|
|
|
|
if ( _wcsicmp ( m_RPNExpression->bsClassName, NTEVT_CLASS ) == 0 )
|
|
{
|
|
t_Status = Query_Record ( a_ErrorObject );
|
|
|
|
if ( t_Status )
|
|
{
|
|
m_State = WBEM_TASKSTATE_ASYNCHRONOUSCOMPLETE;
|
|
}
|
|
}
|
|
else if ( _wcsicmp ( m_RPNExpression->bsClassName, NTEVTLOG_CLASS ) == 0 )
|
|
{
|
|
t_Status = Query_EventLog ( a_ErrorObject );
|
|
|
|
if ( t_Status )
|
|
{
|
|
m_State = WBEM_TASKSTATE_ASYNCHRONOUSCOMPLETE;
|
|
}
|
|
}
|
|
else if ( _wcsicmp ( m_RPNExpression->bsClassName, ASSOC_LOGRECORD) == 0 )
|
|
{
|
|
t_Status = Query_LogRecord ( a_ErrorObject );
|
|
|
|
if ( t_Status )
|
|
{
|
|
m_State = WBEM_TASKSTATE_ASYNCHRONOUSCOMPLETE;
|
|
}
|
|
}
|
|
else if ( _wcsicmp ( m_RPNExpression->bsClassName, ASSOC_USERRECORD) == 0 )
|
|
{
|
|
t_Status = Query_UserRecord ( a_ErrorObject );
|
|
|
|
if ( t_Status )
|
|
{
|
|
m_State = WBEM_TASKSTATE_ASYNCHRONOUSCOMPLETE;
|
|
}
|
|
}
|
|
else if ( _wcsicmp ( m_RPNExpression->bsClassName, ASSOC_COMPRECORD) == 0 )
|
|
{
|
|
t_Status = Query_ComputerRecord ( a_ErrorObject );
|
|
|
|
if ( t_Status )
|
|
{
|
|
m_State = WBEM_TASKSTATE_ASYNCHRONOUSCOMPLETE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//just complete!
|
|
t_Status = FALSE;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS );
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_CLASS );
|
|
a_ErrorObject.SetMessage ( L"Dynamic NT Eventlog Provider does not support this class" );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: DispatchQuery:Dynamic NT Eventlog Provider does not support this class:%s\r\n",
|
|
m_RPNExpression->bsClassName
|
|
);
|
|
)
|
|
}
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: DispatchQuery:Returning %lx\r\n",
|
|
t_Status
|
|
);
|
|
)
|
|
|
|
return t_Status;
|
|
}
|
|
|
|
BOOL ExecQueryAsyncEventObject :: Query_EventLog ( WbemProvErrorObject &a_ErrorObject )
|
|
{
|
|
// open registry for log names
|
|
HKEY hkResult;
|
|
LONG status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
EVENTLOG_BASE, 0,
|
|
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
|
|
&hkResult);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
// indicate error
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((status == ERROR_ACCESS_DENIED) || (status == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed to open the Eventlog registry for logfiles." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_EventLog:Failed to open the Eventlog registry for logfiles - Returning FALSE.\r\n"
|
|
);
|
|
)
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL retVal = TRUE;
|
|
DWORD iValue = 0;
|
|
WCHAR logname[MAX_PATH+1];
|
|
DWORD lognameSize = MAX_PATH+1;
|
|
|
|
// read all entries under this key to find all logfiles...
|
|
while ((status = RegEnumKey(hkResult, iValue, logname, lognameSize)) != ERROR_NO_MORE_ITEMS)
|
|
{
|
|
// if error during read
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
// indicate error
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((status == ERROR_ACCESS_DENIED) || (status == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed while enumerating the Eventlog registry for logfiles." );
|
|
retVal = FALSE;
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_EventLog:Failed while enumerating the Eventlog registry for logfiles.\r\n"
|
|
);
|
|
)
|
|
break;
|
|
}
|
|
|
|
//create the instance logfilename
|
|
CEventlogFileAttributes evtlog(logname);
|
|
IWbemClassObject* pInst = NULL;
|
|
|
|
if (evtlog.GenerateInstance(m_ClassObject, m_AClassObject, &pInst))
|
|
{
|
|
HRESULT t_hr = m_NotificationHandler->Indicate ( 1, & pInst );
|
|
pInst->Release();
|
|
|
|
if (FAILED(t_hr))
|
|
{
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_EventLog:Failed while indicating instance(s) of %s Eventlog file\r\n",
|
|
logname
|
|
);
|
|
)
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed while indicating instance of logfile." );
|
|
retVal = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
else if (retVal) //only do this once!
|
|
{
|
|
//an error, just log an error, don't report it via the interface
|
|
//it is a bad registry entry which the eventlog service allows
|
|
//so we should let it pass...
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_EventLog:Failed to create instance(s) of %s Eventlog file\r\n",
|
|
logname
|
|
);
|
|
)
|
|
|
|
}
|
|
|
|
// read next parameter
|
|
iValue++;
|
|
|
|
} // end while
|
|
|
|
RegCloseKey(hkResult);
|
|
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_EventLog:Returning %lx\r\n",
|
|
retVal
|
|
);
|
|
)
|
|
|
|
return retVal;
|
|
}
|
|
|
|
BOOL ExecQueryAsyncEventObject :: Query_Record ( WbemProvErrorObject &a_ErrorObject )
|
|
{
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_Record\r\n"
|
|
);
|
|
)
|
|
|
|
BOOL retVal = TRUE;
|
|
//just enumerate all logs and let cimom post filter...
|
|
// open registry for log names
|
|
HKEY hkResult = NULL;
|
|
LONG status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
EVENTLOG_BASE, 0,
|
|
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
|
|
&hkResult);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
// indicate error
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((status == ERROR_ACCESS_DENIED) || (status == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed to enumerate the Eventlog registry for logfiles." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_Record:Failed to enumerate the Eventlog registry for logfiles - Return FALSE\r\n"
|
|
);
|
|
)
|
|
retVal = FALSE;
|
|
}
|
|
|
|
if (retVal)
|
|
{
|
|
//Analyze the query...
|
|
SQL_LEVEL_1_RPN_EXPRESSION *t_RpnExpression = NULL;
|
|
PartitionSet *t_PartitionSet = NULL;
|
|
QueryPreprocessor :: QuadState t_State = Query (m_Query, t_RpnExpression);
|
|
|
|
if ( t_State == QueryPreprocessor :: QuadState :: State_True )
|
|
{
|
|
WmiTreeNode *t_Root = NULL;
|
|
|
|
t_State = PreProcess (NULL, t_RpnExpression, t_Root);
|
|
|
|
try
|
|
{
|
|
switch ( t_State )
|
|
{
|
|
case QueryPreprocessor :: QuadState :: State_True:
|
|
{
|
|
|
|
BSTR t_PropertyContainer [ 4 ];
|
|
memset ( t_PropertyContainer, 0, sizeof ( BSTR ) * 4 );
|
|
|
|
try
|
|
{
|
|
t_PropertyContainer [ 0 ] = SysAllocString ( LOGFILE_PROP );
|
|
t_PropertyContainer [ 1 ] = SysAllocString ( RECORD_PROP );
|
|
t_PropertyContainer [ 2 ] = SysAllocString ( GENERATED_PROP );
|
|
t_PropertyContainer [ 3 ] = SysAllocString ( WRITTEN_PROP );
|
|
|
|
|
|
if ((t_PropertyContainer [ 0 ] == NULL) ||
|
|
(t_PropertyContainer [ 1 ] == NULL) ||
|
|
(t_PropertyContainer [ 2 ] == NULL) ||
|
|
(t_PropertyContainer [ 3 ] == NULL) )
|
|
{
|
|
throw CHeap_Exception ( CHeap_Exception :: E_ALLOCATION_ERROR );
|
|
}
|
|
|
|
t_State = PreProcess (
|
|
|
|
NULL,
|
|
t_RpnExpression,
|
|
t_Root,
|
|
4,
|
|
t_PropertyContainer,
|
|
t_PartitionSet
|
|
);
|
|
}
|
|
catch ( ... )
|
|
{
|
|
for (DWORD x = 0; x < 4; x++)
|
|
{
|
|
if ( t_PropertyContainer [ x ] )
|
|
{
|
|
SysFreeString ( t_PropertyContainer [ x ] );
|
|
t_PropertyContainer [ x ] = NULL;
|
|
}
|
|
}
|
|
|
|
throw;
|
|
}
|
|
|
|
for (DWORD x = 0; x < 4; x++)
|
|
{
|
|
if ( t_PropertyContainer [ x ] )
|
|
{
|
|
SysFreeString ( t_PropertyContainer [ x ] );
|
|
t_PropertyContainer [ x ] = NULL;
|
|
}
|
|
}
|
|
|
|
switch ( t_State )
|
|
{
|
|
case QueryPreprocessor :: QuadState :: State_True :
|
|
{
|
|
/*
|
|
* Full set, enumerate
|
|
*/
|
|
t_PartitionSet = NULL;
|
|
}
|
|
break;
|
|
|
|
case QueryPreprocessor :: QuadState :: State_False :
|
|
{
|
|
/*
|
|
* Empty set, no work to do
|
|
*/
|
|
RegCloseKey(hkResult);
|
|
hkResult = NULL;
|
|
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
case QueryPreprocessor :: QuadState :: State_Undefined :
|
|
{
|
|
//we have should now have a non-null partition set
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
/*
|
|
* Didn't understand the query send back everything
|
|
*/
|
|
t_PartitionSet = NULL;
|
|
}
|
|
break;
|
|
}
|
|
|
|
delete t_Root;
|
|
t_Root = NULL;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
/*
|
|
* Didn't understand the query send back everything
|
|
*/
|
|
t_PartitionSet = NULL;
|
|
}
|
|
break;
|
|
}
|
|
|
|
delete t_RpnExpression;
|
|
t_RpnExpression = NULL;
|
|
}
|
|
catch (...)
|
|
{
|
|
if (t_PartitionSet)
|
|
{
|
|
delete t_PartitionSet;
|
|
t_PartitionSet = NULL;
|
|
}
|
|
|
|
if ( t_Root )
|
|
{
|
|
delete t_Root;
|
|
t_Root = NULL;
|
|
}
|
|
|
|
if ( t_RpnExpression )
|
|
{
|
|
delete t_RpnExpression;
|
|
t_RpnExpression = NULL;
|
|
}
|
|
|
|
if ( hkResult )
|
|
{
|
|
RegCloseKey(hkResult);
|
|
hkResult = NULL;
|
|
}
|
|
|
|
throw;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* Didn't understand the query send back everything
|
|
*/
|
|
t_PartitionSet = NULL;
|
|
}
|
|
|
|
DWORD iValue = 0;
|
|
WCHAR logname[MAX_PATH+1];
|
|
DWORD lognameSize = MAX_PATH+1;
|
|
retVal = FALSE;
|
|
|
|
// read all entries under this key to find all logfiles...
|
|
while ((status = RegEnumKey(hkResult, iValue, logname, lognameSize)) != ERROR_NO_MORE_ITEMS)
|
|
{
|
|
// if error during read
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
// indicate error
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((status == ERROR_ACCESS_DENIED) || (status == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed while enumerating the Eventlog registry for logfiles." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_Record:Failed while enumerating the Eventlog registry for logfiles - Return FALSE\r\n"
|
|
);
|
|
)
|
|
break;
|
|
}
|
|
|
|
if (t_PartitionSet)
|
|
{
|
|
//process this logfile for query
|
|
if (SUCCEEDED (RecurseLogFile (a_ErrorObject, t_PartitionSet, logname)))
|
|
{
|
|
retVal = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//process this logfile
|
|
if ( SUCCEEDED( DoAllInLogfile(a_ErrorObject, logname, 0, 0) ) )
|
|
{
|
|
retVal = TRUE;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
// read next parameter
|
|
iValue++;
|
|
|
|
} // end while
|
|
|
|
if (t_PartitionSet)
|
|
{
|
|
delete t_PartitionSet;
|
|
}
|
|
|
|
RegCloseKey(hkResult);
|
|
}
|
|
|
|
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_Record:Returning %lx\r\n",
|
|
retVal
|
|
);
|
|
)
|
|
|
|
return retVal;
|
|
}
|
|
|
|
HRESULT ExecQueryAsyncEventObject :: RecurseLogFile (
|
|
WbemProvErrorObject &a_ErrorObject,
|
|
PartitionSet *a_PartitionSet,
|
|
LPCWSTR a_logname
|
|
)
|
|
{
|
|
HRESULT t_Result = WBEM_E_FAILED;
|
|
|
|
ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount ();
|
|
|
|
if (t_PartitionCount == 0)
|
|
{
|
|
t_Result = S_OK;
|
|
}
|
|
|
|
for ( DWORD t_Partition = 0; t_Partition < t_PartitionCount; t_Partition++ )
|
|
{
|
|
PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition );
|
|
|
|
WmiStringRangeNode *t_Node = ( WmiStringRangeNode * ) t_PropertyPartition->GetRange ();
|
|
|
|
BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
|
|
! t_Node->InfiniteUpperBound () &&
|
|
t_Node->ClosedLowerBound () &&
|
|
t_Node->ClosedUpperBound () &&
|
|
( _wcsicmp ( t_Node->LowerBound (), t_Node->UpperBound () ) == 0 );
|
|
|
|
if (!t_Unique)
|
|
{
|
|
//not naming logfiles therefore do this logfile only if it meets bounds...
|
|
//if even one call succeeds return success
|
|
BOOL t_bProcess = TRUE;
|
|
|
|
if (!t_Node->InfiniteLowerBound())
|
|
{
|
|
int t_iCmp = _wcsicmp(a_logname, t_Node->LowerBound());
|
|
|
|
if (t_Node->ClosedLowerBound())
|
|
{
|
|
if (t_iCmp < 0)
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (t_iCmp <= 0)
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!t_Node->InfiniteUpperBound())
|
|
{
|
|
int t_iCmp = _wcsicmp(a_logname, t_Node->UpperBound());
|
|
|
|
if (t_Node->ClosedUpperBound())
|
|
{
|
|
if (t_iCmp > 0)
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (t_iCmp >= 0)
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (t_bProcess)
|
|
{
|
|
if ( SUCCEEDED(RecurseRecord(a_ErrorObject, t_PropertyPartition, a_logname)) && FAILED(t_Result) )
|
|
{
|
|
t_Result = S_OK;
|
|
}
|
|
|
|
//we've processed this logfile no need to do anymore...
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//are naming logfiles
|
|
if (_wcsicmp(t_Node->LowerBound(), a_logname) == 0)
|
|
{
|
|
//logfile matched let's do records
|
|
if (SUCCEEDED(RecurseRecord(a_ErrorObject, t_PropertyPartition, a_logname)) && FAILED(t_Result) )
|
|
{
|
|
t_Result = S_OK;
|
|
}
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
//not this logfile let's try some other...
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
return t_Result;
|
|
}
|
|
|
|
HRESULT ExecQueryAsyncEventObject :: RecurseRecord (
|
|
WbemProvErrorObject &a_ErrorObject,
|
|
PartitionSet *a_PartitionSet,
|
|
LPCWSTR a_logname
|
|
)
|
|
{
|
|
HRESULT t_Result = S_OK;
|
|
|
|
ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount ();
|
|
|
|
for ( DWORD t_Partition = 0; t_Partition < t_PartitionCount; t_Partition++ )
|
|
{
|
|
PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition );
|
|
WmiUnsignedIntegerRangeNode *t_Node = ( WmiUnsignedIntegerRangeNode * ) t_PropertyPartition->GetRange () ;
|
|
|
|
BOOL t_Unique = !t_Node->InfiniteLowerBound () &&
|
|
!t_Node->InfiniteUpperBound () &&
|
|
t_Node->ClosedLowerBound () &&
|
|
t_Node->ClosedUpperBound () &&
|
|
(t_Node->LowerBound() == t_Node->UpperBound());
|
|
|
|
if (!t_Unique)
|
|
{
|
|
if (t_Node->InfiniteLowerBound() && t_Node->InfiniteUpperBound())
|
|
{
|
|
//no limits on record therefore check time generated...
|
|
t_Result = RecurseTime(a_ErrorObject, t_PropertyPartition, a_logname, TRUE);
|
|
|
|
//there should be only one partition entry for this case but we'll break anyway...
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
DWORD t_dwLower = 0;
|
|
DWORD t_dwUpper = 0xFFFFFFFF;
|
|
BOOL t_bProcess = TRUE;
|
|
|
|
if (!t_Node->InfiniteLowerBound())
|
|
{
|
|
if (t_Node->ClosedLowerBound())
|
|
{
|
|
t_dwLower = t_Node->LowerBound();
|
|
}
|
|
else
|
|
{
|
|
if (t_Node->LowerBound() != 0xFFFFFFFF)
|
|
{
|
|
t_dwLower = t_Node->LowerBound() + 1;
|
|
}
|
|
else
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!t_Node->InfiniteUpperBound())
|
|
{
|
|
if (t_Node->ClosedUpperBound())
|
|
{
|
|
t_dwUpper = t_Node->UpperBound();
|
|
}
|
|
else
|
|
{
|
|
if (t_Node->UpperBound() != 0)
|
|
{
|
|
t_dwUpper = t_Node->UpperBound() - 1;
|
|
}
|
|
else
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (t_dwUpper < t_dwLower)
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
|
|
//now return all records including the bounds
|
|
if (t_bProcess)
|
|
{
|
|
CEventLogFile evtLog(a_logname, FALSE);
|
|
|
|
if (evtLog.IsValid())
|
|
{
|
|
DWORD t_dwEventSize = 0;
|
|
DWORD t_dwErr = evtLog.ReadRecord(t_dwUpper, &t_dwEventSize, TRUE);
|
|
|
|
if (0 == t_dwErr)
|
|
{
|
|
DWORD t_dwState = 0;
|
|
|
|
while (0 == t_dwState)
|
|
{
|
|
PEVENTLOGRECORD EventBuffer = (PEVENTLOGRECORD)evtLog.GetBuffer();
|
|
|
|
while (t_dwEventSize != 0)
|
|
{
|
|
if (EventBuffer->RecordNumber >= t_dwLower)
|
|
{
|
|
CEventlogRecord evtrec(a_logname, EventBuffer, NULL, m_ClassObject, m_AClassObject);
|
|
IWbemClassObject* pInst = NULL;
|
|
|
|
if (evtrec.GenerateInstance(&pInst))
|
|
{
|
|
t_Result = m_NotificationHandler->Indicate ( 1, & pInst );
|
|
|
|
//upper limit is decreased with this indicate!
|
|
t_dwUpper--;
|
|
pInst->Release();
|
|
|
|
if (FAILED(t_Result))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed while indicating record instance." );
|
|
t_dwState = 2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// drop by length of this record and point to next record
|
|
t_dwEventSize -= EventBuffer->Length;
|
|
EventBuffer = (PEVENTLOGRECORD) ((UCHAR*) EventBuffer + EventBuffer->Length);
|
|
}
|
|
else
|
|
{
|
|
t_dwState = 2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (t_dwState == 0)
|
|
{
|
|
t_dwErr = evtLog.ReadRecord(0, &t_dwEventSize, TRUE);
|
|
|
|
if (0 != t_dwErr)
|
|
{
|
|
if (SUCCEEDED(t_Result) && (t_dwErr != ERROR_HANDLE_EOF))
|
|
{
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
t_Result = WBEM_E_FAILED;
|
|
|
|
if ((t_dwErr == ERROR_ACCESS_DENIED) || (t_dwErr == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed while enumerating one of the logfiles." );
|
|
}
|
|
|
|
t_dwState = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((t_dwState == 1) && (t_dwErr == ERROR_HANDLE_EOF) && (t_dwUpper > t_dwLower))
|
|
{
|
|
//got all the records til the start of the log see if there are any at the top
|
|
t_Result = DoAllInLogfile(a_ErrorObject, a_logname, t_dwUpper, t_dwLower);
|
|
|
|
if (FAILED(t_Result))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (t_dwLower != t_dwUpper)
|
|
{
|
|
//the upper bound does not exist, try from the top down...
|
|
t_Result = DoAllInLogfile(a_ErrorObject, a_logname, t_dwUpper, t_dwLower);
|
|
|
|
if (FAILED(t_Result))
|
|
{
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//are naming records
|
|
CEventLogFile evtLog(a_logname, FALSE);
|
|
|
|
if (evtLog.IsValid())
|
|
{
|
|
DWORD err = evtLog.ReadRecord(t_Node->LowerBound());
|
|
|
|
if (0 == err)
|
|
{
|
|
EVENTLOGRECORD* EventBuffer = (EVENTLOGRECORD*) evtLog.GetBuffer();
|
|
CEventlogRecord evtRec(a_logname, EventBuffer, NULL, m_ClassObject, m_AClassObject);
|
|
IWbemClassObject* pInst = NULL;
|
|
|
|
if (evtRec.GenerateInstance(&pInst))
|
|
{
|
|
t_Result = m_NotificationHandler->Indicate ( 1 , & pInst ) ;
|
|
pInst->Release();
|
|
|
|
if (FAILED(t_Result))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed while indicating record instance." );
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//failed to create record
|
|
t_Result = WBEM_E_FAILED;
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED ) ;
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
|
|
a_ErrorObject.SetMessage ( L"Failed to create instance from Eventlog data" ) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return t_Result;
|
|
}
|
|
|
|
HRESULT ExecQueryAsyncEventObject::RecurseTime(WbemProvErrorObject &a_ErrorObject, PartitionSet *a_PartitionSet,
|
|
LPCWSTR a_logname, BOOL a_Generated)
|
|
{
|
|
HRESULT t_Result = S_OK;
|
|
|
|
ULONG t_PartitionCount = a_PartitionSet->GetPartitionCount ();
|
|
|
|
for ( DWORD t_Partition = 0; t_Partition < t_PartitionCount; t_Partition++ )
|
|
{
|
|
PartitionSet *t_PropertyPartition = a_PartitionSet->GetPartition ( t_Partition );
|
|
|
|
WmiStringRangeNode *t_Node = ( WmiStringRangeNode * ) t_PropertyPartition->GetRange ();
|
|
|
|
BOOL t_Unique = ! t_Node->InfiniteLowerBound () &&
|
|
! t_Node->InfiniteUpperBound () &&
|
|
t_Node->ClosedLowerBound () &&
|
|
t_Node->ClosedUpperBound () &&
|
|
( _wcsicmp ( t_Node->LowerBound (), t_Node->UpperBound () ) == 0 );
|
|
|
|
if (!t_Unique)
|
|
{
|
|
if (t_Node->InfiniteLowerBound() && t_Node->InfiniteUpperBound())
|
|
{
|
|
//no limits on record therefore check time written...
|
|
if (a_Generated)
|
|
{
|
|
t_Result = RecurseTime(a_ErrorObject, t_PropertyPartition, a_logname, FALSE);
|
|
}
|
|
else
|
|
{
|
|
//do all in the logfile...
|
|
t_Result = DoAllInLogfile(a_ErrorObject, a_logname, 0, 0);
|
|
}
|
|
|
|
//there should be only one partition entry for this case but we'll break anyway...
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
//we have bounds (at least one anyway!)
|
|
DWORD t_tmLower = 0;
|
|
DWORD t_tmUpper = 0xFFFFFFFF;
|
|
BOOL t_bProcess = TRUE;
|
|
|
|
if (!t_Node->InfiniteLowerBound())
|
|
{
|
|
WBEMTime t_Time(t_Node->LowerBound());
|
|
time_t t_temp = 0;
|
|
|
|
if (t_Time.IsOk() && t_Time.Gettime_t(&t_temp))
|
|
{
|
|
t_tmLower = (DWORD)t_temp;
|
|
|
|
if (!t_Node->ClosedLowerBound())
|
|
{
|
|
if (t_tmLower != 0xFFFFFFFF)
|
|
{
|
|
t_tmLower++;
|
|
}
|
|
else
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
DWORD t_len = wcslen(t_Node->LowerBound());
|
|
|
|
if (t_len == NTEVT_DMTFLEN)
|
|
{
|
|
BOOL t_bIsLo = FALSE;
|
|
BOOL t_bIsHi = TRUE;
|
|
|
|
if (CheckTime(t_Node->LowerBound(), t_bIsLo, t_bIsHi))
|
|
{
|
|
if (t_bIsHi)
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!t_Node->InfiniteUpperBound())
|
|
{
|
|
WBEMTime t_Time(t_Node->UpperBound());
|
|
time_t t_temp = 0;
|
|
|
|
if (t_Time.IsOk() && t_Time.Gettime_t(&t_temp))
|
|
{
|
|
t_tmUpper = (DWORD)t_temp;
|
|
|
|
if (!t_Node->ClosedUpperBound())
|
|
{
|
|
if (t_tmUpper != 0)
|
|
{
|
|
t_tmUpper--;
|
|
}
|
|
else
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
DWORD t_len = wcslen(t_Node->UpperBound());
|
|
|
|
if (t_len == NTEVT_DMTFLEN)
|
|
{
|
|
BOOL t_bIsLo = FALSE;
|
|
BOOL t_bIsHi = TRUE;
|
|
|
|
if (CheckTime(t_Node->LowerBound(), t_bIsLo, t_bIsHi))
|
|
{
|
|
if (t_bIsLo)
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (t_tmUpper < t_tmLower)
|
|
{
|
|
t_bProcess = FALSE;
|
|
}
|
|
|
|
//now return all records including the bounds
|
|
if (t_bProcess)
|
|
{
|
|
t_Result = GetRecordsBetweenTimes(a_ErrorObject, a_logname, a_Generated, t_tmUpper, t_tmLower);
|
|
|
|
if (FAILED(t_Result))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//want records with exactly the right time...
|
|
WBEMTime t_Time(t_Node->LowerBound());
|
|
time_t t_temp = 0;
|
|
|
|
if (t_Time.IsOk() && t_Time.Gettime_t(&t_temp))
|
|
{
|
|
t_Result = GetRecordsBetweenTimes(a_ErrorObject, a_logname, a_Generated, (DWORD)t_temp, (DWORD)t_temp);
|
|
|
|
if (FAILED(t_Result))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return t_Result;
|
|
}
|
|
|
|
HRESULT ExecQueryAsyncEventObject::GetRecordsBetweenTimes(WbemProvErrorObject &a_ErrorObject, LPCWSTR a_logname,
|
|
BOOL a_Generated, DWORD a_dwUpper, DWORD a_dwLower)
|
|
{
|
|
HRESULT retVal = WBEM_E_FAILED;
|
|
CEventLogFile evtLog(a_logname, FALSE);
|
|
|
|
if (evtLog.IsValid())
|
|
{
|
|
DWORD t_NewRec = 0;
|
|
DWORD t_NumRecs = 0;
|
|
|
|
if (evtLog.GetLastRecordID(t_NewRec, t_NumRecs))
|
|
{
|
|
retVal = WBEM_S_NO_ERROR;
|
|
|
|
while (t_NumRecs > 0)
|
|
{
|
|
DWORD t_RecId = t_NumRecs/2;
|
|
|
|
if (t_NumRecs%2)
|
|
{
|
|
t_RecId++;
|
|
}
|
|
|
|
//adjust for the record number offset
|
|
if (t_RecId > t_NewRec)
|
|
{
|
|
//recordnumber has wrapped around...
|
|
t_RecId = 0xFFFFFFFF - t_RecId + t_NewRec + 1;
|
|
}
|
|
else
|
|
{
|
|
t_RecId = t_NewRec - t_RecId + 1;
|
|
}
|
|
|
|
DWORD t_dwEventSize = 0;
|
|
DWORD t_dwErr = evtLog.ReadRecord(t_RecId, &t_dwEventSize, TRUE);
|
|
|
|
if (0 == t_dwErr)
|
|
{
|
|
EVENTLOGRECORD* t_pEventBuffer = (EVENTLOGRECORD*) evtLog.GetBuffer();
|
|
DWORD t_Time = a_Generated ? t_pEventBuffer->TimeGenerated : t_pEventBuffer->TimeWritten;
|
|
|
|
if (a_dwUpper >= t_Time)
|
|
{
|
|
if (a_dwLower <= t_Time)
|
|
{
|
|
//generate all above and below this that match...
|
|
t_NumRecs = 0;
|
|
|
|
//below...
|
|
while((a_dwUpper >= t_Time) && (a_dwLower <= t_Time) && (t_dwEventSize != 0))
|
|
{
|
|
CEventlogRecord evtrec(a_logname, t_pEventBuffer, NULL, m_ClassObject, m_AClassObject);
|
|
IWbemClassObject* pInst = NULL;
|
|
|
|
if (evtrec.GenerateInstance(&pInst))
|
|
{
|
|
retVal = m_NotificationHandler->Indicate ( 1, & pInst );
|
|
pInst->Release();
|
|
|
|
if (FAILED(retVal))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed while indicating record instance." );
|
|
break;
|
|
}
|
|
}
|
|
|
|
// drop by length of this record and point to next record
|
|
t_dwEventSize -= t_pEventBuffer->Length;
|
|
|
|
if (t_dwEventSize == 0)
|
|
{
|
|
t_dwErr = evtLog.ReadRecord(0, &t_dwEventSize, TRUE);
|
|
|
|
if (t_dwErr == ERROR_SUCCESS)
|
|
{
|
|
t_pEventBuffer = (EVENTLOGRECORD*) evtLog.GetBuffer();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_pEventBuffer = (PEVENTLOGRECORD) ((UCHAR*) t_pEventBuffer + t_pEventBuffer->Length);
|
|
}
|
|
|
|
t_Time = a_Generated ? t_pEventBuffer->TimeGenerated : t_pEventBuffer->TimeWritten;
|
|
}
|
|
|
|
if (SUCCEEDED(retVal))
|
|
{
|
|
//above...
|
|
evtLog.ReadRecord(t_RecId, &t_dwEventSize, FALSE);
|
|
|
|
//skip the record we've done already...
|
|
t_pEventBuffer = (EVENTLOGRECORD*) evtLog.GetBuffer();
|
|
t_dwEventSize -= t_pEventBuffer->Length;
|
|
|
|
if (t_dwEventSize != 0)
|
|
{
|
|
t_pEventBuffer = (PEVENTLOGRECORD) ((UCHAR*) t_pEventBuffer + t_pEventBuffer->Length);
|
|
t_Time = a_Generated ? t_pEventBuffer->TimeGenerated : t_pEventBuffer->TimeWritten;
|
|
|
|
while((a_dwUpper >= t_Time) && (a_dwLower <= t_Time) && (t_dwEventSize != 0))
|
|
{
|
|
CEventlogRecord evtrec(a_logname, t_pEventBuffer, NULL, m_ClassObject, m_AClassObject);
|
|
IWbemClassObject* pInst = NULL;
|
|
|
|
if (evtrec.GenerateInstance(&pInst))
|
|
{
|
|
retVal = m_NotificationHandler->Indicate ( 1, & pInst );
|
|
pInst->Release();
|
|
|
|
if (FAILED(retVal))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed while indicating record instance." );
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
// drop by length of this record and point to next record
|
|
t_dwEventSize -= t_pEventBuffer->Length;
|
|
|
|
if (t_dwEventSize == 0)
|
|
{
|
|
t_dwErr = evtLog.ReadRecord(0, &t_dwEventSize, FALSE);
|
|
|
|
if (t_dwErr == ERROR_SUCCESS)
|
|
{
|
|
t_pEventBuffer = (EVENTLOGRECORD*) evtLog.GetBuffer();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_pEventBuffer = (PEVENTLOGRECORD) ((UCHAR*) t_pEventBuffer + t_pEventBuffer->Length);
|
|
}
|
|
|
|
t_Time = a_Generated ? t_pEventBuffer->TimeGenerated : t_pEventBuffer->TimeWritten;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//too old, go higher done automatically by halving t_NumRecs
|
|
if (t_NumRecs > 1)
|
|
{
|
|
if ((t_NumRecs%2) || (t_NumRecs == 2))
|
|
{
|
|
t_NumRecs = t_NumRecs/2;
|
|
}
|
|
else
|
|
{
|
|
t_NumRecs = t_NumRecs/2 - 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_NumRecs = 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//too recent, setup the number of records left and go lower by
|
|
//setting the upper limit to one less than we've checked...
|
|
if (t_NumRecs > 1)
|
|
{
|
|
t_NumRecs = t_NumRecs/2;
|
|
|
|
if (t_RecId == 1)
|
|
{
|
|
//we've wrapped...
|
|
t_NewRec = 0xFFFFFFFF;
|
|
}
|
|
else
|
|
{
|
|
t_NewRec = t_RecId - 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_NumRecs = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
t_NumRecs = 0;
|
|
|
|
if (t_dwErr != ERROR_HANDLE_EOF)
|
|
{
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((t_dwErr == ERROR_ACCESS_DENIED) || (t_dwErr == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed while searching one of the logfiles." );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
HRESULT ExecQueryAsyncEventObject::DoAllInLogfile(WbemProvErrorObject &a_ErrorObject, LPCWSTR a_logname, DWORD a_dwUpper, DWORD a_dwLower)
|
|
{
|
|
//process this logfile
|
|
HRESULT retVal = S_OK;
|
|
CEventLogFile evtLog(a_logname, FALSE);
|
|
BOOL bContinue = TRUE;
|
|
|
|
if (evtLog.IsValid())
|
|
{
|
|
evtLog.ReadLastRecord();
|
|
}
|
|
|
|
while (evtLog.IsValid() && SUCCEEDED(retVal) && bContinue)
|
|
{
|
|
DWORD dwEventSize = 0;
|
|
DWORD err = evtLog.ReadRecord(0, &dwEventSize, TRUE);
|
|
|
|
if (0 != err)
|
|
{
|
|
if (err != ERROR_HANDLE_EOF)
|
|
{
|
|
a_ErrorObject.SetStatus ( WBEM_PROV_E_UNEXPECTED );
|
|
|
|
if ((err == ERROR_ACCESS_DENIED) || (err == ERROR_PRIVILEGE_NOT_HELD))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_S_ACCESS_DENIED );
|
|
a_ErrorObject.SetSecurityPrivRequired();
|
|
a_ErrorObject.SetSecurityPrivFailed();
|
|
a_ErrorObject.SetPrivilegeFailed();
|
|
}
|
|
else
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
}
|
|
|
|
a_ErrorObject.SetMessage ( L"Failed while enumerating one of the logfiles." );
|
|
DebugOut(
|
|
CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine (
|
|
|
|
_T(__FILE__),__LINE__,
|
|
L"ExecQueryAsyncEventObject :: Query_Record:Failed while enumerating one of the logfiles.\r\n"
|
|
);
|
|
)
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
PEVENTLOGRECORD EventBuffer = (PEVENTLOGRECORD)evtLog.GetBuffer();
|
|
|
|
if (a_dwUpper != a_dwLower)
|
|
{
|
|
if ((EventBuffer->RecordNumber > a_dwUpper) || (EventBuffer->RecordNumber < a_dwLower))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
while (dwEventSize != 0)
|
|
{
|
|
if (a_dwUpper != a_dwLower)
|
|
{
|
|
if ((EventBuffer->RecordNumber > a_dwUpper) || (EventBuffer->RecordNumber < a_dwLower))
|
|
{
|
|
bContinue = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
CEventlogRecord evtrec(a_logname, EventBuffer, NULL, m_ClassObject, m_AClassObject);
|
|
IWbemClassObject* pInst = NULL;
|
|
|
|
if (evtrec.GenerateInstance(&pInst))
|
|
{
|
|
retVal = m_NotificationHandler->Indicate ( 1, & pInst );
|
|
pInst->Release();
|
|
|
|
if (FAILED(retVal))
|
|
{
|
|
a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED );
|
|
a_ErrorObject.SetMessage ( L"Failed while indicating record instance." );
|
|
}
|
|
}
|
|
|
|
// drop by length of this record and point to next record
|
|
dwEventSize -= EventBuffer->Length;
|
|
EventBuffer = (PEVENTLOGRECORD) ((UCHAR*) EventBuffer + EventBuffer->Length);
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState ExecQueryAsyncEventObject :: Compare (
|
|
|
|
LONG a_Operand1,
|
|
LONG a_Operand2,
|
|
ULONG a_Operand1Func,
|
|
ULONG a_Operand2Func,
|
|
WmiTreeNode &a_OperatorType
|
|
)
|
|
{
|
|
QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
|
|
switch ( a_Operand1Func )
|
|
{
|
|
case WmiValueNode :: WmiValueFunction :: Function_None:
|
|
{
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
|
|
switch ( a_Operand2Func )
|
|
{
|
|
case WmiValueNode :: WmiValueFunction :: Function_None:
|
|
{
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
|
|
if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualNode ) )
|
|
{
|
|
t_Status = a_Operand1 == a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotEqualNode ) )
|
|
{
|
|
t_Status = a_Operand1 != a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrGreaterNode ) )
|
|
{
|
|
t_Status = a_Operand1 >= a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrLessNode ) )
|
|
{
|
|
t_Status = a_Operand1 <= a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLessNode ) )
|
|
{
|
|
t_Status = a_Operand1 < a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorGreaterNode ) )
|
|
{
|
|
t_Status = a_Operand1 > a_Operand2
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False;
|
|
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLikeNode ) )
|
|
{
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotLikeNode ) )
|
|
{
|
|
}
|
|
|
|
return t_Status;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState ExecQueryAsyncEventObject :: Compare (
|
|
|
|
wchar_t *a_Operand1,
|
|
wchar_t *a_Operand2,
|
|
ULONG a_Operand1Func,
|
|
ULONG a_Operand2Func,
|
|
WmiTreeNode &a_OperatorType
|
|
)
|
|
{
|
|
QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
|
|
wchar_t *a_Operand1AfterFunc = NULL;
|
|
wchar_t *a_Operand2AfterFunc = NULL;
|
|
|
|
switch ( a_Operand1Func )
|
|
{
|
|
case WmiValueNode :: WmiValueFunction :: Function_None:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case WmiValueNode :: WmiValueFunction :: Function_Upper:
|
|
{
|
|
ULONG length = wcslen ( a_Operand1 );
|
|
wchar_t *a_Operand1AfterFunc = new wchar_t [ length + 1 ];
|
|
for ( ULONG index = 0; index < length; index ++ )
|
|
{
|
|
a_Operand1AfterFunc [ index ] = towupper ( a_Operand1 [ index ] );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WmiValueNode :: WmiValueFunction :: Function_Lower:
|
|
{
|
|
ULONG length = wcslen ( a_Operand1 );
|
|
wchar_t *a_Operand1AfterFunc = new wchar_t [ length + 1 ];
|
|
for ( ULONG index = 0; index < length; index ++ )
|
|
{
|
|
a_Operand1AfterFunc [ index ] = towlower ( a_Operand1 [ index ] );
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
|
|
switch ( a_Operand2Func )
|
|
{
|
|
case WmiValueNode :: WmiValueFunction :: Function_None:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case WmiValueNode :: WmiValueFunction :: Function_Upper:
|
|
{
|
|
ULONG length = wcslen ( a_Operand2 );
|
|
wchar_t *a_Operand2AfterFunc = new wchar_t [ length + 1 ];
|
|
for ( ULONG index = 0; index < length; index ++ )
|
|
{
|
|
a_Operand2AfterFunc [ index ] = towupper ( a_Operand2 [ index ] );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WmiValueNode :: WmiValueFunction :: Function_Lower:
|
|
{
|
|
ULONG length = wcslen ( a_Operand2 );
|
|
wchar_t *a_Operand2AfterFunc = new wchar_t [ length + 1 ];
|
|
for ( ULONG index = 0; index < length; index ++ )
|
|
{
|
|
a_Operand2AfterFunc [ index ] = towlower ( a_Operand2 [ index ] );
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
|
|
const wchar_t *t_Arg1 = a_Operand1AfterFunc ? a_Operand1AfterFunc : a_Operand1;
|
|
const wchar_t *t_Arg2 = a_Operand2AfterFunc ? a_Operand2AfterFunc : a_Operand2;
|
|
|
|
if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) == 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( ( t_Arg1 ) || ( t_Arg2 ) )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotEqualNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) != 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( ( t_Arg1 ) || ( t_Arg2 ) )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrGreaterNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) >= 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( t_Arg1 )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
else
|
|
{
|
|
if ( t_Arg2 )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorEqualOrLessNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) <= 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( ( t_Arg1 ) )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( t_Arg2 )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLessNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) < 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( ( ! t_Arg1 ) && ( ! t_Arg2 ) )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else if ( t_Arg1 )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorGreaterNode ) )
|
|
{
|
|
if ( ( t_Arg1 ) && ( t_Arg2 ) )
|
|
{
|
|
t_Status = wcscmp ( t_Arg1 , t_Arg2 ) > 0
|
|
? QueryPreprocessor :: QuadState :: State_True
|
|
: QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else
|
|
{
|
|
if ( ( ! t_Arg1 ) && ( ! t_Arg2 ) )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
else if ( t_Arg1 )
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True ;
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False ;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorLikeNode ) )
|
|
{
|
|
}
|
|
else if ( typeid ( a_OperatorType ) == typeid ( WmiOperatorNotLikeNode ) )
|
|
{
|
|
}
|
|
|
|
delete [] a_Operand1AfterFunc;
|
|
delete [] a_Operand2AfterFunc;
|
|
|
|
return t_Status;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState ExecQueryAsyncEventObject :: CompareDateTime (
|
|
|
|
IWbemClassObject *a_ClassObject,
|
|
BSTR a_PropertyName,
|
|
WmiTreeNode *a_Operator,
|
|
WmiTreeNode *a_Operand
|
|
)
|
|
{
|
|
/*
|
|
* If property and value can never occur then return State_False to imply empty set
|
|
* If property and value do not infer anything then return State_Undefined.
|
|
*/
|
|
WmiStringNode *t_StringNode = ( WmiStringNode * ) a_Operand;
|
|
|
|
if ( t_StringNode == NULL || t_StringNode->GetValue() == NULL)
|
|
{
|
|
return QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
WBEMTime t_Time((const BSTR)t_StringNode->GetValue());
|
|
|
|
if ( typeid ( *a_Operator ) == typeid ( WmiOperatorEqualNode ) )
|
|
{
|
|
time_t t_temp = 0;
|
|
t_Status = (t_Time.IsOk() && t_Time.Gettime_t(&t_temp))
|
|
? QueryPreprocessor :: QuadState :: State_Undefined
|
|
: QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorNotEqualNode ) )
|
|
{
|
|
time_t t_temp = 0;
|
|
t_Status = (t_Time.IsOk() && t_Time.Gettime_t(&t_temp))
|
|
? QueryPreprocessor :: QuadState :: State_Undefined
|
|
: QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorEqualOrGreaterNode ) )
|
|
{
|
|
//to do: check t_time >= val this will always be true if t_time >= max time_t
|
|
//will always be false if t_time is < 1970.
|
|
time_t t_temp = 0;
|
|
|
|
if (t_Time.IsOk() && t_Time.Gettime_t(&t_temp))
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_Undefined;
|
|
}
|
|
else
|
|
{
|
|
DWORD t_len = wcslen(t_StringNode->GetValue());
|
|
|
|
if (t_len == NTEVT_DMTFLEN)
|
|
{
|
|
BOOL t_bIsLo = FALSE;
|
|
BOOL t_bIsHi = TRUE;
|
|
|
|
if (CheckTime(t_StringNode->GetValue(), t_bIsLo, t_bIsHi))
|
|
{
|
|
if (t_bIsHi)
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
else if (t_bIsLo)
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorEqualOrLessNode ) )
|
|
{
|
|
//to do: check t_time <= val this will always be true if t_time <= 1970
|
|
//will always be false if t_time is > max time_t.
|
|
time_t t_temp = 0;
|
|
|
|
if (t_Time.IsOk() && t_Time.Gettime_t(&t_temp))
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_Undefined;
|
|
}
|
|
else
|
|
{
|
|
DWORD t_len = wcslen(t_StringNode->GetValue());
|
|
|
|
if (t_len == NTEVT_DMTFLEN)
|
|
{
|
|
BOOL t_bIsLo = FALSE;
|
|
BOOL t_bIsHi = TRUE;
|
|
|
|
if (CheckTime(t_StringNode->GetValue(), t_bIsLo, t_bIsHi))
|
|
{
|
|
if (t_bIsHi)
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
else if (t_bIsLo)
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorLessNode ) )
|
|
{
|
|
//to do: check t_time < val this will always be true if t_time < 1970
|
|
//will always be false if t_time is > max time_t.
|
|
time_t t_temp = 0;
|
|
|
|
if (t_Time.IsOk() && t_Time.Gettime_t(&t_temp))
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_Undefined;
|
|
}
|
|
else
|
|
{
|
|
DWORD t_len = wcslen(t_StringNode->GetValue());
|
|
|
|
if (t_len == NTEVT_DMTFLEN)
|
|
{
|
|
BOOL t_bIsLo = FALSE;
|
|
BOOL t_bIsHi = TRUE;
|
|
|
|
if (CheckTime(t_StringNode->GetValue(), t_bIsLo, t_bIsHi))
|
|
{
|
|
if (t_bIsHi)
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
else if (t_bIsLo)
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
}
|
|
}
|
|
else if ( typeid ( *a_Operator ) == typeid ( WmiOperatorGreaterNode ) )
|
|
{
|
|
//to do: check t_time > val this will always be true if t_time > max time_t
|
|
//will always be false if t_time is < 1970.
|
|
time_t t_temp = 0;
|
|
|
|
if (t_Time.IsOk() && t_Time.Gettime_t(&t_temp))
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_Undefined;
|
|
}
|
|
else
|
|
{
|
|
DWORD t_len = wcslen(t_StringNode->GetValue());
|
|
|
|
if (t_len == NTEVT_DMTFLEN)
|
|
{
|
|
BOOL t_bIsLo = FALSE;
|
|
BOOL t_bIsHi = TRUE;
|
|
|
|
if (CheckTime(t_StringNode->GetValue(), t_bIsLo, t_bIsHi))
|
|
{
|
|
if (t_bIsHi)
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
else if (t_bIsLo)
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_False;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
}
|
|
}
|
|
}
|
|
|
|
return t_Status;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState ExecQueryAsyncEventObject :: CompareString (
|
|
|
|
IWbemClassObject *a_ClassObject,
|
|
BSTR a_PropertyName,
|
|
WmiTreeNode *a_Operator,
|
|
WmiTreeNode *a_Operand
|
|
)
|
|
{
|
|
QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
|
|
WmiStringNode *t_StringNode = ( WmiStringNode * ) a_Operand;
|
|
|
|
VARIANT t_Variant;
|
|
VariantInit ( & t_Variant );
|
|
|
|
HRESULT t_Result = a_ClassObject->Get ( a_PropertyName, 0, &t_Variant, NULL, NULL );
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
t_Status = Compare (
|
|
|
|
t_StringNode->GetValue (),
|
|
t_Variant.bstrVal,
|
|
t_StringNode->GetPropertyFunction (),
|
|
t_StringNode->GetConstantFunction (),
|
|
*a_Operator
|
|
);
|
|
}
|
|
|
|
VariantClear ( & t_Variant );
|
|
|
|
return t_Status;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState ExecQueryAsyncEventObject :: CompareInteger (
|
|
|
|
IWbemClassObject *a_ClassObject,
|
|
BSTR a_PropertyName,
|
|
WmiTreeNode *a_Operator,
|
|
WmiTreeNode *a_Operand
|
|
)
|
|
{
|
|
QueryPreprocessor :: QuadState t_Status = QueryPreprocessor :: QuadState :: State_True;
|
|
|
|
WmiSignedIntegerNode *t_IntegerNode = ( WmiSignedIntegerNode * ) a_Operand;
|
|
|
|
VARIANT t_Variant;
|
|
VariantInit ( & t_Variant );
|
|
|
|
HRESULT t_Result = a_ClassObject->Get ( a_PropertyName, 0, &t_Variant, NULL, NULL );
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
t_Status = Compare (
|
|
|
|
t_IntegerNode->GetValue (),
|
|
t_Variant.lVal,
|
|
t_IntegerNode->GetPropertyFunction (),
|
|
t_IntegerNode->GetConstantFunction (),
|
|
*a_Operator
|
|
);
|
|
}
|
|
|
|
VariantClear ( & t_Variant );
|
|
|
|
return t_Status;
|
|
}
|
|
|
|
WmiTreeNode *ExecQueryAsyncEventObject :: AllocTypeNode (
|
|
|
|
void *a_Context,
|
|
BSTR a_PropertyName,
|
|
VARIANT &a_Variant,
|
|
WmiValueNode :: WmiValueFunction a_PropertyFunction,
|
|
WmiValueNode :: WmiValueFunction a_ConstantFunction,
|
|
WmiTreeNode *a_Parent
|
|
)
|
|
{
|
|
WmiTreeNode *t_Node = NULL;
|
|
|
|
VARTYPE t_VarType = VT_NULL;
|
|
|
|
if ( *a_PropertyName == L'_' )
|
|
{
|
|
// System property
|
|
|
|
if ( _wcsicmp ( a_PropertyName, SYSTEM_PROPERTY_CLASS ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.bstrVal,
|
|
a_PropertyFunction,
|
|
a_ConstantFunction,
|
|
0xFFFFFFFF,
|
|
a_Parent
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName, SYSTEM_PROPERTY_SUPERCLASS ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.bstrVal,
|
|
a_PropertyFunction,
|
|
a_ConstantFunction,
|
|
0xFFFFFFFF,
|
|
a_Parent
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName, SYSTEM_PROPERTY_GENUS ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_I4))
|
|
{
|
|
t_Node = new WmiSignedIntegerNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.lVal,
|
|
0xFFFFFFFF,
|
|
a_Parent
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName, SYSTEM_PROPERTY_SERVER ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.bstrVal,
|
|
a_PropertyFunction,
|
|
a_ConstantFunction,
|
|
0xFFFFFFFF,
|
|
a_Parent
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName, SYSTEM_PROPERTY_NAMESPACE ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.bstrVal,
|
|
a_PropertyFunction,
|
|
a_ConstantFunction,
|
|
0xFFFFFFFF,
|
|
a_Parent
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName, SYSTEM_PROPERTY_PROPERTY_COUNT ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_I4))
|
|
{
|
|
t_Node = new WmiSignedIntegerNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.lVal,
|
|
0xFFFFFFFF,
|
|
a_Parent
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName, SYSTEM_PROPERTY_DYNASTY ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.bstrVal,
|
|
a_PropertyFunction,
|
|
a_ConstantFunction,
|
|
0xFFFFFFFF,
|
|
a_Parent
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName, SYSTEM_PROPERTY_RELPATH ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.bstrVal,
|
|
a_PropertyFunction,
|
|
a_ConstantFunction,
|
|
0xFFFFFFFF,
|
|
a_Parent
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName, SYSTEM_PROPERTY_PATH ) == 0 &&
|
|
(V_VT(&a_Variant) == VT_BSTR))
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.bstrVal,
|
|
a_PropertyFunction,
|
|
a_ConstantFunction,
|
|
0xFFFFFFFF,
|
|
a_Parent
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( a_PropertyName, SYSTEM_PROPERTY_DERIVATION ) == 0 )
|
|
{
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CIMTYPE t_VarType;
|
|
long t_Flavour;
|
|
VARIANT t_Variant;
|
|
VariantInit ( & t_Variant );
|
|
|
|
HRESULT t_Result = m_ClassObject->Get (
|
|
|
|
a_PropertyName,
|
|
0,
|
|
& t_Variant,
|
|
& t_VarType,
|
|
& t_Flavour
|
|
);
|
|
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
if ( t_VarType & CIM_FLAG_ARRAY )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
switch ( t_VarType & ( ~ CIM_FLAG_ARRAY ) )
|
|
{
|
|
case CIM_BOOLEAN:
|
|
{
|
|
if(V_VT(&a_Variant) == VT_I4)
|
|
{
|
|
t_Node = new WmiSignedIntegerNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.lVal,
|
|
GetPriority ( a_PropertyName ),
|
|
a_Parent
|
|
);
|
|
}
|
|
else if (V_VT(&a_Variant) == VT_BOOL)
|
|
{
|
|
t_Node = new WmiSignedIntegerNode (
|
|
|
|
a_PropertyName,
|
|
(a_Variant.lVal == VARIANT_FALSE) ? 0 : 1,
|
|
GetPriority ( a_PropertyName ),
|
|
a_Parent
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CIM_SINT8:
|
|
case CIM_SINT16:
|
|
case CIM_CHAR16:
|
|
case CIM_SINT32:
|
|
{
|
|
if(V_VT(&a_Variant) == VT_I4)
|
|
{
|
|
t_Node = new WmiSignedIntegerNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.lVal,
|
|
GetPriority ( a_PropertyName ),
|
|
a_Parent
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CIM_UINT8:
|
|
case CIM_UINT16:
|
|
case CIM_UINT32:
|
|
{
|
|
if(V_VT(&a_Variant) == VT_I4)
|
|
{
|
|
t_Node = new WmiUnsignedIntegerNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.lVal,
|
|
GetPriority ( a_PropertyName ),
|
|
a_Parent
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CIM_SINT64:
|
|
case CIM_UINT64:
|
|
{
|
|
if(V_VT(&a_Variant) == VT_BSTR)
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.bstrVal,
|
|
a_PropertyFunction,
|
|
a_ConstantFunction,
|
|
GetPriority ( a_PropertyName ),
|
|
a_Parent
|
|
);
|
|
}
|
|
else if(V_VT(&a_Variant) == VT_I4)
|
|
{
|
|
_variant_t t_uintBuff (&a_Variant);
|
|
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName,
|
|
(BSTR)((_bstr_t) t_uintBuff),
|
|
a_PropertyFunction,
|
|
a_ConstantFunction,
|
|
GetPriority ( a_PropertyName ),
|
|
a_Parent
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CIM_STRING:
|
|
case CIM_DATETIME:
|
|
case CIM_REFERENCE:
|
|
{
|
|
if(V_VT(&a_Variant) == VT_BSTR)
|
|
{
|
|
t_Node = new WmiStringNode (
|
|
|
|
a_PropertyName,
|
|
a_Variant.bstrVal,
|
|
a_PropertyFunction,
|
|
a_ConstantFunction,
|
|
GetPriority ( a_PropertyName ),
|
|
a_Parent
|
|
);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CIM_REAL32:
|
|
case CIM_REAL64:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case CIM_OBJECT:
|
|
case CIM_EMPTY:
|
|
{
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
VariantClear ( & t_Variant );
|
|
}
|
|
|
|
return t_Node;
|
|
}
|
|
|
|
QueryPreprocessor :: QuadState ExecQueryAsyncEventObject :: InvariantEvaluate (
|
|
|
|
void *a_Context,
|
|
WmiTreeNode *a_Operator,
|
|
WmiTreeNode *a_Operand
|
|
)
|
|
{
|
|
/*
|
|
* If property and value are invariant i.e. will never change for all instances then return State_True.
|
|
* If property is not indexable or keyed then return State_True to define an unknown number of possible values which we cannot optimise against.
|
|
* If property and value can never occur then return State_False to imply empty set
|
|
* If property and value do not infer anything then return State_Undefined.
|
|
* If property and value are in error then return State_Error
|
|
* Never return State_ReEvaluate.
|
|
*/
|
|
|
|
QueryPreprocessor :: QuadState t_State = QueryPreprocessor :: QuadState :: State_Error;
|
|
|
|
WmiValueNode *t_Node = ( WmiValueNode * ) a_Operand;
|
|
BSTR t_PropertyName = t_Node->GetPropertyName ();
|
|
|
|
if ( t_PropertyName != NULL )
|
|
{
|
|
if ( *t_PropertyName == L'_' )
|
|
{
|
|
// System property, must check values
|
|
|
|
if ( _wcsicmp ( t_PropertyName, SYSTEM_PROPERTY_CLASS ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_CLASS,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName, SYSTEM_PROPERTY_SUPERCLASS ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_SUPERCLASS,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName, SYSTEM_PROPERTY_GENUS ) == 0 )
|
|
{
|
|
t_State = CompareInteger (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_GENUS,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName, SYSTEM_PROPERTY_SERVER ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_SERVER,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName, SYSTEM_PROPERTY_NAMESPACE ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_NAMESPACE,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName, SYSTEM_PROPERTY_PROPERTY_COUNT ) == 0 )
|
|
{
|
|
t_State = CompareInteger (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_PROPERTY_COUNT,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName, SYSTEM_PROPERTY_DYNASTY ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_DYNASTY,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName, SYSTEM_PROPERTY_RELPATH ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_RELPATH,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName, SYSTEM_PROPERTY_PATH ) == 0 )
|
|
{
|
|
t_State = CompareString (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_PATH,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName, SYSTEM_PROPERTY_DERIVATION ) == 0 )
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined;
|
|
}
|
|
else
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//if it is time generated or time written check the max and min are ok
|
|
if ( _wcsicmp ( t_PropertyName, GENERATED_PROP ) == 0 )
|
|
{
|
|
t_State = CompareDateTime (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_PATH,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else if ( _wcsicmp ( t_PropertyName, WRITTEN_PROP ) == 0 )
|
|
{
|
|
t_State = CompareDateTime (
|
|
|
|
m_ClassObject,
|
|
SYSTEM_PROPERTY_PATH,
|
|
a_Operator,
|
|
a_Operand
|
|
);
|
|
}
|
|
else
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
t_State = QueryPreprocessor :: QuadState :: State_Undefined;
|
|
}
|
|
|
|
return t_State;
|
|
}
|
|
|
|
WmiRangeNode *ExecQueryAsyncEventObject :: AllocInfiniteRangeNode (
|
|
|
|
void *a_Context,
|
|
BSTR a_PropertyName
|
|
)
|
|
{
|
|
WmiRangeNode *t_RangeNode = NULL;
|
|
|
|
CIMTYPE t_VarType;
|
|
long t_Flavour;
|
|
VARIANT t_Variant;
|
|
VariantInit ( & t_Variant );
|
|
|
|
HRESULT t_Result = m_ClassObject->Get (
|
|
|
|
a_PropertyName,
|
|
0,
|
|
& t_Variant,
|
|
& t_VarType,
|
|
& t_Flavour
|
|
);
|
|
|
|
if ( SUCCEEDED ( t_Result ) )
|
|
{
|
|
if ( t_VarType & CIM_FLAG_ARRAY )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
switch ( t_VarType & ( ~ CIM_FLAG_ARRAY ) )
|
|
{
|
|
case CIM_BOOLEAN:
|
|
case CIM_SINT8:
|
|
case CIM_SINT16:
|
|
case CIM_CHAR16:
|
|
case CIM_SINT32:
|
|
{
|
|
t_RangeNode = new WmiSignedIntegerRangeNode (
|
|
|
|
a_PropertyName,
|
|
0xFFFFFFFF,
|
|
TRUE,
|
|
TRUE,
|
|
FALSE,
|
|
FALSE,
|
|
0,
|
|
0,
|
|
NULL,
|
|
NULL
|
|
);
|
|
}
|
|
break;
|
|
|
|
case CIM_UINT8:
|
|
case CIM_UINT16:
|
|
case CIM_UINT32:
|
|
{
|
|
t_RangeNode = new WmiUnsignedIntegerRangeNode (
|
|
|
|
a_PropertyName,
|
|
0xFFFFFFFF,
|
|
TRUE,
|
|
TRUE,
|
|
FALSE,
|
|
FALSE,
|
|
0,
|
|
0,
|
|
NULL,
|
|
NULL
|
|
);
|
|
}
|
|
break;
|
|
|
|
case CIM_SINT64:
|
|
case CIM_UINT64:
|
|
case CIM_STRING:
|
|
case CIM_DATETIME:
|
|
case CIM_REFERENCE:
|
|
{
|
|
t_RangeNode = new WmiStringRangeNode (
|
|
|
|
a_PropertyName,
|
|
0x0,
|
|
TRUE,
|
|
TRUE,
|
|
FALSE,
|
|
FALSE,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
}
|
|
break;
|
|
|
|
case CIM_REAL32:
|
|
case CIM_REAL64:
|
|
{
|
|
}
|
|
break;
|
|
|
|
case CIM_OBJECT:
|
|
case CIM_EMPTY:
|
|
{
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
VariantClear ( & t_Variant );
|
|
|
|
return t_RangeNode;
|
|
}
|
|
|
|
ULONG ExecQueryAsyncEventObject :: GetPriority ( BSTR a_PropertyName )
|
|
{
|
|
if ( _wcsicmp ( a_PropertyName, LOGFILE_PROP ) == 0 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if ( _wcsicmp ( a_PropertyName, RECORD_PROP ) == 0 )
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if ( _wcsicmp ( a_PropertyName, GENERATED_PROP ) == 0 )
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
if ( _wcsicmp ( a_PropertyName, WRITTEN_PROP ) == 0 )
|
|
{
|
|
return 3;
|
|
}
|
|
|
|
return 0xFFFFFFFF;
|
|
}
|
|
|
|
BOOL ExecQueryAsyncEventObject::CheckTime( const BSTR a_wszText, BOOL &a_IsLow, BOOL &a_IsHigh )
|
|
{
|
|
a_IsLow = FALSE;
|
|
a_IsHigh = FALSE;
|
|
|
|
if (a_wszText == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
wchar_t t_DefaultBuffer[] = {L"16010101000000.000000+000"} ;
|
|
wchar_t t_DateBuffer[ NTEVT_DMTFLEN + 1 ] ;
|
|
t_DateBuffer[ NTEVT_DMTFLEN ] = NULL ;
|
|
|
|
// wildcard cleanup and validation
|
|
// ===============================
|
|
|
|
if( NTEVT_DMTFLEN != wcslen(a_wszText) )
|
|
{
|
|
return FALSE ;
|
|
}
|
|
|
|
const wchar_t *t_pwBuffer = (const wchar_t*)a_wszText ;
|
|
|
|
for( int t_i = 0; t_i < NTEVT_DMTFLEN; t_i++ )
|
|
{
|
|
switch( a_wszText[ t_i ] )
|
|
{
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
{
|
|
// stepping on separator or sign
|
|
if( NTEVT_DECPOS == t_i || NTEVT_SGNPOS == t_i )
|
|
{
|
|
return FALSE ;
|
|
}
|
|
t_DateBuffer[ t_i ] = a_wszText[ t_i ] ;
|
|
|
|
break ;
|
|
}
|
|
case '*':
|
|
{
|
|
// stepping on separator or sign
|
|
if( NTEVT_DECPOS == t_i || NTEVT_SGNPOS == t_i )
|
|
{
|
|
return FALSE ;
|
|
}
|
|
else
|
|
{
|
|
// replace with default stamp
|
|
t_DateBuffer[ t_i ] = t_DefaultBuffer[ t_i ] ;
|
|
}
|
|
break ;
|
|
}
|
|
case '.':
|
|
{
|
|
if( NTEVT_DECPOS != t_i )
|
|
{
|
|
return FALSE ;
|
|
}
|
|
t_DateBuffer[ t_i ] = a_wszText[ t_i ] ;
|
|
|
|
break ;
|
|
}
|
|
case '+':
|
|
case '-':
|
|
{
|
|
if( NTEVT_SGNPOS != t_i )
|
|
{
|
|
return FALSE ;
|
|
}
|
|
t_DateBuffer[ t_i ] = a_wszText[ t_i ] ;
|
|
break ;
|
|
}
|
|
default:
|
|
{
|
|
return FALSE ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Parse it
|
|
// ========
|
|
|
|
int nYear, nMonth, nDay, nHour, nMinute, nSecond, nMicro, nOffset;
|
|
WCHAR wchSep;
|
|
|
|
int nRes = swscanf (
|
|
|
|
(LPCWSTR)&t_DateBuffer,
|
|
L"%4d%2d%2d%2d%2d%2d.%6d%c%3d",
|
|
&nYear,
|
|
&nMonth,
|
|
&nDay,
|
|
&nHour,
|
|
&nMinute,
|
|
&nSecond,
|
|
&nMicro,
|
|
&wchSep,
|
|
&nOffset
|
|
);
|
|
|
|
if ( ( 9 != nRes ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (nYear < 1970)
|
|
{
|
|
a_IsLow = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL retVal = FALSE;
|
|
WBEMTime t_max ((time_t)0xFFFFFFFF);
|
|
BSTR t_temp = t_max.GetBSTR();
|
|
|
|
if (t_temp)
|
|
{
|
|
if (_wcsicmp(a_wszText, t_temp) >= 0)
|
|
{
|
|
a_IsHigh = TRUE;
|
|
retVal = TRUE;
|
|
}
|
|
|
|
SysFreeString(t_temp);
|
|
}
|
|
|
|
// if we got here, the earlier WBEMTIME should have been OK so return FALSE.
|
|
return retVal;
|
|
}
|
|
|