Leaked source code of windows server 2003
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.

621 lines
14 KiB

  1. // EventInfo.cpp
  2. #include "precomp.h"
  3. #include "ProvInfo.h"
  4. #include "EventInfo.h"
  5. #include "NCProv.h"
  6. #include "NCProvider.h"
  7. #include <comutl.h>
  8. #define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
  9. #define DWORD_ALIGNED(x) ((DWORD)((((x) * 8) + 31) & (~31)) / 8)
  10. /////////////////////////////////////////////////////////////////////////////
  11. // CEventInfo
  12. CEventInfo::CEventInfo() :
  13. m_pPropFuncs(0)
  14. {
  15. }
  16. CEventInfo::~CEventInfo()
  17. {
  18. }
  19. BOOL GetClassQualifier(
  20. IWbemClassObject *pObj,
  21. LPCWSTR szQualifier,
  22. VARIANT *pVal)
  23. {
  24. IWbemQualifierSet *pSet = NULL;
  25. BOOL bRet = FALSE;
  26. if (SUCCEEDED(pObj->GetQualifierSet(&pSet)))
  27. {
  28. if (SUCCEEDED(pSet->Get(szQualifier, 0, pVal, NULL)))
  29. bRet = TRUE;
  30. pSet->Release();
  31. }
  32. return bRet;
  33. }
  34. BOOL GetClassPropertyQualifier(
  35. IWbemClassObject *pObj,
  36. LPCWSTR szProperty,
  37. LPCWSTR szQualifier,
  38. VARIANT *pVal)
  39. {
  40. IWbemQualifierSet *pSet = NULL;
  41. BOOL bRet = FALSE;
  42. if (SUCCEEDED(pObj->GetPropertyQualifierSet(szProperty, &pSet)))
  43. {
  44. if (SUCCEEDED(pSet->Get(szQualifier, 0, pVal, NULL)))
  45. bRet = TRUE;
  46. pSet->Release();
  47. }
  48. return bRet;
  49. }
  50. #define MAX_EVENT_PROPS 1024
  51. BOOL CEventInfo::InitFromBuffer(CClientInfo *pInfo, CBuffer *pBuffer)
  52. {
  53. WCHAR *pszEvent;
  54. DWORD nProps,
  55. dwStrSize;
  56. BOOL bRet = FALSE;
  57. m_pInfo = pInfo;
  58. // Get the number of properties for this event layout.
  59. nProps = pBuffer->ReadDWORD();
  60. if ( nProps > MAX_EVENT_PROPS )
  61. return FALSE;
  62. pszEvent = pBuffer->ReadAlignedLenString(&dwStrSize);
  63. if ( dwStrSize == 0 )
  64. return FALSE;
  65. // Prepare the array of property functions.
  66. m_pPropFuncs.Init(nProps);
  67. LPWSTR *pszProps = new LPWSTR[nProps];
  68. if (pszProps)
  69. {
  70. for (DWORD i = 0; i < nProps; i++)
  71. {
  72. DWORD type = pBuffer->ReadDWORD();
  73. DWORD dwSize;
  74. LPCWSTR szProp = pBuffer->ReadAlignedLenString(&dwSize);
  75. PROP_FUNC pFunc = TypeToPropFunc(type);
  76. if ( pFunc == NULL || !m_pPropFuncs.AddVal(pFunc) )
  77. {
  78. delete [] pszProps;
  79. return FALSE;
  80. }
  81. pszProps[i] = (BSTR) szProp;
  82. }
  83. bRet =
  84. Init(
  85. pInfo->m_pProvider->m_pProv->GetNamespace(),
  86. pszEvent,
  87. (LPCWSTR*) pszProps,
  88. nProps,
  89. FAILED_PROP_TRY_ARRAY);
  90. delete [] pszProps;
  91. }
  92. return bRet;
  93. }
  94. BOOL CEventInfo::SetPropsWithBuffer(CBuffer *pBuffer)
  95. {
  96. if (!m_pObj)
  97. return FALSE;
  98. DWORD nProps = m_pPropFuncs.GetCount();
  99. BOOL bRet = TRUE;
  100. DWORD *pNullTable = (DWORD*) pBuffer->m_pCurrent;
  101. if ( PBYTE(pNullTable + nProps/32) >
  102. (pBuffer->m_pBuffer + pBuffer->m_dwSize) )
  103. return FALSE;
  104. // We need this as the offsets are relative from the beginning
  105. // of the object packet (including the 2 DWORDs of header stuff).
  106. m_pBitsBase = (LPBYTE) (pNullTable - 3);
  107. _ASSERT( m_pBitsBase < pBuffer->m_pBuffer + pBuffer->m_dwSize );
  108. m_cBitsBase = pBuffer->m_pBuffer + pBuffer->m_dwSize - m_pBitsBase;
  109. m_pdwPropTable = pNullTable + (nProps / 32 + ((nProps % 32) != 0));
  110. if ( PBYTE(m_pdwPropTable + nProps) >
  111. (pBuffer->m_pBuffer + pBuffer->m_dwSize) )
  112. return FALSE;
  113. //
  114. // here we should be safe to use the prop table now, but the
  115. // use of bits base is checked against buffer overflow on a case by
  116. // case basis.
  117. //
  118. for (m_iCurrentVar = 0;
  119. m_iCurrentVar < nProps && bRet;
  120. m_iCurrentVar++)
  121. {
  122. if ((pNullTable[m_iCurrentVar / 32] & (1 << (m_iCurrentVar % 32))))
  123. {
  124. PROP_FUNC pFunc = m_pPropFuncs[m_iCurrentVar];
  125. _ASSERT(pFunc != NULL);
  126. bRet = (this->*pFunc)();
  127. _ASSERT(bRet);
  128. }
  129. #ifdef NO_WINMGMT
  130. else
  131. WriteNULL(m_iCurrentVar);
  132. #endif
  133. }
  134. return bRet;
  135. }
  136. PROP_FUNC CEventInfo::TypeToPropFunc(DWORD type)
  137. {
  138. PROP_FUNC pRet;
  139. BOOL bNonArray = (type & CIM_FLAG_ARRAY) == 0;
  140. switch(type & ~CIM_FLAG_ARRAY)
  141. {
  142. case CIM_STRING:
  143. case CIM_REFERENCE:
  144. case CIM_DATETIME:
  145. pRet = bNonArray ? ProcessString : ProcessStringArray;
  146. break;
  147. case CIM_UINT32:
  148. case CIM_SINT32:
  149. case CIM_REAL32:
  150. pRet = bNonArray ? ProcessDWORD : ProcessArray4;
  151. break;
  152. case CIM_UINT16:
  153. case CIM_SINT16:
  154. case CIM_CHAR16:
  155. case CIM_BOOLEAN:
  156. pRet = bNonArray ? ProcessWORD : ProcessArray2;
  157. break;
  158. case CIM_SINT8:
  159. case CIM_UINT8:
  160. pRet = bNonArray ? ProcessBYTE : ProcessArray1;
  161. break;
  162. case CIM_SINT64:
  163. case CIM_UINT64:
  164. case CIM_REAL64:
  165. pRet = bNonArray ? ProcessDWORD64 : ProcessArray8;
  166. break;
  167. case CIM_OBJECT:
  168. pRet = bNonArray ? ProcessObject : NULL;
  169. break;
  170. // We'll use this for _IWmiObjects.
  171. case CIM_IUNKNOWN:
  172. pRet = bNonArray ? ProcessWmiObject : NULL;
  173. break;
  174. default:
  175. // Bad type!
  176. _ASSERT(FALSE);
  177. pRet = NULL;
  178. }
  179. return pRet;
  180. }
  181. BOOL CEventInfo::ProcessString()
  182. {
  183. DWORD cData;
  184. LPBYTE pData = GetPropDataPointer(m_iCurrentVar, cData );
  185. if ( cData < sizeof(DWORD) )
  186. return FALSE;
  187. DWORD dwSize = *(DWORD*) pData;
  188. BOOL bRet;
  189. if ( dwSize > cData - sizeof(DWORD) )
  190. return FALSE;
  191. #ifndef NO_WINMGMT
  192. bRet = WriteData( m_iCurrentVar,
  193. pData + sizeof(DWORD),
  194. dwSize );
  195. #else
  196. bRet = TRUE;
  197. #endif
  198. return bRet;
  199. }
  200. #define MAX_ARRAY_SIZE 4096
  201. BOOL CEventInfo::ProcessStringArray()
  202. {
  203. DWORD cData;
  204. LPBYTE pData = GetPropDataPointer(m_iCurrentVar, cData);
  205. if ( cData < sizeof(DWORD) )
  206. return FALSE;
  207. DWORD nStrings = *(DWORD*) pData;
  208. BOOL bRet;
  209. VARIANT vValue;
  210. SAFEARRAYBOUND sabound;
  211. if ( nStrings > MAX_ARRAY_SIZE )
  212. return FALSE;
  213. sabound.lLbound = 0;
  214. sabound.cElements = nStrings;
  215. pData += sizeof(DWORD);
  216. cData -= sizeof(DWORD);
  217. if ((V_ARRAY(&vValue) = SafeArrayCreate(VT_BSTR, 1, &sabound)) != NULL)
  218. {
  219. BSTR *pStrings = (BSTR*) vValue.parray->pvData;
  220. vValue.vt = VT_BSTR | VT_ARRAY;
  221. for (DWORD i = 0; i < nStrings; i++)
  222. {
  223. if ( cData < sizeof(DWORD) )
  224. break;
  225. DWORD cLen = DWORD_ALIGNED(*(DWORD*)pData);
  226. pData += sizeof(DWORD);
  227. cData -= sizeof(DWORD);
  228. if ( cLen > cData )
  229. break;
  230. pStrings[i] = SysAllocString((BSTR)pData);
  231. if ( pStrings[i] == NULL )
  232. break;
  233. pData += cLen;
  234. cData -= cLen;
  235. }
  236. if ( i != nStrings )
  237. {
  238. SafeArrayDestroy(V_ARRAY(&vValue));
  239. return FALSE;
  240. }
  241. #ifndef NO_WINMGMT
  242. HRESULT hr;
  243. hr =
  244. m_pObj->Put(
  245. m_pProps[m_iCurrentVar].m_strName,
  246. 0,
  247. &vValue,
  248. 0);
  249. bRet = SUCCEEDED(hr);
  250. if (!bRet)
  251. bRet = TRUE;
  252. #else
  253. bRet = TRUE;
  254. #endif
  255. SafeArrayDestroy(V_ARRAY(&vValue));
  256. }
  257. else
  258. bRet = FALSE;
  259. return bRet;
  260. }
  261. BOOL CEventInfo::ProcessDWORD()
  262. {
  263. #ifndef NO_WINMGMT
  264. return WriteDWORD(m_iCurrentVar, m_pdwPropTable[m_iCurrentVar]);
  265. #else
  266. //m_pBuffer->ReadDWORD();
  267. return TRUE;
  268. #endif
  269. }
  270. BOOL CEventInfo::ProcessBYTE()
  271. {
  272. BYTE cData = m_pdwPropTable[m_iCurrentVar];
  273. #ifndef NO_WINMGMT
  274. return WriteData(m_iCurrentVar, &cData, sizeof(cData));
  275. #else
  276. return TRUE;
  277. #endif
  278. }
  279. BOOL CEventInfo::ProcessDWORD64()
  280. {
  281. DWORD cData;
  282. DWORD64 *pdwData = (DWORD64*) GetPropDataPointer(m_iCurrentVar,cData);
  283. if ( cData < sizeof(DWORD64) )
  284. return FALSE;
  285. #ifndef NO_WINMGMT
  286. return WriteData(m_iCurrentVar, pdwData, sizeof(*pdwData));
  287. #else
  288. return TRUE;
  289. #endif
  290. }
  291. BOOL CEventInfo::ProcessWORD()
  292. {
  293. WORD wData = m_pdwPropTable[m_iCurrentVar];
  294. #ifndef NO_WINMGMT
  295. return WriteData(m_iCurrentVar, &wData, sizeof(wData));
  296. #else
  297. return TRUE;
  298. #endif
  299. }
  300. BOOL CEventInfo::ProcessScalarArray(DWORD dwItemSize)
  301. {
  302. DWORD cBits;
  303. LPBYTE pBits = GetPropDataPointer(m_iCurrentVar,cBits);
  304. BOOL bRet;
  305. if ( cBits < sizeof(DWORD) )
  306. return FALSE;
  307. cBits -= sizeof(DWORD);
  308. if ( cBits < (*(DWORD*)pBits) * dwItemSize )
  309. return FALSE;
  310. #ifndef NO_WINMGMT
  311. bRet = WriteArrayData(m_iCurrentVar, pBits, dwItemSize);
  312. #else
  313. bRet = TRUE;
  314. #endif
  315. return bRet;
  316. }
  317. BOOL CEventInfo::ProcessArray1()
  318. {
  319. return ProcessScalarArray(1);
  320. }
  321. BOOL CEventInfo::ProcessArray2()
  322. {
  323. return ProcessScalarArray(2);
  324. }
  325. BOOL CEventInfo::ProcessArray4()
  326. {
  327. return ProcessScalarArray(4);
  328. }
  329. BOOL CEventInfo::ProcessArray8()
  330. {
  331. return ProcessScalarArray(8);
  332. }
  333. // Digs out an embedded object from the current buffer.
  334. BOOL CEventInfo::GetEmbeddedObject(IUnknown **ppObj, LPBYTE pBits, DWORD cBits )
  335. {
  336. *ppObj = NULL;
  337. CEventInfo* pEvent = new CEventInfo;
  338. if ( pEvent == NULL )
  339. return FALSE;
  340. BOOL bRet = FALSE;
  341. if ( cBits > sizeof(DWORD) )
  342. {
  343. DWORD dwSize = *(DWORD*)pBits;
  344. cBits -= sizeof(DWORD);
  345. if ( dwSize <= cBits )
  346. {
  347. CBuffer bufferObj( pBits+sizeof(DWORD),
  348. dwSize,
  349. CBuffer::ALIGN_NONE );
  350. bRet =
  351. pEvent->InitFromBuffer(m_pInfo, &bufferObj) &&
  352. pEvent->SetPropsWithBuffer(&bufferObj);
  353. }
  354. }
  355. if (bRet)
  356. {
  357. bRet =
  358. SUCCEEDED(pEvent->m_pObj->QueryInterface(
  359. IID_IUnknown, (LPVOID*) ppObj));
  360. }
  361. delete pEvent;
  362. return bRet;
  363. }
  364. BOOL CEventInfo::ProcessObject()
  365. {
  366. _variant_t vObj;
  367. BOOL bRet = FALSE;
  368. LPBYTE pObjBegin = m_pBitsBase + m_pdwPropTable[m_iCurrentVar];
  369. DWORD cObjBits = m_cBitsBase - m_pdwPropTable[m_iCurrentVar];
  370. if (GetEmbeddedObject(&vObj.punkVal, pObjBegin, cObjBits))
  371. {
  372. vObj.vt = VT_UNKNOWN;
  373. bRet =
  374. SUCCEEDED(m_pObj->Put(
  375. m_pProps[m_iCurrentVar].m_strName,
  376. 0,
  377. &vObj,
  378. 0));
  379. }
  380. return bRet;
  381. }
  382. // Digs out an embedded object from the current buffer.
  383. BOOL CEventInfo::GetWmiObject(_IWmiObject **ppObj, LPBYTE pBits, DWORD cBits )
  384. {
  385. if (m_pObjSpawner == NULL)
  386. {
  387. HRESULT hr;
  388. hr =
  389. m_pInfo->m_pProvider->m_pProv->GetNamespace()->GetObject(
  390. CWbemBSTR( L"__NAMESPACE" ),
  391. 0,
  392. NULL,
  393. (IWbemClassObject**) (_IWmiObject**) &m_pObjSpawner,
  394. NULL);
  395. if (FAILED(hr))
  396. return FALSE;
  397. }
  398. BOOL bRet = FALSE;
  399. _IWmiObject *pObjTemp = NULL;
  400. if (SUCCEEDED(m_pObjSpawner->SpawnInstance(0, (IWbemClassObject**) &pObjTemp)))
  401. {
  402. if ( cBits >= sizeof(DWORD ) )
  403. {
  404. DWORD dwSize = *(DWORD*) pBits;
  405. cBits -= sizeof(DWORD);
  406. if ( dwSize <= cBits )
  407. {
  408. LPVOID pMem = CoTaskMemAlloc(dwSize);
  409. if (pMem)
  410. {
  411. memcpy(pMem, pBits + sizeof(DWORD), dwSize);
  412. if (SUCCEEDED(pObjTemp->SetObjectMemory(pMem, dwSize)))
  413. {
  414. *ppObj = pObjTemp;
  415. bRet = TRUE;
  416. }
  417. }
  418. }
  419. }
  420. if ( !bRet )
  421. pObjTemp->Release();
  422. }
  423. return bRet;
  424. }
  425. BOOL CEventInfo::ProcessWmiObject()
  426. {
  427. BOOL bRet;
  428. LPBYTE pObjBegin = m_pBitsBase + m_pdwPropTable[m_iCurrentVar];
  429. DWORD cObjBits = m_cBitsBase - m_pdwPropTable[m_iCurrentVar];
  430. _IWmiObject *pObj = NULL;
  431. if (GetWmiObject(&pObj, pObjBegin, cObjBits))
  432. {
  433. CProp &prop = m_pProps[m_iCurrentVar];
  434. HRESULT hr;
  435. hr =
  436. m_pWmiObj->SetPropByHandle(
  437. prop.m_lHandle,
  438. 0,
  439. sizeof(_IWmiObject*),
  440. &pObj);
  441. pObj->Release();
  442. bRet = SUCCEEDED(hr);
  443. }
  444. else
  445. bRet = FALSE;
  446. return bRet;
  447. }
  448. /////////////////////////////////////////////////////////////////////////////
  449. // CEventInfoMap
  450. CEventInfoMap::~CEventInfoMap()
  451. {
  452. while (m_mapNormalEvents.size())
  453. {
  454. CNormalInfoMapIterator item = m_mapNormalEvents.begin();
  455. delete (*item).second;
  456. m_mapNormalEvents.erase(item);
  457. }
  458. }
  459. CEventInfo *CEventInfoMap::GetNormalEventInfo(DWORD dwIndex)
  460. {
  461. CEventInfo *pInfo;
  462. CNormalInfoMapIterator item = m_mapNormalEvents.find(dwIndex);
  463. if (item != m_mapNormalEvents.end())
  464. pInfo = (*item).second;
  465. else
  466. pInfo = NULL;
  467. return pInfo;
  468. }
  469. BOOL CEventInfoMap::AddNormalEventInfo(DWORD dwIndex, CEventInfo *pInfo)
  470. {
  471. m_mapNormalEvents[dwIndex] = pInfo;
  472. return TRUE;
  473. }
  474. HRESULT CEventInfo::Indicate()
  475. {
  476. HRESULT hr;
  477. hr = m_pSink->Indicate(1, &m_pObj);
  478. return hr;
  479. }