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.

722 lines
15 KiB

  1. /*++
  2. Copyright (C) 1996-2000 Microsoft Corporation
  3. Module Name:
  4. logfiles.cpp
  5. Abstract:
  6. Implementation of the ILogFiles interface
  7. --*/
  8. #include "polyline.h"
  9. #include "unkhlpr.h"
  10. #include "unihelpr.h"
  11. #include "smonmsg.h"
  12. #include "logsrc.h"
  13. #include "logfiles.h"
  14. //Standard IUnknown implementation for contained interface
  15. IMPLEMENT_CONTAINED_CONSTRUCTOR(CPolyline, CImpILogFiles)
  16. IMPLEMENT_CONTAINED_DESTRUCTOR(CImpILogFiles)
  17. IMPLEMENT_CONTAINED_ADDREF(CImpILogFiles)
  18. IMPLEMENT_CONTAINED_RELEASE(CImpILogFiles)
  19. STDMETHODIMP
  20. CImpILogFiles::QueryInterface (
  21. IN REFIID riid,
  22. OUT PPVOID ppv
  23. )
  24. {
  25. HRESULT hr = S_OK;
  26. if (ppv == NULL) {
  27. return E_POINTER;
  28. }
  29. try {
  30. *ppv=NULL;
  31. if (IID_IUnknown == riid || IID_ILogFiles == riid) {
  32. *ppv = (LPVOID)this;
  33. AddRef();
  34. } else {
  35. hr = E_NOINTERFACE;
  36. }
  37. } catch (...) {
  38. hr = E_POINTER;
  39. }
  40. return hr;
  41. }
  42. STDMETHODIMP
  43. CImpILogFiles::GetTypeInfoCount (
  44. OUT UINT *pctInfo
  45. )
  46. {
  47. HRESULT hr = S_OK;
  48. if (pctInfo == NULL) {
  49. return E_POINTER;
  50. }
  51. try {
  52. *pctInfo = 1;
  53. } catch (...) {
  54. hr = E_POINTER;
  55. }
  56. return hr;
  57. }
  58. STDMETHODIMP
  59. CImpILogFiles::GetTypeInfo (
  60. IN UINT itInfo,
  61. IN LCID /* lcid */,
  62. OUT ITypeInfo** ppITypeInfo
  63. )
  64. {
  65. HRESULT hr = S_OK;
  66. if (ppITypeInfo == NULL) {
  67. return E_POINTER;
  68. }
  69. //
  70. // We have only one type information
  71. //
  72. if (0 != itInfo) {
  73. return TYPE_E_ELEMENTNOTFOUND;
  74. }
  75. else {
  76. try {
  77. *ppITypeInfo = NULL;
  78. //We ignore the LCID
  79. hr = m_pObj->m_pITypeLib->GetTypeInfoOfGuid(IID_ILogFiles, ppITypeInfo);
  80. } catch (...) {
  81. hr = E_POINTER;
  82. }
  83. }
  84. return hr;
  85. }
  86. STDMETHODIMP
  87. CImpILogFiles::GetIDsOfNames (
  88. IN REFIID riid,
  89. IN OLECHAR **rgszNames,
  90. IN UINT cNames,
  91. IN LCID /* lcid */,
  92. OUT DISPID *rgDispID
  93. )
  94. {
  95. HRESULT hr = DISP_E_UNKNOWNINTERFACE;
  96. ITypeInfo *pTI = NULL;
  97. if (rgDispID == NULL || rgszNames == NULL) {
  98. return E_POINTER;
  99. }
  100. if (IID_NULL == riid) {
  101. try {
  102. *rgDispID = NULL;
  103. hr = m_pObj->m_pITypeLib->GetTypeInfoOfGuid(IID_ILogFiles, &pTI);
  104. if (SUCCEEDED(hr)) {
  105. hr = DispGetIDsOfNames(pTI, rgszNames, cNames, rgDispID);
  106. pTI->Release();
  107. }
  108. } catch (...) {
  109. hr = E_POINTER;
  110. }
  111. }
  112. return hr;
  113. }
  114. /*
  115. * CImpIDispatch::Invoke
  116. *
  117. * Purpose:
  118. * Calls a method in the dispatch interface or manipulates a
  119. * property.
  120. *
  121. * Parameters:
  122. * dispID DISPID of the method or property of interest.
  123. * riid REFIID reserved, must be IID_NULL.
  124. * lcid LCID of the locale.
  125. * wFlags USHORT describing the context of the invocation.
  126. * pDispParams DISPPARAMS * to the array of arguments.
  127. * pVarResult VARIANT * in which to store the result. Is
  128. * NULL if the caller is not interested.
  129. * pExcepInfo EXCEPINFO * to exception information.
  130. * puArgErr UINT * in which to store the index of an
  131. * invalid parameter if DISP_E_TYPEMISMATCH
  132. * is returned.
  133. *
  134. * Return Value:
  135. * HRESULT NOERROR or a general error code.
  136. */
  137. STDMETHODIMP
  138. CImpILogFiles::Invoke (
  139. IN DISPID dispID,
  140. IN REFIID riid,
  141. IN LCID /* lcid */,
  142. IN USHORT wFlags,
  143. IN DISPPARAMS *pDispParams,
  144. OUT VARIANT *pVarResult,
  145. OUT EXCEPINFO *pExcepInfo,
  146. OUT UINT *puArgErr
  147. )
  148. {
  149. HRESULT hr = DISP_E_UNKNOWNINTERFACE;
  150. ITypeInfo *pTI = NULL;
  151. if ( IID_NULL == riid ) {
  152. try {
  153. hr = m_pObj->m_pITypeLib->GetTypeInfoOfGuid(IID_ILogFiles, &pTI);
  154. if (SUCCEEDED(hr)) {
  155. hr = pTI->Invoke(this,
  156. dispID,
  157. wFlags,
  158. pDispParams,
  159. pVarResult,
  160. pExcepInfo,
  161. puArgErr);
  162. pTI->Release();
  163. }
  164. } catch (...) {
  165. hr = E_POINTER;
  166. }
  167. }
  168. return hr;
  169. }
  170. STDMETHODIMP
  171. CImpILogFiles::get_Count (
  172. OUT LONG* pLong )
  173. {
  174. HRESULT hr = S_OK;
  175. if (pLong == NULL) {
  176. return E_POINTER;
  177. }
  178. try {
  179. *pLong = m_pObj->m_pCtrl->NumLogFiles();
  180. } catch (...) {
  181. hr = E_POINTER;
  182. }
  183. return hr;
  184. }
  185. STDMETHODIMP
  186. CImpILogFiles::get__NewEnum (
  187. IUnknown **ppIunk
  188. )
  189. {
  190. HRESULT hr = S_OK;
  191. CImpIEnumLogFile *pEnum = NULL;
  192. if (ppIunk == NULL) {
  193. return E_POINTER;
  194. }
  195. try {
  196. *ppIunk = NULL;
  197. pEnum = new CImpIEnumLogFile;
  198. if ( NULL != pEnum ) {
  199. hr = pEnum->Init ( m_pObj->m_pCtrl->FirstLogFile(),
  200. m_pObj->m_pCtrl->NumLogFiles() );
  201. if ( SUCCEEDED ( hr ) ) {
  202. *ppIunk = pEnum;
  203. pEnum->AddRef();
  204. //
  205. // Up to here, everything works well
  206. //
  207. }
  208. }
  209. else {
  210. hr = E_OUTOFMEMORY;
  211. }
  212. } catch (...) {
  213. hr = E_POINTER;
  214. }
  215. if (FAILED(hr) && pEnum != NULL) {
  216. delete pEnum;
  217. }
  218. return hr;
  219. }
  220. STDMETHODIMP
  221. CImpILogFiles::get_Item (
  222. IN VARIANT varIndex,
  223. OUT DILogFileItem **ppI
  224. )
  225. {
  226. HRESULT hr = S_OK;
  227. VARIANT varLoc;
  228. INT iIndex = 0;
  229. INT i;
  230. CLogFileItem *pItem = NULL;
  231. if (ppI == NULL) {
  232. return E_POINTER;
  233. }
  234. //
  235. // Try coercing index to I4
  236. //
  237. VariantInit(&varLoc);
  238. try {
  239. *ppI = NULL;
  240. #pragma warning(push)
  241. #pragma warning ( disable : 4127 )
  242. //
  243. // We use do {} while (0) here to act like a switch statement
  244. //
  245. do {
  246. hr = VariantChangeType(&varLoc, &varIndex, 0, VT_I4);
  247. if ( !SUCCEEDED (hr) ) {
  248. break;
  249. }
  250. //
  251. // Verify index is in range
  252. //
  253. iIndex = V_I4(&varLoc);
  254. if ( iIndex < 1 || iIndex > m_pObj->m_pCtrl->NumLogFiles() ) {
  255. hr = DISP_E_BADINDEX;
  256. break;
  257. }
  258. //
  259. // Traverse log file linked list to indexed item
  260. //
  261. pItem = m_pObj->m_pCtrl->FirstLogFile ();
  262. i = 1;
  263. while (i++ < iIndex && NULL != pItem ) {
  264. pItem = pItem->Next();
  265. }
  266. //
  267. // Something wrong with linked list!!
  268. //
  269. if ( NULL == pItem ) {
  270. hr = E_FAIL;
  271. break;
  272. }
  273. //
  274. // Return counter's dispatch interface
  275. //
  276. hr = pItem->QueryInterface(DIID_DILogFileItem, (PVOID*)ppI);
  277. } while (0);
  278. #pragma warning(pop)
  279. } catch (...) {
  280. hr = E_POINTER;
  281. }
  282. return hr;
  283. }
  284. STDMETHODIMP
  285. CImpILogFiles::Add (
  286. IN BSTR bstrPath,
  287. OUT DILogFileItem **ppI
  288. )
  289. {
  290. HRESULT hr = S_OK;
  291. eDataSourceTypeConstant eDataSourceType = sysmonCurrentActivity;
  292. PCLogFileItem pItem = NULL;
  293. if (ppI == NULL) {
  294. return E_POINTER;
  295. }
  296. //
  297. // Check data source type. Only add log files
  298. // when the data source is not sysmonLogFiles
  299. //
  300. hr = m_pObj->m_pCtrl->get_DataSourceType ( eDataSourceType );
  301. if ( SUCCEEDED ( hr ) ) {
  302. if ( sysmonLogFiles != eDataSourceType ) {
  303. try {
  304. *ppI = NULL;
  305. // If non-null log file path
  306. if ( NULL != bstrPath && 0 != bstrPath[0] ) {
  307. hr = m_pObj->m_pCtrl->AddSingleLogFile((LPWSTR)bstrPath, &pItem);
  308. if ( SUCCEEDED ( hr ) ) {
  309. hr = pItem->QueryInterface(DIID_DILogFileItem, (PVOID*)ppI);
  310. pItem->Release();
  311. }
  312. } else {
  313. hr = E_INVALIDARG;
  314. }
  315. } catch (...) {
  316. hr = E_POINTER;
  317. }
  318. } else {
  319. hr = SMON_STATUS_LOG_FILE_DATA_SOURCE;
  320. }
  321. }
  322. return hr;
  323. }
  324. STDMETHODIMP
  325. CImpILogFiles::Remove (
  326. IN VARIANT varIndex
  327. )
  328. {
  329. HRESULT hr;
  330. eDataSourceTypeConstant eDataSourceType = sysmonCurrentActivity;
  331. DILogFileItem* pDI = NULL;
  332. PCLogFileItem pItem = NULL;
  333. // Check data source type. Only remove log files
  334. // when the data source is not sysmonLogFiles
  335. hr = m_pObj->m_pCtrl->get_DataSourceType ( eDataSourceType );
  336. if ( SUCCEEDED ( hr ) ) {
  337. if ( sysmonLogFiles != eDataSourceType ) {
  338. // Get interface to indexed item
  339. hr = get_Item(varIndex, &pDI);
  340. if ( SUCCEEDED ( hr ) ) {
  341. // Exchange Dispatch interface for direct one
  342. hr = pDI->QueryInterface(IID_ILogFileItem, (PVOID*)&pItem);
  343. pDI->Release();
  344. if ( SUCCEEDED ( hr ) ) {
  345. assert ( NULL != pItem );
  346. // Remove the item from the control's list.
  347. m_pObj->m_pCtrl->RemoveSingleLogFile ( pItem );
  348. // Release the temp interface
  349. pItem->Release();
  350. }
  351. } else {
  352. hr = SMON_STATUS_LOG_FILE_DATA_SOURCE;
  353. }
  354. }
  355. }
  356. return hr;
  357. }
  358. CImpIEnumLogFile::CImpIEnumLogFile (
  359. void )
  360. : m_cItems ( 0 ),
  361. m_uCurrent ( 0 ),
  362. m_cRef ( 0 ),
  363. m_paLogFileItem ( NULL )
  364. {
  365. return;
  366. }
  367. HRESULT
  368. CImpIEnumLogFile::Init (
  369. PCLogFileItem pLogFileItem,
  370. INT cItems )
  371. {
  372. HRESULT hr = NOERROR;
  373. INT i;
  374. if ( cItems > 0 ) {
  375. m_paLogFileItem = (PCLogFileItem*)malloc(sizeof(PCLogFileItem) * cItems);
  376. if ( NULL != m_paLogFileItem ) {
  377. ZeroMemory(m_paLogFileItem, sizeof(PCLogFileItem) * cItems);
  378. m_cItems = cItems;
  379. for (i = 0; i < cItems; i++) {
  380. m_paLogFileItem[i] = pLogFileItem;
  381. pLogFileItem = pLogFileItem->Next();
  382. }
  383. } else {
  384. hr = E_OUTOFMEMORY;
  385. }
  386. } // No error if cItems <= 0
  387. return hr;
  388. }
  389. STDMETHODIMP
  390. CImpIEnumLogFile::QueryInterface (
  391. IN REFIID riid,
  392. OUT PVOID *ppv
  393. )
  394. {
  395. HRESULT hr = S_OK;
  396. if (ppv == NULL) {
  397. return E_POINTER;
  398. }
  399. try {
  400. *ppv = NULL;
  401. if ((riid == IID_IUnknown) || (riid == IID_IEnumVARIANT)) {
  402. *ppv = this;
  403. AddRef();
  404. } else {
  405. hr = E_NOINTERFACE;
  406. }
  407. } catch (...) {
  408. hr = E_POINTER;
  409. }
  410. return hr;
  411. }
  412. STDMETHODIMP_(ULONG)
  413. CImpIEnumLogFile::AddRef (
  414. VOID
  415. )
  416. {
  417. return ++m_cRef;
  418. }
  419. STDMETHODIMP_(ULONG)
  420. CImpIEnumLogFile::Release(
  421. VOID
  422. )
  423. {
  424. if (--m_cRef == 0) {
  425. if (m_paLogFileItem != NULL)
  426. free(m_paLogFileItem);
  427. delete this;
  428. return 0;
  429. }
  430. return m_cRef;
  431. }
  432. STDMETHODIMP
  433. CImpIEnumLogFile::Next(
  434. IN ULONG cItems,
  435. OUT VARIANT *varItem,
  436. OUT ULONG *pcReturned)
  437. {
  438. HRESULT hr = S_OK;
  439. ULONG i;
  440. ULONG cRet;
  441. if (varItem == NULL) {
  442. return E_POINTER;
  443. }
  444. try {
  445. //
  446. // Clear the return variants
  447. //
  448. for (i = 0; i < cItems; i++) {
  449. VariantInit(&varItem[i]);
  450. }
  451. //
  452. // Try to fill the caller's array
  453. //
  454. for (cRet = 0; cRet < cItems; cRet++) {
  455. // No more, return success with false
  456. if (m_uCurrent == m_cItems) {
  457. hr = S_FALSE;
  458. break;
  459. }
  460. // Get a dispatch interface for the item
  461. hr = m_paLogFileItem[m_uCurrent]->QueryInterface(DIID_DILogFileItem,
  462. (PVOID*)&V_DISPATCH(&varItem[cRet]));
  463. if (FAILED(hr))
  464. break;
  465. V_VT(&varItem[cRet]) = VT_DISPATCH;
  466. m_uCurrent++;
  467. }
  468. // If failed, clear out the variants
  469. if (FAILED(hr)) {
  470. for (i = 0; i < cItems; i++) {
  471. if (V_VT(&varItem[i]) == VT_DISPATCH) {
  472. V_DISPATCH(&varItem[i])->Release();
  473. }
  474. VariantClear(&varItem[i]);
  475. }
  476. cRet = 0;
  477. }
  478. // If desired, return number of items fetched
  479. if (pcReturned) {
  480. *pcReturned = cRet;
  481. }
  482. } catch (...) {
  483. hr = E_POINTER;
  484. }
  485. return hr;
  486. }
  487. STDMETHODIMP
  488. CImpIEnumLogFile::Skip(
  489. IN ULONG cItems
  490. )
  491. /*++
  492. Purpose:
  493. Attempt to skip over the next 'cItems' elements in the enumeration
  494. sequence.
  495. Entry:
  496. cItems = the count of elements to skip
  497. Exit:
  498. return value = HRESULT
  499. S_OK
  500. S_FALSE - the end of the sequence was reached
  501. --*/
  502. {
  503. m_uCurrent += cItems;
  504. if (m_uCurrent > m_cItems) {
  505. m_uCurrent = m_cItems;
  506. return S_FALSE;
  507. }
  508. return S_OK;
  509. }
  510. /***
  511. *HRESULT CEnumPoint::Reset(void)
  512. *Purpose:
  513. * Reset the enumeration sequence back to the beginning.
  514. *
  515. *Entry:
  516. * None
  517. *
  518. *Exit:
  519. * return value = SHRESULT CODE
  520. * S_OK
  521. *
  522. ***********************************************************************/
  523. STDMETHODIMP
  524. CImpIEnumLogFile::Reset(
  525. VOID
  526. )
  527. {
  528. m_uCurrent = 0;
  529. return S_OK;
  530. }
  531. /***
  532. *HRESULT CEnumPoint::Clone(IEnumVARIANT**)
  533. *Purpose:
  534. * Retrun a CPoint enumerator with exactly the same state as the
  535. * current one.
  536. *
  537. *Entry:
  538. * None
  539. *
  540. *Exit:
  541. * return value = HRESULT
  542. * S_OK
  543. * E_OUTOFMEMORY
  544. *
  545. ***********************************************************************/
  546. STDMETHODIMP
  547. CImpIEnumLogFile::Clone (
  548. OUT IEnumVARIANT **ppEnum
  549. )
  550. {
  551. HRESULT hr = S_OK;
  552. ULONG i;
  553. CImpIEnumLogFile *pNewEnum = NULL;
  554. if (ppEnum == NULL) {
  555. return E_POINTER;
  556. }
  557. try {
  558. *ppEnum = NULL;
  559. // Create new enumerator
  560. pNewEnum = new CImpIEnumLogFile;
  561. if ( NULL != pNewEnum ) {
  562. // Init, copy item list and current position
  563. pNewEnum->m_cItems = m_cItems;
  564. pNewEnum->m_uCurrent = m_uCurrent;
  565. pNewEnum->m_paLogFileItem = (PCLogFileItem*)malloc(sizeof(PCLogFileItem) * m_cItems);
  566. if ( NULL != pNewEnum->m_paLogFileItem ) {
  567. for (i=0; i<m_cItems; i++) {
  568. pNewEnum->m_paLogFileItem[i] = m_paLogFileItem[i];
  569. }
  570. *ppEnum = pNewEnum;
  571. } else {
  572. hr = E_OUTOFMEMORY;
  573. }
  574. } else {
  575. hr = E_OUTOFMEMORY;
  576. }
  577. } catch (...) {
  578. hr = E_POINTER;
  579. }
  580. if (FAILED(hr) && pNewEnum != NULL) {
  581. if (pNewEnum->m_paLogFileItem != NULL) {
  582. free(pNewEnum->m_paLogFileItem);
  583. }
  584. delete pNewEnum;
  585. }
  586. return hr;
  587. }