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.

1404 lines
32 KiB

  1. //***************************************************************************
  2. //
  3. // PROVTHRD.CPP
  4. //
  5. // Module: OLE MS PROVIDER FRAMEWORK
  6. //
  7. // Copyright (c) 1996-2003 Microsoft Corporation, All Rights Reserved
  8. //
  9. //***************************************************************************
  10. #include <precomp.h>
  11. #include <provimex.h>
  12. #include <provexpt.h>
  13. #include <provtempl.h>
  14. #include <strsafe.h>
  15. #include <provmt.h>
  16. #include <typeinfo.h>
  17. #include <process.h>
  18. #include <objbase.h>
  19. #include <provcont.h>
  20. #include "provevt.h"
  21. #include "provthrd.h"
  22. #include "provlog.h"
  23. #include <Allocator.cpp>
  24. #include <Algorithms.h>
  25. CStaticCriticalSection ProvThreadObject :: s_Lock ;
  26. LONG ProvThreadObject :: s_ReferenceCount = 0 ;
  27. WmiAllocator g_Allocator ;
  28. ThreadContainer ProvThreadObject :: s_ThreadContainer ( g_Allocator ) ;
  29. typedef ProvOnDelete < CRITICAL_SECTION *, VOID ( * ) ( LPCRITICAL_SECTION ), LeaveCriticalSection > LeaveCriticalSectionScope;
  30. class ProvShutdownTaskObject : public ProvTaskObject
  31. {
  32. private:
  33. ProvThreadObject *m_ThreadToShutdown ;
  34. protected:
  35. public:
  36. ProvShutdownTaskObject (ProvThreadObject *threadToShutdown) ;
  37. void Process () ;
  38. } ;
  39. ProvShutdownTaskObject :: ProvShutdownTaskObject (
  40. ProvThreadObject *threadToShutdown
  41. ) : m_ThreadToShutdown ( threadToShutdown )
  42. {
  43. }
  44. void ProvShutdownTaskObject ::Process()
  45. {
  46. if ( m_ThreadToShutdown )
  47. {
  48. m_ThreadToShutdown->SignalThreadShutdown ();
  49. }
  50. Complete();
  51. }
  52. BOOL ProvThreadObject :: Startup ()
  53. {
  54. InterlockedIncrement ( & s_ReferenceCount ) ;
  55. return TRUE ;
  56. }
  57. void ProvThreadObject :: Closedown()
  58. {
  59. #if DBG == 1
  60. if ( s_ReferenceCount == 0 )
  61. {
  62. DebugBreak ();
  63. }
  64. #endif
  65. if ( InterlockedDecrement ( & s_ReferenceCount ) <= 0 )
  66. ProcessDetach () ;
  67. }
  68. void ProvThreadObject :: ProcessAttach ()
  69. {
  70. }
  71. void ProvThreadObject :: ProcessDetach ( BOOL a_ProcessDetaching )
  72. {
  73. // delete all known thread objects
  74. s_Lock.Lock();
  75. ThreadContainerIterator t_Iterator = s_ThreadContainer.Begin () ;
  76. while ( ! t_Iterator.Null () )
  77. {
  78. s_Lock.Unlock () ;
  79. t_Iterator.GetElement ()->SignalThreadShutdown () ;
  80. s_Lock.Lock();
  81. t_Iterator = s_ThreadContainer.Begin () ;
  82. }
  83. s_ThreadContainer.UnInitialize () ;
  84. s_Lock.Unlock () ;
  85. }
  86. void ProvThreadObject :: ThreadExecutionProcedure ( void *a_ThreadParameter )
  87. {
  88. SetStructuredExceptionHandler seh;
  89. try
  90. {
  91. ProvThreadObject *t_ThreadObject = ( ProvThreadObject * ) a_ThreadParameter ;
  92. BOOL bInitialised = FALSE;
  93. try
  94. {
  95. if ( t_ThreadObject->RegisterThread () )
  96. {
  97. t_ThreadObject->Initialise () ;
  98. bInitialised = TRUE;
  99. SetEvent ( t_ThreadObject->m_ThreadInitialization ) ;
  100. DebugMacro8(
  101. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n [%s] Thread beginning dispatch") , t_ThreadObject->m_ThreadName ) ;
  102. )
  103. if ( t_ThreadObject->Wait () )
  104. {
  105. }
  106. else
  107. {
  108. }
  109. DebugMacro8(
  110. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n [%s] Thread completed dispatch") , t_ThreadObject->m_ThreadName ) ;
  111. )
  112. t_ThreadObject->Uninitialise () ;
  113. bInitialised = FALSE;
  114. DebugMacro8(
  115. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n Thread terminating") ) ;
  116. )
  117. }
  118. }
  119. catch(Structured_Exception e_SE)
  120. {
  121. t_ThreadObject->RemoveThread () ;
  122. if ( bInitialised )
  123. {
  124. DebugMacro(
  125. CNTEventProvider::g_NTEvtDebugLog->Write ( _TEXT("\n *** [%s] Thread terminating -> structured exception *** ") , t_ThreadObject->m_ThreadName ) ;
  126. )
  127. t_ThreadObject->Uninitialise () ;
  128. }
  129. return;
  130. }
  131. catch(Heap_Exception e_HE)
  132. {
  133. t_ThreadObject->RemoveThread () ;
  134. if ( bInitialised )
  135. {
  136. DebugMacro(
  137. CNTEventProvider::g_NTEvtDebugLog->Write ( _TEXT("\n *** [%s] Thread terminating -> heap exception *** ") , t_ThreadObject->m_ThreadName ) ;
  138. )
  139. t_ThreadObject->Uninitialise () ;
  140. }
  141. return;
  142. }
  143. catch(...)
  144. {
  145. t_ThreadObject->RemoveThread () ;
  146. if ( bInitialised )
  147. {
  148. DebugMacro(
  149. CNTEventProvider::g_NTEvtDebugLog->Write ( _TEXT("\n *** [%s] Thread terminating -> exception *** ") , t_ThreadObject->m_ThreadName ) ;
  150. )
  151. t_ThreadObject->Uninitialise () ;
  152. }
  153. return;
  154. }
  155. }
  156. catch ( ... )
  157. {
  158. DebugMacro(
  159. CNTEventProvider::g_NTEvtDebugLog->Write ( _TEXT("\n *** Thread terminating -> second chance exception *** ") ) ;
  160. )
  161. }
  162. }
  163. void ProvThreadObject :: TerminateThread ()
  164. {
  165. :: TerminateThread (m_ThreadHandle,0) ;
  166. }
  167. ProvThreadObject :: ProvThreadObject (
  168. const TCHAR *a_ThreadName,
  169. DWORD a_timeout
  170. ) : m_EventContainer ( NULL ) ,
  171. m_EventContainerLength ( 0 ) ,
  172. m_ThreadId ( 0 ) ,
  173. m_ThreadHandle ( 0 ) ,
  174. m_ThreadName ( NULL ) ,
  175. m_timeout ( a_timeout ),
  176. m_pShutdownTask ( NULL ) ,
  177. m_ScheduleReapContainer ( g_Allocator ) ,
  178. m_TaskQueue ( g_Allocator ) ,
  179. m_ThreadInitialization ( NULL )
  180. {
  181. if ( a_ThreadName )
  182. {
  183. m_ThreadName = _tcsdup ( a_ThreadName ) ;
  184. if( NULL == m_ThreadName) throw Heap_Exception(Heap_Exception::E_ALLOCATION_ERROR);
  185. }
  186. m_ThreadInitialization = CreateEvent ( NULL , FALSE , FALSE , NULL ) ;
  187. if ( NULL == m_ThreadInitialization) throw Heap_Exception(Heap_Exception::E_ALLOCATION_ERROR);
  188. ConstructEventContainer () ;
  189. }
  190. void ProvThreadObject :: BeginThread()
  191. {
  192. UINT_PTR t_PseudoHandle = _beginthread (
  193. ProvThreadObject :: ThreadExecutionProcedure ,
  194. 0 ,
  195. ( void * ) this
  196. ) ;
  197. s_Lock.Lock () ;
  198. LeaveCriticalSectionScope lcs ( s_Lock );
  199. if ( ( HANDLE ) t_PseudoHandle != INVALID_HANDLE_VALUE )
  200. {
  201. BOOL t_Status = DuplicateHandle (
  202. GetCurrentProcess () ,
  203. ( HANDLE ) t_PseudoHandle ,
  204. GetCurrentProcess () ,
  205. GetThreadHandleReference () ,
  206. 0 ,
  207. TRUE ,
  208. DUPLICATE_SAME_ACCESS
  209. ) ;
  210. if ( ! t_Status )
  211. {
  212. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  213. }
  214. }
  215. }
  216. BOOL ProvThreadObject :: WaitForStartup ()
  217. {
  218. DWORD dwHandles = 2;
  219. HANDLE hHandles[] =
  220. {
  221. m_ThreadInitialization,
  222. m_ThreadHandle
  223. };
  224. DWORD dwWaitResult = WAIT_TIMEOUT;
  225. dwWaitResult = WaitForMultipleObjects ( dwHandles, hHandles, FALSE, INFINITE ) ;
  226. return ( ( ( dwWaitResult - WAIT_OBJECT_0 ) == 0 ) && ( dwWaitResult != WAIT_FAILED ) );
  227. }
  228. ProvThreadObject :: ~ProvThreadObject ()
  229. {
  230. DebugMacro8(
  231. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n Enter Thread destructor") ) ;
  232. )
  233. if ( ( m_ThreadId != GetCurrentThreadId () ) && ( m_ThreadId != 0 ))
  234. {
  235. SignalThreadShutdown () ;
  236. }
  237. free ( m_ThreadName ) ;
  238. ProvAbstractTaskObject *t_TaskObject = NULL ;
  239. WmiStatusCode t_StatusCode ;
  240. while ( ( t_StatusCode = m_TaskQueue.Top ( t_TaskObject ) ) == e_StatusCode_Success )
  241. {
  242. m_TaskQueue.DeQueue () ;
  243. t_TaskObject->DetachTaskFromThread ( *this ) ;
  244. }
  245. m_TaskQueue.UnInitialize () ;
  246. free ( m_EventContainer ) ;
  247. // we should have task already deleted by SignalThreadShutdown
  248. s_Lock.Lock();
  249. s_ThreadContainer.Delete ( m_ThreadId ) ;
  250. s_Lock.Unlock () ;
  251. if ( m_ThreadInitialization )
  252. {
  253. CloseHandle ( m_ThreadInitialization ) ;
  254. }
  255. if (m_pShutdownTask != NULL)
  256. {
  257. delete m_pShutdownTask;
  258. }
  259. DebugMacro8(
  260. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n Exit Thread destructor") ) ;
  261. )
  262. }
  263. void ProvThreadObject :: PostSignalThreadShutdown ()
  264. {
  265. DebugMacro8(
  266. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n Posting thread shutdown") ) ;
  267. )
  268. if (m_pShutdownTask != NULL)
  269. {
  270. DebugMacro8(
  271. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n Thread shutdown previously posted") ) ;
  272. )
  273. }
  274. else
  275. {
  276. m_pShutdownTask = new ProvShutdownTaskObject(this);
  277. ScheduleTask(*m_pShutdownTask);
  278. m_pShutdownTask->Exec();
  279. DebugMacro8(
  280. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n Thread shutdown posted") ) ;
  281. )
  282. }
  283. }
  284. void ProvThreadObject :: SignalThreadShutdown ()
  285. {
  286. s_Lock.Lock();
  287. LeaveCriticalSectionScope lcs ( s_Lock) ;
  288. WmiStatusCode t_StatusCode = s_ThreadContainer.Delete ( m_ThreadId ) ;
  289. lcs.Exec ();
  290. if ( t_StatusCode != e_StatusCode_NotFound )
  291. {
  292. // this should be safe now
  293. if ( m_ThreadId == GetCurrentThreadId () )
  294. {
  295. m_ThreadTerminateEvent.Set () ;
  296. }
  297. else
  298. {
  299. HANDLE t_Handle = m_ThreadHandle ;
  300. m_ThreadTerminateEvent.Set () ;
  301. DWORD t_Event = WaitForSingleObject (
  302. t_Handle ,
  303. INFINITE
  304. ) ;
  305. if ( t_Event != WAIT_OBJECT_0 )
  306. {
  307. DWORD dwError = ERROR_SUCCESS;
  308. dwError = ::GetLastError ();
  309. if ( dwError != ERROR_NOT_ENOUGH_MEMORY )
  310. {
  311. #if DBG == 1
  312. // for testing purpose I will let process break
  313. ::DebugBreak();
  314. #endif
  315. }
  316. while ( ERROR_SUCCESS != dwError )
  317. {
  318. // resources will eventually come back
  319. ::Sleep ( 1000 );
  320. if ( WAIT_OBJECT_0 == WaitForSingleObject (
  321. t_Handle ,
  322. INFINITE
  323. ) )
  324. {
  325. // terminate loop
  326. dwError = ERROR_SUCCESS;
  327. }
  328. }
  329. }
  330. CloseHandle ( t_Handle ) ;
  331. }
  332. }
  333. }
  334. void ProvThreadObject :: ConstructEventContainer ()
  335. {
  336. DebugMacro8(
  337. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Constructing Container") , m_ThreadName ) ;
  338. )
  339. s_Lock.Lock();
  340. LeaveCriticalSectionScope lcs ( s_Lock ) ;
  341. BOOL bAllocated = FALSE;
  342. do
  343. {
  344. ULONG origEventContainerLength = m_EventContainerLength ;
  345. if ( ( m_TaskQueue.Size () + 2 ) < MAXIMUM_WAIT_OBJECTS )
  346. {
  347. m_EventContainerLength = m_TaskQueue.Size () + 2;
  348. }
  349. else
  350. {
  351. m_EventContainerLength = MAXIMUM_WAIT_OBJECTS - 1;
  352. }
  353. HANDLE * tempArray = ( HANDLE * ) realloc ( m_EventContainer , sizeof ( HANDLE ) * m_EventContainerLength );
  354. if ( tempArray == NULL )
  355. {
  356. //
  357. // revert the size back
  358. //
  359. m_EventContainerLength = origEventContainerLength ;
  360. s_Lock.Unlock () ;
  361. // system will eventually come back !
  362. Sleep (60000);
  363. s_Lock.Lock();
  364. }
  365. else
  366. {
  367. m_EventContainer = tempArray;
  368. bAllocated = TRUE;
  369. }
  370. }
  371. while ( ! bAllocated );
  372. m_EventContainer [ 0 ] = GetHandle () ;
  373. m_EventContainer [ 1 ] = m_ThreadTerminateEvent.GetHandle () ;
  374. ULONG t_EventIndex = 2 ;
  375. WmiStatusCode t_StatusCode ;
  376. ProvAbstractTaskObject *t_TaskObject = NULL ;
  377. while ( ( t_EventIndex < m_EventContainerLength ) && ( t_StatusCode = m_TaskQueue.Top ( t_TaskObject ) ) == e_StatusCode_Success )
  378. {
  379. t_StatusCode = m_TaskQueue.DeQueue () ;
  380. t_StatusCode = m_TaskQueue.EnQueue ( t_TaskObject ) ;
  381. m_EventContainer [ t_EventIndex ] = t_TaskObject->GetHandle () ;
  382. t_EventIndex ++ ;
  383. }
  384. }
  385. ProvThreadObject *ProvThreadObject :: GetThreadObject ()
  386. {
  387. s_Lock.Lock();
  388. LeaveCriticalSectionScope lcs ( s_Lock );
  389. DWORD t_CurrentThreadId = GetCurrentThreadId () ;
  390. ProvThreadObject *t_ThreadObject ;
  391. ThreadContainerIterator t_Iterator ;
  392. if ( s_ThreadContainer.Find ( GetCurrentThreadId () , t_Iterator ) == e_StatusCode_Success )
  393. {
  394. t_ThreadObject = t_Iterator.GetElement () ;
  395. }
  396. else
  397. {
  398. t_ThreadObject = NULL ;
  399. }
  400. return t_ThreadObject ;
  401. }
  402. ProvAbstractTaskObject *ProvThreadObject :: GetTaskObject ( HANDLE &a_Handle )
  403. {
  404. ProvAbstractTaskObject *t_TaskObject = NULL ;
  405. s_Lock.Lock();
  406. LeaveCriticalSectionScope lcs ( s_Lock );
  407. ULONG t_QueueSize = m_TaskQueue.Size () ;
  408. WmiStatusCode t_StatusCode ;
  409. while ( t_QueueSize && ( ( t_StatusCode = m_TaskQueue.Top ( t_TaskObject ) ) == e_StatusCode_Success ) )
  410. {
  411. m_TaskQueue.DeQueue () ;
  412. m_TaskQueue.EnQueue ( t_TaskObject ) ;
  413. if ( t_TaskObject->GetHandle () == a_Handle )
  414. {
  415. break ;
  416. }
  417. t_QueueSize -- ;
  418. }
  419. return t_TaskObject ;
  420. }
  421. BOOL ProvThreadObject :: RegisterThread ()
  422. {
  423. s_Lock.Lock();
  424. LeaveCriticalSectionScope lcs ( s_Lock );
  425. BOOL t_Status = FALSE ;
  426. m_ThreadId = GetCurrentThreadId () ;
  427. ThreadContainerIterator t_Iterator ;
  428. if ( s_ThreadContainer.Insert ( m_ThreadId , this , t_Iterator ) == e_StatusCode_Success )
  429. {
  430. t_Status = TRUE;
  431. }
  432. DebugMacro8(
  433. TCHAR buffer [ 1025 ] ;
  434. StringCchPrintf ( buffer , sizeof ( buffer ) / sizeof ( TCHAR ) , _TEXT("\nThread [%s] = %lx, with thread id = %lx") , m_ThreadName , (UINT_PTR)this , m_ThreadId ) ;
  435. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, buffer ) ;
  436. )
  437. return t_Status ;
  438. }
  439. BOOL ProvThreadObject :: RemoveThread ()
  440. {
  441. s_Lock.Lock();
  442. LeaveCriticalSectionScope lcs ( s_Lock );
  443. BOOL t_Status = s_ThreadContainer.Delete ( m_ThreadId ) ;
  444. if ( t_Status )
  445. {
  446. DebugMacro8(
  447. TCHAR buffer [ 1025 ] ;
  448. StringCchPrintf ( buffer , sizeof ( buffer ) / sizeof ( TCHAR ) , _TEXT("\nThread [%s] = %lx, with thread id = %lx was removed from container") , m_ThreadName , (UINT_PTR)this , m_ThreadId ) ;
  449. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, buffer ) ;
  450. )
  451. }
  452. else
  453. {
  454. DebugMacro8(
  455. TCHAR buffer [ 1025 ] ;
  456. StringCchPrintf ( buffer , sizeof ( buffer ) / sizeof ( TCHAR ) , _TEXT("\nThread [%s] = %lx, with thread id = %lx failed to remove from container") , m_ThreadName , (UINT_PTR)this , m_ThreadId ) ;
  457. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, buffer ) ;
  458. )
  459. }
  460. return t_Status ;
  461. }
  462. void ProvThreadObject :: Process ()
  463. {
  464. s_Lock.Lock();
  465. LeaveCriticalSectionScope lcs ( s_Lock );
  466. ScheduleReapContainerIterator t_Iterator = m_ScheduleReapContainer.Begin () ;
  467. while ( ! t_Iterator.Null () )
  468. {
  469. DebugMacro8(
  470. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Thread Process [%lx]") , m_ThreadName , t_Iterator.GetKey () );
  471. )
  472. t_Iterator.GetElement ()->Set () ;
  473. t_Iterator.Increment () ;
  474. }
  475. }
  476. BOOL ProvThreadObject :: WaitDispatch ( ULONG t_HandleIndex , BOOL &a_Terminated )
  477. {
  478. BOOL t_Status = TRUE ;
  479. HANDLE t_Handle = m_EventContainer [ t_HandleIndex ] ;
  480. if ( t_Handle == GetHandle () )
  481. {
  482. // Task has been scheduled so we must update arrays
  483. DebugMacro8(
  484. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Thread Wait: Refreshing handles") , m_ThreadName );
  485. )
  486. Process () ;
  487. ConstructEventContainer () ;
  488. }
  489. else if ( t_Handle == m_ThreadTerminateEvent.GetHandle () )
  490. {
  491. // thread has been told to close down
  492. a_Terminated = TRUE ;
  493. m_ThreadTerminateEvent.Process () ;
  494. DebugMacro8(
  495. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Someone t_Terminated") , m_ThreadName ) ;
  496. )
  497. }
  498. else
  499. {
  500. DebugMacro8(
  501. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Thread Wait: Processing Task") , m_ThreadName );
  502. )
  503. ProvAbstractTaskObject *t_TaskObject = GetTaskObject ( t_Handle ) ;
  504. if ( t_TaskObject )
  505. {
  506. ConstructEventContainer () ;
  507. t_TaskObject->Process () ;
  508. }
  509. else
  510. {
  511. DebugMacro8(
  512. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Couldn't Find Task Object") , m_ThreadName ) ;
  513. )
  514. t_Status = FALSE ;
  515. }
  516. }
  517. return t_Status ;
  518. }
  519. BOOL ProvThreadObject :: Wait ()
  520. {
  521. BOOL t_Status = TRUE ;
  522. BOOL t_Terminated = FALSE ;
  523. while ( t_Status && ! t_Terminated )
  524. {
  525. DWORD t_Event = MsgWaitForMultipleObjects (
  526. m_EventContainerLength ,
  527. m_EventContainer ,
  528. FALSE ,
  529. m_timeout ,
  530. QS_ALLINPUT
  531. ) ;
  532. ULONG t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  533. if ( t_Event == 0xFFFFFFFF )
  534. {
  535. DWORD t_Error = GetLastError () ;
  536. DebugMacro8(
  537. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Handle problem") , m_ThreadName ) ;
  538. )
  539. t_Status = FALSE ;
  540. }
  541. else if ( t_Event == WAIT_TIMEOUT)
  542. {
  543. TimedOut();
  544. }
  545. else if ( t_HandleIndex <= m_EventContainerLength )
  546. {
  547. // Go into dispatch loop
  548. if ( t_HandleIndex == m_EventContainerLength )
  549. {
  550. BOOL t_DispatchStatus ;
  551. MSG t_Msg ;
  552. while ( ( t_DispatchStatus = PeekMessage ( & t_Msg , NULL , 0 , 0 , PM_NOREMOVE ) ) == TRUE )
  553. {
  554. int t_Result = 0;
  555. t_Result = GetMessage ( & t_Msg , NULL , 0 , 0 );
  556. if ( t_Result != 0 && t_Result != -1 )
  557. {
  558. TranslateMessage ( & t_Msg ) ;
  559. DispatchMessage ( & t_Msg ) ;
  560. }
  561. BOOL t_Timeout = FALSE ;
  562. while ( !t_Timeout && t_Status && !t_Terminated )
  563. {
  564. t_Event = WaitForMultipleObjects (
  565. m_EventContainerLength ,
  566. m_EventContainer ,
  567. FALSE ,
  568. 0
  569. ) ;
  570. t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  571. if ( t_Event == 0xFFFFFFFF )
  572. {
  573. DWORD t_Error = GetLastError () ;
  574. DebugMacro8(
  575. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Handle problem") , m_ThreadName ) ;
  576. )
  577. t_Status = FALSE ;
  578. }
  579. else if ( t_Event == WAIT_TIMEOUT)
  580. {
  581. t_Timeout = TRUE ;
  582. }
  583. else if ( t_HandleIndex < m_EventContainerLength )
  584. {
  585. t_Status = WaitDispatch ( t_HandleIndex , t_Terminated ) ;
  586. }
  587. else
  588. {
  589. DebugMacro8(
  590. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Unknown handle index") , m_ThreadName ) ;
  591. )
  592. t_Status = FALSE ;
  593. }
  594. }
  595. }
  596. }
  597. else if ( t_HandleIndex < m_EventContainerLength )
  598. {
  599. t_Status = WaitDispatch ( t_HandleIndex , t_Terminated ) ;
  600. }
  601. else
  602. {
  603. DebugMacro8(
  604. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Unknown handle index") , m_ThreadName ) ;
  605. )
  606. t_Status = FALSE ;
  607. }
  608. }
  609. }
  610. return t_Status ;
  611. }
  612. ULONG ProvThreadObject :: GetEventHandlesSize ()
  613. {
  614. return m_EventContainerLength ;
  615. }
  616. HANDLE *ProvThreadObject :: GetEventHandles ()
  617. {
  618. return m_EventContainer ;
  619. }
  620. BOOL ProvThreadObject :: ScheduleTask ( ProvAbstractTaskObject &a_TaskObject )
  621. {
  622. BOOL t_Result = TRUE ;
  623. s_Lock.Lock();
  624. /*
  625. * Add Synchronous object to worker thread container
  626. */
  627. a_TaskObject.m_ScheduledHandle = a_TaskObject.GetHandle ();
  628. WmiStatusCode t_StatusCode = m_TaskQueue.EnQueue ( &a_TaskObject ) ;
  629. s_Lock.Unlock () ;
  630. a_TaskObject.AttachTaskToThread ( *this ) ;
  631. if ( GetCurrentThreadId () != m_ThreadId )
  632. {
  633. Set () ;
  634. }
  635. else
  636. {
  637. ConstructEventContainer () ;
  638. }
  639. return t_Result ;
  640. }
  641. BOOL ProvThreadObject :: ReapTask ( ProvAbstractTaskObject &a_TaskObject )
  642. {
  643. DebugMacro8(
  644. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Entering ReapTask [%lx]") , m_ThreadName , a_TaskObject.m_ScheduledHandle );
  645. )
  646. BOOL t_Result = TRUE ;
  647. s_Lock.Lock();
  648. /*
  649. * Remove worker object from worker thread container
  650. */
  651. ProvAbstractTaskObject *t_TaskObject = NULL ;
  652. ULONG t_QueueSize = m_TaskQueue.Size () ;
  653. WmiStatusCode t_StatusCode ;
  654. while ( t_QueueSize && ( ( t_StatusCode = m_TaskQueue.Top ( t_TaskObject ) ) == e_StatusCode_Success ) )
  655. {
  656. m_TaskQueue.DeQueue () ;
  657. if ( a_TaskObject.m_ScheduledHandle == t_TaskObject->m_ScheduledHandle )
  658. {
  659. break ;
  660. }
  661. m_TaskQueue.EnQueue ( t_TaskObject ) ;
  662. t_QueueSize -- ;
  663. }
  664. s_Lock.Unlock () ;
  665. /*
  666. * Inform worker thread,thread container has been updated.
  667. */
  668. if ( GetCurrentThreadId () != m_ThreadId )
  669. {
  670. ProvEventObject t_ReapedEventObject ;
  671. s_Lock.Lock() ;
  672. ScheduleReapContainerIterator t_Iterator ;
  673. WmiStatusCode t_StatusCode = m_ScheduleReapContainer.Insert ( t_ReapedEventObject.GetHandle () , &t_ReapedEventObject , t_Iterator ) ;
  674. s_Lock.Unlock () ;
  675. DebugMacro8(
  676. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] ReapTask: Setting update") , m_ThreadName );
  677. )
  678. Set () ;
  679. DebugMacro8(
  680. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] ReapTask: Beginning Wait on [%lx]") , m_ThreadName , t_ReapedEventObject.GetHandle () );
  681. )
  682. if ( t_ReapedEventObject.Wait () )
  683. {
  684. }
  685. else
  686. {
  687. t_Result = FALSE ;
  688. }
  689. DebugMacro8(
  690. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] ReapTask: Ended Wait") , m_ThreadName );
  691. )
  692. s_Lock.Lock();
  693. t_StatusCode = m_ScheduleReapContainer.Delete ( t_ReapedEventObject.GetHandle () ) ;
  694. s_Lock.Unlock () ;
  695. }
  696. else
  697. {
  698. DebugMacro8(
  699. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] ReapTask: ConstructEventContainer") , m_ThreadName );
  700. )
  701. ConstructEventContainer () ;
  702. }
  703. DebugMacro8(
  704. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\n[%s] Returning from ReapTask [%lx]") , m_ThreadName , a_TaskObject.m_ScheduledHandle );
  705. )
  706. a_TaskObject.DetachTaskFromThread ( *this ) ;
  707. return t_Result ;
  708. }
  709. ProvAbstractTaskObject :: ProvAbstractTaskObject (
  710. const TCHAR *a_GlobalTaskNameComplete,
  711. const TCHAR *a_GlobalTaskNameAcknowledgement,
  712. DWORD a_timeout
  713. ) : m_CompletionEvent ( a_GlobalTaskNameComplete ) ,
  714. m_AcknowledgementEvent ( a_GlobalTaskNameAcknowledgement ) ,
  715. m_timeout ( a_timeout ),
  716. m_ScheduledHandle (NULL),
  717. m_ThreadContainer (g_Allocator)
  718. {
  719. }
  720. ProvAbstractTaskObject :: ~ProvAbstractTaskObject ()
  721. {
  722. DebugMacro8(
  723. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: ~ProvAbstractTaskObject () [%lx]") , m_ScheduledHandle ) ;
  724. )
  725. m_Lock.Lock();
  726. LeaveCriticalSectionScope lcs ( m_Lock );
  727. if (NULL != m_ScheduledHandle)
  728. {
  729. ThreadContainerIterator t_Iterator = m_ThreadContainer.Begin () ;
  730. while ( ! t_Iterator.Null () )
  731. {
  732. ProvThreadObject *t_Task = t_Iterator.GetElement () ;
  733. t_Task->ReapTask ( *this ) ;
  734. t_Iterator = m_ThreadContainer.Begin () ;
  735. }
  736. }
  737. m_ThreadContainer.UnInitialize () ;
  738. }
  739. void ProvAbstractTaskObject :: DetachTaskFromThread ( ProvThreadObject &a_ThreadObject )
  740. {
  741. m_Lock.Lock();
  742. LeaveCriticalSectionScope lcs ( m_Lock );
  743. WmiStatusCode t_StatusCode = m_ThreadContainer.Delete ( a_ThreadObject.GetThreadId () ) ;
  744. }
  745. void ProvAbstractTaskObject :: AttachTaskToThread ( ProvThreadObject &a_ThreadObject )
  746. {
  747. m_Lock.Lock();
  748. LeaveCriticalSectionScope lcs ( m_Lock );
  749. ThreadContainerIterator t_Iterator ;
  750. WmiStatusCode t_StatusCode = m_ThreadContainer.Insert ( a_ThreadObject.GetThreadId () , &a_ThreadObject , t_Iterator ) ;
  751. }
  752. BOOL ProvAbstractTaskObject :: Wait ( BOOL a_Dispatch )
  753. {
  754. BOOL t_Status = TRUE ;
  755. BOOL t_Processed = FALSE ;
  756. while ( t_Status && ! t_Processed )
  757. {
  758. ProvThreadObject *t_ThreadObject = ProvThreadObject :: GetThreadObject () ;
  759. ULONG t_TaskEventArrayLength = 0 ;
  760. HANDLE *t_TaskEventArray = NULL ;
  761. if ( t_ThreadObject && a_Dispatch )
  762. {
  763. ULONG t_TaskArrayLength = t_ThreadObject->GetEventHandlesSize () ;
  764. t_TaskEventArrayLength = t_TaskArrayLength + 1 ;
  765. t_TaskEventArray = new HANDLE [ t_TaskEventArrayLength ] ;
  766. if ( t_TaskArrayLength )
  767. {
  768. memcpy (
  769. & ( t_TaskEventArray [ 1 ] ) ,
  770. t_ThreadObject->GetEventHandles () ,
  771. t_TaskArrayLength * sizeof ( HANDLE )
  772. ) ;
  773. }
  774. t_TaskEventArray [ 0 ] = m_CompletionEvent.GetHandle () ;
  775. }
  776. else
  777. {
  778. t_TaskEventArrayLength = 1 ;
  779. t_TaskEventArray = new HANDLE [ t_TaskEventArrayLength ] ;
  780. t_TaskEventArray [ 0 ] = m_CompletionEvent.GetHandle () ;
  781. }
  782. DWORD t_Event ;
  783. if ( a_Dispatch )
  784. {
  785. t_Event = MsgWaitForMultipleObjects (
  786. t_TaskEventArrayLength ,
  787. t_TaskEventArray ,
  788. FALSE ,
  789. m_timeout ,
  790. QS_ALLINPUT
  791. ) ;
  792. }
  793. else
  794. {
  795. t_Event = WaitForMultipleObjects (
  796. t_TaskEventArrayLength ,
  797. t_TaskEventArray ,
  798. FALSE ,
  799. m_timeout
  800. ) ;
  801. }
  802. ULONG t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  803. if ( t_Event == 0xFFFFFFFF )
  804. {
  805. DebugMacro8(
  806. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: Illegal Handle") ) ;
  807. )
  808. DWORD t_Error = GetLastError () ;
  809. t_Status = FALSE ;
  810. }
  811. else if ( t_Event == WAIT_TIMEOUT)
  812. {
  813. TimedOut();
  814. }
  815. else if ( t_HandleIndex == t_TaskEventArrayLength )
  816. {
  817. BOOL t_DispatchStatus ;
  818. MSG t_Msg ;
  819. while ( ( t_DispatchStatus = PeekMessage ( & t_Msg , NULL , 0 , 0 , PM_NOREMOVE ) ) == TRUE )
  820. {
  821. int t_Result = 0;
  822. t_Result = GetMessage ( & t_Msg , NULL , 0 , 0 );
  823. if ( t_Result != 0 && t_Result != -1 )
  824. {
  825. TranslateMessage ( & t_Msg ) ;
  826. DispatchMessage ( & t_Msg ) ;
  827. }
  828. BOOL t_Timeout = FALSE ;
  829. while (!t_Timeout && t_Status && !t_Processed )
  830. {
  831. t_Event = WaitForMultipleObjects (
  832. t_TaskEventArrayLength ,
  833. t_TaskEventArray ,
  834. FALSE ,
  835. 0
  836. ) ;
  837. t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  838. if ( t_Event == 0xFFFFFFFF )
  839. {
  840. DebugMacro8(
  841. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: Illegal Handle") ) ;
  842. )
  843. DWORD t_Error = GetLastError () ;
  844. t_Status = FALSE ;
  845. }
  846. else if ( t_Event == WAIT_TIMEOUT)
  847. {
  848. t_Timeout = TRUE ;
  849. }
  850. else if ( t_HandleIndex < t_TaskEventArrayLength )
  851. {
  852. HANDLE t_Handle = t_TaskEventArray [ t_HandleIndex ] ;
  853. t_Status = WaitDispatch ( t_ThreadObject , t_Handle , t_Processed ) ;
  854. }
  855. else
  856. {
  857. DebugMacro8(
  858. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: Illegal Handle index") ) ;
  859. )
  860. t_Status = FALSE ;
  861. }
  862. }
  863. }
  864. }
  865. else if ( t_HandleIndex < t_TaskEventArrayLength )
  866. {
  867. HANDLE t_Handle = t_TaskEventArray [ t_HandleIndex ] ;
  868. t_Status = WaitDispatch ( t_ThreadObject , t_Handle , t_Processed ) ;
  869. }
  870. else
  871. {
  872. DebugMacro8(
  873. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: Illegal Handle index") ) ;
  874. )
  875. t_Status = FALSE ;
  876. }
  877. delete [] t_TaskEventArray ;
  878. }
  879. return t_Status ;
  880. }
  881. BOOL ProvAbstractTaskObject :: WaitDispatch ( ProvThreadObject *a_ThreadObject, HANDLE a_Handle , BOOL &a_Processed )
  882. {
  883. BOOL t_Status = TRUE ;
  884. if ( a_Handle == m_CompletionEvent.GetHandle () )
  885. {
  886. DebugMacro8(
  887. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nWait: Completed") );
  888. )
  889. m_CompletionEvent.Process () ;
  890. a_Processed = TRUE ;
  891. }
  892. else if ( a_ThreadObject && ( a_Handle == a_ThreadObject->GetHandle () ) )
  893. {
  894. DebugMacro8(
  895. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nTask Wait: Refreshing handles") );
  896. )
  897. a_ThreadObject->Process () ;
  898. a_ThreadObject->ConstructEventContainer () ;
  899. }
  900. else
  901. {
  902. ProvAbstractTaskObject *t_TaskObject = a_ThreadObject->GetTaskObject ( a_Handle ) ;
  903. if ( t_TaskObject )
  904. {
  905. a_ThreadObject->ConstructEventContainer () ;
  906. t_TaskObject->Process () ;
  907. }
  908. else
  909. {
  910. DebugMacro8(
  911. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: Illegal Task") ) ;
  912. )
  913. t_Status = FALSE ;
  914. }
  915. }
  916. return t_Status ;
  917. }
  918. BOOL ProvAbstractTaskObject :: WaitAcknowledgement ( BOOL a_Dispatch )
  919. {
  920. BOOL t_Status = TRUE ;
  921. BOOL t_Processed = FALSE ;
  922. while ( t_Status && ! t_Processed )
  923. {
  924. ProvThreadObject *t_ThreadObject = ProvThreadObject :: GetThreadObject () ;
  925. ULONG t_TaskEventArrayLength = 0 ;
  926. HANDLE *t_TaskEventArray = NULL ;
  927. if ( t_ThreadObject && a_Dispatch )
  928. {
  929. ULONG t_TaskArrayLength = t_ThreadObject->GetEventHandlesSize () ;
  930. t_TaskEventArrayLength = t_TaskArrayLength + 1 ;
  931. t_TaskEventArray = new HANDLE [ t_TaskEventArrayLength ] ;
  932. if ( t_TaskArrayLength )
  933. {
  934. memcpy (
  935. & ( t_TaskEventArray [ 1 ] ) ,
  936. t_ThreadObject->GetEventHandles () ,
  937. t_TaskArrayLength * sizeof ( HANDLE )
  938. ) ;
  939. }
  940. t_TaskEventArray [ 0 ] = m_AcknowledgementEvent.GetHandle () ;
  941. }
  942. else
  943. {
  944. t_TaskEventArrayLength = 1 ;
  945. t_TaskEventArray = new HANDLE [ t_TaskEventArrayLength ] ;
  946. t_TaskEventArray [ 0 ] = m_AcknowledgementEvent.GetHandle () ;
  947. }
  948. DWORD t_Event ;
  949. if ( a_Dispatch )
  950. {
  951. t_Event = MsgWaitForMultipleObjects (
  952. t_TaskEventArrayLength ,
  953. t_TaskEventArray ,
  954. FALSE ,
  955. m_timeout ,
  956. QS_ALLINPUT
  957. ) ;
  958. }
  959. else
  960. {
  961. t_Event = WaitForMultipleObjects (
  962. t_TaskEventArrayLength ,
  963. t_TaskEventArray ,
  964. FALSE ,
  965. m_timeout
  966. ) ;
  967. }
  968. ULONG t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  969. if ( t_Event == 0xFFFFFFFF )
  970. {
  971. DebugMacro8(
  972. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: Illegal Handle") ) ;
  973. )
  974. DWORD t_Error = GetLastError () ;
  975. t_Status = FALSE ;
  976. }
  977. else if ( t_Event == WAIT_TIMEOUT)
  978. {
  979. TimedOut();
  980. }
  981. if ( t_HandleIndex == t_TaskEventArrayLength )
  982. {
  983. BOOL t_DispatchStatus ;
  984. MSG t_Msg ;
  985. while ( ( t_DispatchStatus = PeekMessage ( & t_Msg , NULL , 0 , 0 , PM_NOREMOVE ) ) == TRUE )
  986. {
  987. int t_Result = 0;
  988. t_Result = GetMessage ( & t_Msg , NULL , 0 , 0 );
  989. if ( t_Result != 0 && t_Result != -1 )
  990. {
  991. TranslateMessage ( & t_Msg ) ;
  992. DispatchMessage ( & t_Msg ) ;
  993. }
  994. BOOL t_Timeout = FALSE ;
  995. while ( !t_Timeout && t_Status && !t_Processed )
  996. {
  997. t_Event = WaitForMultipleObjects (
  998. t_TaskEventArrayLength ,
  999. t_TaskEventArray ,
  1000. FALSE ,
  1001. 0
  1002. ) ;
  1003. ULONG t_HandleIndex = t_Event - WAIT_OBJECT_0 ;
  1004. if ( t_Event == 0xFFFFFFFF )
  1005. {
  1006. DebugMacro8(
  1007. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: Illegal Handle") ) ;
  1008. )
  1009. DWORD t_Error = GetLastError () ;
  1010. t_Status = FALSE ;
  1011. }
  1012. else if ( t_Event == WAIT_TIMEOUT)
  1013. {
  1014. t_Timeout = TRUE ;
  1015. }
  1016. else if ( t_HandleIndex < t_TaskEventArrayLength )
  1017. {
  1018. HANDLE t_Handle = t_TaskEventArray [ t_HandleIndex ] ;
  1019. t_Status = WaitAcknowledgementDispatch ( t_ThreadObject , t_Handle , t_Processed ) ;
  1020. }
  1021. else
  1022. {
  1023. DebugMacro8(
  1024. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: Illegal Handle index") ) ;
  1025. )
  1026. t_Status = FALSE ;
  1027. }
  1028. }
  1029. }
  1030. }
  1031. else if ( t_HandleIndex < t_TaskEventArrayLength )
  1032. {
  1033. HANDLE t_Handle = t_TaskEventArray [ t_HandleIndex ] ;
  1034. t_Status = WaitAcknowledgementDispatch ( t_ThreadObject , t_Handle , t_Processed ) ;
  1035. }
  1036. else
  1037. {
  1038. DebugMacro8(
  1039. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: Illegal Handle index") ) ;
  1040. )
  1041. t_Status = FALSE ;
  1042. }
  1043. delete [] t_TaskEventArray ;
  1044. }
  1045. return t_Status ;
  1046. }
  1047. BOOL ProvAbstractTaskObject :: WaitAcknowledgementDispatch ( ProvThreadObject *a_ThreadObject , HANDLE a_Handle , BOOL &a_Processed )
  1048. {
  1049. BOOL t_Status = TRUE ;
  1050. if ( a_Handle == m_AcknowledgementEvent.GetHandle () )
  1051. {
  1052. DebugMacro8(
  1053. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nWait: Completed") );
  1054. )
  1055. m_AcknowledgementEvent.Process () ;
  1056. a_Processed = TRUE ;
  1057. }
  1058. else if ( a_ThreadObject && ( a_Handle == a_ThreadObject->GetHandle () ) )
  1059. {
  1060. DebugMacro8(
  1061. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nTask Wait: Refreshing handles") );
  1062. )
  1063. a_ThreadObject->Process () ;
  1064. a_ThreadObject->ConstructEventContainer () ;
  1065. }
  1066. else
  1067. {
  1068. ProvAbstractTaskObject *t_TaskObject = a_ThreadObject->GetTaskObject ( a_Handle ) ;
  1069. if ( t_TaskObject )
  1070. {
  1071. a_ThreadObject->ConstructEventContainer () ;
  1072. t_TaskObject->Process () ;
  1073. }
  1074. else
  1075. {
  1076. DebugMacro8(
  1077. CNTEventProvider::g_NTEvtDebugLog->WriteFileAndLine ( _TEXT(__FILE__),__LINE__, _TEXT("\nProvAbstractTaskObject :: Illegal Task") ) ;
  1078. )
  1079. t_Status = FALSE ;
  1080. }
  1081. }
  1082. return t_Status ;
  1083. }
  1084. ProvTaskObject::ProvTaskObject (
  1085. const TCHAR *a_GlobalTaskNameStart,
  1086. const TCHAR *a_GlobalTaskNameComplete ,
  1087. const TCHAR *a_GlobalTaskNameAcknowledge,
  1088. DWORD a_timeout
  1089. ): ProvAbstractTaskObject(a_GlobalTaskNameComplete, a_GlobalTaskNameAcknowledge,a_timeout), m_Event(a_GlobalTaskNameStart)
  1090. {
  1091. }