Source code of Windows XP (NT5)
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.

1646 lines
43 KiB

  1. /*++
  2. Copyright (C) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. RESYNC2.CPP
  5. Abstract:
  6. History:
  7. ivanbrug 01-Oct-2000 changed for svchost migration
  8. --*/
  9. #include "precomp.h"
  10. #include <winntsec.h>
  11. #include <malloc.h>
  12. #include <tchar.h>
  13. #include <initguid.h>
  14. #include "WinMgmt.h"
  15. #include <Wmistr.h>
  16. #include <wmium.h>
  17. #include <wmicom.h>
  18. #include <wmimof.h>
  19. #include "resync2.h"
  20. #include "wbemdelta.h" // for DeltaDredge
  21. #include "arrtempl.h"
  22. //
  23. //
  24. // this is because WDMLib is __BADLY__ DESIGNED
  25. //
  26. /////////////////////////////////////////////////////////////
  27. void WINAPI EventCallbackRoutine(PWNODE_HEADER WnodeHeader, ULONG_PTR Context)
  28. {
  29. return;
  30. }
  31. //
  32. //
  33. // This class listens on WDM events
  34. //
  35. /////////////////////////////////////////////////////////////
  36. CWDMListener::CWDMListener():
  37. m_dwSignature(SIG_WDMEVENTS_BUSY),
  38. m_hEventAdd(NULL),
  39. m_hEventRem(NULL),
  40. m_hWaitAdd(NULL),
  41. m_hWaitRem(NULL),
  42. m_UnInited(TRUE),
  43. m_GuidAdd(GUID_MOF_RESOURCE_ADDED_NOTIFICATION),
  44. m_GuidRem(GUID_MOF_RESOURCE_REMOVED_NOTIFICATION)
  45. {
  46. }
  47. DWORD
  48. CWDMListener::OpenAdd()
  49. {
  50. DWORD dwErr;
  51. dwErr = WmiOpenBlock(&m_GuidAdd,
  52. WMIGUID_NOTIFICATION | SYNCHRONIZE,
  53. &m_hEventAdd);
  54. if (ERROR_SUCCESS == dwErr)
  55. {
  56. if (RegisterWaitForSingleObject(&m_hWaitAdd,
  57. m_hEventAdd,
  58. CWDMListener::EvtCallBackAdd,
  59. this,
  60. INFINITE,
  61. WT_EXECUTEONLYONCE))
  62. {
  63. return ERROR_SUCCESS;
  64. }
  65. else
  66. {
  67. dwErr = GetLastError();
  68. }
  69. }
  70. else
  71. {
  72. dwErr = GetLastError();
  73. }
  74. // if here, some errors
  75. CloseAdd();
  76. return dwErr;
  77. }
  78. DWORD
  79. CWDMListener::OpenRemove()
  80. {
  81. DWORD dwRet;
  82. dwRet = WmiOpenBlock(&m_GuidRem,
  83. WMIGUID_NOTIFICATION | SYNCHRONIZE,
  84. &m_hEventRem);
  85. if (ERROR_SUCCESS == dwRet)
  86. {
  87. if (RegisterWaitForSingleObject(&m_hWaitRem,
  88. m_hEventRem,
  89. CWDMListener::EvtCallBackRem,
  90. this,
  91. INFINITE,
  92. WT_EXECUTEONLYONCE))
  93. {
  94. return ERROR_SUCCESS;
  95. }
  96. else
  97. {
  98. dwRet = GetLastError();
  99. }
  100. }
  101. else
  102. {
  103. dwRet = GetLastError();
  104. }
  105. CloseRemove();
  106. return dwRet;
  107. }
  108. DWORD
  109. CWDMListener::CloseAdd()
  110. {
  111. if (m_hWaitAdd){
  112. UnregisterWaitEx(m_hWaitAdd,NULL);
  113. m_hWaitAdd = NULL;
  114. }
  115. if (m_hEventAdd){
  116. WmiCloseBlock(m_hEventAdd);
  117. m_hEventAdd = NULL;
  118. }
  119. return 0;
  120. }
  121. DWORD
  122. CWDMListener::CloseRemove()
  123. {
  124. if (m_hWaitRem){
  125. UnregisterWaitEx(m_hWaitRem,NULL);
  126. m_hWaitRem = NULL;
  127. }
  128. if (m_hEventRem){
  129. WmiCloseBlock(m_hEventRem);
  130. m_hEventRem = NULL;
  131. }
  132. return 0;
  133. }
  134. VOID
  135. CWDMListener::Unregister()
  136. {
  137. CInCritSec ics(&m_cs);
  138. if (m_UnInited)
  139. return;
  140. m_UnInited = TRUE;
  141. m_dwSignature = SIG_WDMEVENTS_FREE;
  142. CloseAdd();
  143. CloseRemove();
  144. }
  145. CWDMListener::~CWDMListener()
  146. {
  147. Unregister();
  148. }
  149. DWORD
  150. CWDMListener::Register()
  151. {
  152. CInCritSec ics(&m_cs);
  153. if (!m_UnInited) // prevent multiple calls
  154. return 0;
  155. m_dwSignature = SIG_WDMEVENTS_BUSY;
  156. if (ERROR_SUCCESS == OpenAdd() && ERROR_SUCCESS == OpenRemove())
  157. {
  158. // OK here
  159. m_UnInited = FALSE;
  160. }
  161. else
  162. {
  163. m_dwSignature = SIG_WDMEVENTS_FREE;
  164. m_UnInited = TRUE;
  165. }
  166. return GetLastError();
  167. }
  168. VOID NTAPI
  169. CWDMListener::EvtCallBackAdd(VOID * pContext,BOOLEAN bTimerFired)
  170. {
  171. if (!GLOB_Monitor_IsRegistred())
  172. {
  173. return;
  174. }
  175. CWDMListener * pThis = (CWDMListener *)pContext;
  176. if (SIG_WDMEVENTS_BUSY != pThis->m_dwSignature)
  177. {
  178. return;
  179. };
  180. if (pThis)
  181. pThis->EvtCallThis(bTimerFired,Type_Added);
  182. //
  183. // we have process the WDM event
  184. // since we are in the RtlpWorkerThread and
  185. // we are registred with WT_EXECUTEONLYONCE
  186. // REDO FROM START
  187. //
  188. {
  189. CInCritSec ics(&pThis->m_cs);
  190. if (ERROR_SUCCESS == pThis->CloseAdd())
  191. {
  192. pThis->OpenAdd();
  193. }
  194. }
  195. }
  196. VOID NTAPI
  197. CWDMListener::EvtCallBackRem(VOID * pContext,BOOLEAN bTimerFired)
  198. {
  199. if (!GLOB_Monitor_IsRegistred())
  200. {
  201. return;
  202. }
  203. CWDMListener * pThis = (CWDMListener *)pContext;
  204. if (SIG_WDMEVENTS_BUSY != pThis->m_dwSignature)
  205. {
  206. return;
  207. };
  208. if (pThis)
  209. pThis->EvtCallThis(bTimerFired,Type_Removed);
  210. //
  211. // we have process the WDM event
  212. // since we are in the RtlpWorkerThread and
  213. // we are registred with WT_EXECUTEONLYONCE
  214. // REDO FROM START
  215. //
  216. {
  217. CInCritSec ics(&pThis->m_cs);
  218. if (ERROR_SUCCESS == pThis->CloseRemove())
  219. {
  220. pThis->OpenRemove();
  221. }
  222. }
  223. }
  224. VOID
  225. CWDMListener::EvtCallThis(BOOLEAN bTimerFired, int Type)
  226. {
  227. if (bTimerFired)
  228. {
  229. // never here
  230. }
  231. else
  232. {
  233. if (m_UnInited)
  234. return;
  235. DWORD dwRet;
  236. if (Type_Added == Type)
  237. {
  238. dwRet = WmiReceiveNotifications(1,&m_hEventAdd,CWDMListener::WmiCallBack,(ULONG_PTR)this);
  239. }
  240. else if (Type_Removed == Type)
  241. {
  242. dwRet = WmiReceiveNotifications(1,&m_hEventRem,CWDMListener::WmiCallBack,(ULONG_PTR)this);
  243. }
  244. }
  245. }
  246. VOID WINAPI
  247. CWDMListener::WmiCallBack(PWNODE_HEADER Wnode,
  248. UINT_PTR NotificationContext)
  249. {
  250. CWDMListener * pThis = (CWDMListener *)NotificationContext;
  251. #ifdef DEBUG_ADAP
  252. WCHAR pszClsID[40];
  253. StringFromGUID2(Wnode->Guid,pszClsID,40);
  254. DBG_PRINTFA((pBuff,"Flag %08x ProvId %08x %p GUID %S\n",
  255. Wnode->Flags,Wnode->ProviderId,(ULONG_PTR)Wnode->ClientContext,pszClsID));
  256. if (WNODE_FLAG_ALL_DATA & Wnode->Flags)
  257. {
  258. WNODE_ALL_DATA * pAllData = (WNODE_ALL_DATA *)Wnode;
  259. DWORD i;
  260. for (i=0;i<pAllData->InstanceCount;i++)
  261. {
  262. WCHAR pTmpBuff[MAX_PATH+1];
  263. pTmpBuff[MAX_PATH] = 0;
  264. DWORD dwSize = (pAllData->OffsetInstanceDataAndLength[i].LengthInstanceData>MAX_PATH)?MAX_PATH:pAllData->OffsetInstanceDataAndLength[i].LengthInstanceData;
  265. memcpy(pTmpBuff,(BYTE*)pAllData+pAllData->OffsetInstanceDataAndLength[i].OffsetInstanceData,dwSize);
  266. DBG_PRINTFA((pBuff,"%d - %S\n",i,pTmpBuff));
  267. //DEBUGTRACE((LOG_WMIADAP,"%d - %S\n",i,pTmpBuff));
  268. }
  269. };
  270. #endif
  271. #ifdef DBG
  272. if (!HeapValidate(GetProcessHeap(),0,NULL))
  273. {
  274. DebugBreak();
  275. }
  276. if (!HeapValidate(CWin32DefaultArena::GetArenaHeap(),0,NULL))
  277. {
  278. DebugBreak();
  279. }
  280. #endif
  281. CWMIBinMof WMIBinMof;
  282. //=============================================================================
  283. // Note: this combo will always succeed, as all the initialize is doing is
  284. // setting a flag to FALSE and returning S_OK
  285. //=============================================================================
  286. if( SUCCEEDED( WMIBinMof.Initialize(NULL,FALSE)) )
  287. {
  288. if (WMIBinMof.BinaryMofEventChanged(Wnode))
  289. {
  290. #ifdef DEBUG_ADAP
  291. DBG_PRINTFA((pBuff,"---- WMIBinMof.BinaryMofEventChanged == CHANGED ----\n"));
  292. #endif
  293. ERRORTRACE((LOG_WMIADAP,"WDM event && WMIBinMof.BinaryMofEventChanged == TRUE\n"));
  294. ResyncPerf(RESYNC_TYPE_WDMEVENT);
  295. #ifdef DBG
  296. if (!HeapValidate(GetProcessHeap(),0,NULL))
  297. {
  298. DebugBreak();
  299. }
  300. if (!HeapValidate(CWin32DefaultArena::GetArenaHeap(),0,NULL))
  301. {
  302. DebugBreak();
  303. }
  304. #endif
  305. }
  306. else
  307. {
  308. #ifdef DEBUG_ADAP
  309. DBG_PRINTFA((pBuff,"---- WMIBinMof.BinaryMofEventChanged == NOT CHANGED ----\n"));
  310. #endif
  311. }
  312. }
  313. return;
  314. }
  315. CCounterEvts::CCounterEvts():
  316. m_dwSignature(SIG_COUNTEEVENTS_BUSY),
  317. m_LoadCtrEvent(NULL),
  318. m_UnloadCtrEvent(NULL),
  319. m_Uninited(TRUE),
  320. m_WaitLoadCtr(NULL),
  321. m_WaitUnloadCtr(NULL),
  322. m_hWmiReverseAdapSetLodCtr(NULL),
  323. m_hWmiReverseAdapLodCtrDone(NULL),
  324. m_hPendingTasksStart(NULL),
  325. m_hPendingTasksComplete(NULL)
  326. {
  327. }
  328. DWORD g_LocalSystemSD[] = {
  329. 0x80040001, 0x00000014, 0x00000020, 0x00000000,
  330. 0x0000002c, 0x00000101, 0x05000000, 0x00000012,
  331. 0x00000101, 0x05000000, 0x00000012, 0x00300002,
  332. 0x00000001, 0x00140000, 0x001f0003, 0x00000101,
  333. 0x05000000, 0x00000012, 0x00000000, 0x00000000
  334. };
  335. //
  336. // for testing purpose, allow administrators to use the event
  337. //
  338. DWORD g_LocalSystemAdminsSD[] = {
  339. 0x80040001, 0x00000014, 0x00000020, 0x00000000,
  340. 0x0000002c, 0x00000101, 0x05000000, 0x00000012,
  341. 0x00000101, 0x05000000, 0x00000012, 0x00340002,
  342. 0x00000002, 0x00140000, 0x001f0003, 0x00000101,
  343. 0x05000000, 0x00000012, 0x00180000, 0x001f0003,
  344. 0x00000201, 0x05000000, 0x00000020, 0x00000220
  345. };
  346. DWORD
  347. CCounterEvts::Init()
  348. {
  349. if (!m_Uninited)
  350. return 0;
  351. m_LoadCtrEvent = CreateEvent(NULL, FALSE, FALSE,LOAD_CTR_EVENT_NAME);
  352. if (m_LoadCtrEvent)
  353. SetObjectAccess2(m_LoadCtrEvent);
  354. else
  355. goto end_fail;
  356. m_UnloadCtrEvent = CreateEvent(NULL, FALSE, FALSE, UNLOAD_CTR_EVENT_NAME);
  357. if (m_UnloadCtrEvent)
  358. SetObjectAccess2(m_UnloadCtrEvent);
  359. else
  360. goto end_fail;
  361. m_hWmiReverseAdapSetLodCtr = CreateEvent(NULL,FALSE,FALSE,REVERSE_DREDGE_EVENT_NAME_SET);
  362. if (m_hWmiReverseAdapSetLodCtr)
  363. SetObjectAccess2(m_hWmiReverseAdapSetLodCtr);
  364. else
  365. goto end_fail;
  366. m_hWmiReverseAdapLodCtrDone = CreateEvent(NULL,FALSE,FALSE,REVERSE_DREDGE_EVENT_NAME_ACK);
  367. if (m_hWmiReverseAdapLodCtrDone)
  368. SetObjectAccess2(m_hWmiReverseAdapLodCtrDone);
  369. else
  370. goto end_fail;
  371. SECURITY_ATTRIBUTES sa;
  372. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  373. //sa.lpSecurityDescriptor = (LPVOID)g_LocalSystemSD;
  374. // test only
  375. sa.lpSecurityDescriptor = (LPVOID)g_LocalSystemAdminsSD;
  376. sa.bInheritHandle = FALSE;
  377. m_hPendingTasksStart = CreateEvent(&sa,FALSE,FALSE,PENDING_TASK_START);
  378. if (!m_hPendingTasksStart)
  379. goto end_fail;
  380. m_hPendingTasksComplete = CreateEvent(&sa,TRUE,TRUE,PENDING_TASK_COMPLETE);
  381. if (!m_hPendingTasksComplete)
  382. goto end_fail;
  383. m_Uninited = FALSE;
  384. return NO_ERROR;
  385. end_fail:
  386. return GetLastError();
  387. }
  388. VOID NTAPI
  389. CCounterEvts::EvtCallBackLoad(VOID * pContext,BOOLEAN bTimerFired)
  390. {
  391. if (!GLOB_Monitor_IsRegistred())
  392. {
  393. return;
  394. }
  395. CCounterEvts * pCounter = (CCounterEvts *)pContext;
  396. if (SIG_COUNTEEVENTS_BUSY != pCounter->m_dwSignature)
  397. {
  398. return;
  399. }
  400. pCounter->CallBack(bTimerFired,Type_Load);
  401. }
  402. VOID NTAPI
  403. CCounterEvts::EvtCallBackUnload(VOID * pContext,BOOLEAN bTimerFired)
  404. {
  405. if (!GLOB_Monitor_IsRegistred())
  406. {
  407. return;
  408. }
  409. CCounterEvts * pCounter = (CCounterEvts *)pContext;
  410. if (SIG_COUNTEEVENTS_BUSY != pCounter->m_dwSignature)
  411. {
  412. return;
  413. }
  414. pCounter->CallBack(bTimerFired,Type_Unload);
  415. }
  416. VOID NTAPI
  417. CCounterEvts::EvtCallBackPendingTask(VOID * pContext,BOOLEAN bTimerFired)
  418. {
  419. if (!GLOB_Monitor_IsRegistred())
  420. {
  421. return;
  422. }
  423. CCounterEvts * pCounter = (CCounterEvts *)pContext;
  424. if (SIG_COUNTEEVENTS_BUSY != pCounter->m_dwSignature)
  425. {
  426. return;
  427. }
  428. pCounter->CallBackPending(bTimerFired);
  429. }
  430. VOID
  431. CCounterEvts::CallBack(BOOLEAN bTimerFired,int Type)
  432. {
  433. #ifdef DEBUG_ADAP
  434. DBG_PRINTFA((pBuff,"CallBack with type %d called\n",Type));
  435. #endif
  436. if (GLOB_IsResyncAllowed())
  437. {
  438. DWORD dwRet = WaitForSingleObject(m_hWmiReverseAdapSetLodCtr,0);
  439. if (WAIT_OBJECT_0 == dwRet)
  440. {
  441. // this is the hack not to spawn a Delta Dredge when there is before a Reverese Dredge
  442. #ifdef DEBUG_ADAP
  443. DBG_PRINTFA((pBuff," - SetEvent(m_hWmiReverseAdapLodCtrDone);\n"));
  444. #endif
  445. SetEvent(m_hWmiReverseAdapLodCtrDone);
  446. }
  447. else
  448. {
  449. #ifdef DEBUG_ADAP
  450. DBG_PRINTFA((pBuff," - ResyncPerf(RESYNC_TYPE_LODCTR);\n"));
  451. #endif
  452. ResyncPerf(RESYNC_TYPE_LODCTR);
  453. }
  454. }
  455. }
  456. VOID
  457. CCounterEvts::CallBackPending(BOOLEAN bTimerFired)
  458. {
  459. if (GLOB_IsResyncAllowed())
  460. {
  461. #ifdef DEBUG_ADAP
  462. DBG_PRINTFA((pBuff," - PendingTask Start set\n"));
  463. #endif
  464. ResyncPerf(RESYNC_TYPE_PENDING_TASKS);
  465. }
  466. }
  467. DWORD
  468. CCounterEvts::Register()
  469. {
  470. m_dwSignature = SIG_COUNTEEVENTS_BUSY;
  471. BOOL LoadUnloadOK = FALSE;
  472. if (RegisterWaitForSingleObject(&m_WaitLoadCtr,
  473. m_LoadCtrEvent,
  474. CCounterEvts::EvtCallBackLoad,
  475. this,
  476. INFINITE,
  477. WT_EXECUTEDEFAULT)) // automatic reset
  478. {
  479. if(RegisterWaitForSingleObject(&m_WaitUnloadCtr,
  480. m_UnloadCtrEvent,
  481. CCounterEvts::EvtCallBackUnload,
  482. this,
  483. INFINITE,
  484. WT_EXECUTEDEFAULT)) // automatic reset
  485. {
  486. LoadUnloadOK = TRUE;
  487. }
  488. else
  489. {
  490. UnregisterWaitEx(m_WaitLoadCtr,NULL);
  491. m_WaitLoadCtr = NULL;
  492. }
  493. }
  494. if (LoadUnloadOK &&
  495. RegisterWaitForSingleObject(&m_hWaitPendingTasksStart,
  496. m_hPendingTasksStart,
  497. CCounterEvts::EvtCallBackPendingTask,
  498. this,
  499. INFINITE,
  500. WT_EXECUTEDEFAULT))
  501. {
  502. return ERROR_SUCCESS;
  503. }
  504. else
  505. {
  506. UnregisterWaitEx(m_WaitLoadCtr,NULL);
  507. m_WaitLoadCtr = NULL;
  508. UnregisterWaitEx(m_WaitUnloadCtr,NULL);
  509. m_WaitUnloadCtr = NULL;
  510. }
  511. return GetLastError();
  512. }
  513. DWORD
  514. CCounterEvts::Unregister()
  515. {
  516. m_dwSignature = SIG_COUNTEEVENTS_FREE;
  517. if (m_WaitLoadCtr)
  518. {
  519. UnregisterWaitEx(m_WaitLoadCtr,NULL);
  520. m_WaitLoadCtr = NULL;
  521. }
  522. if (m_WaitUnloadCtr)
  523. {
  524. UnregisterWaitEx(m_WaitUnloadCtr,NULL);
  525. m_WaitUnloadCtr = NULL;
  526. }
  527. if (m_hWaitPendingTasksStart)
  528. {
  529. UnregisterWaitEx(m_hWaitPendingTasksStart,NULL);
  530. m_hWaitPendingTasksStart = NULL;
  531. }
  532. return 0;
  533. }
  534. VOID
  535. CCounterEvts::UnInit()
  536. {
  537. if (!m_Uninited)
  538. return;
  539. if(m_LoadCtrEvent) {
  540. CloseHandle(m_LoadCtrEvent);
  541. m_LoadCtrEvent = NULL;
  542. }
  543. if(m_UnloadCtrEvent)
  544. {
  545. CloseHandle(m_UnloadCtrEvent);
  546. m_UnloadCtrEvent = NULL;
  547. }
  548. if (m_hWmiReverseAdapSetLodCtr)
  549. {
  550. CloseHandle(m_hWmiReverseAdapSetLodCtr);
  551. m_hWmiReverseAdapSetLodCtr = NULL;
  552. }
  553. if (m_hWmiReverseAdapLodCtrDone)
  554. {
  555. CloseHandle(m_hWmiReverseAdapLodCtrDone);
  556. m_hWmiReverseAdapLodCtrDone = NULL;
  557. }
  558. if (m_hPendingTasksStart)
  559. {
  560. CloseHandle(m_hPendingTasksStart);
  561. m_hPendingTasksStart = NULL;
  562. }
  563. if (m_hPendingTasksComplete)
  564. {
  565. CloseHandle(m_hPendingTasksComplete);
  566. m_hPendingTasksComplete = NULL;
  567. }
  568. m_Uninited = TRUE;
  569. }
  570. CCounterEvts::~CCounterEvts()
  571. {
  572. if (!m_Uninited)
  573. UnInit();
  574. m_dwSignature = SIG_COUNTEEVENTS_FREE;
  575. }
  576. //
  577. // this is the main abstraction
  578. // the child classes will call the ResyncPerf function,
  579. // as long as the CWbemServices write hook.
  580. // The ResyncPerf function will grab the global monitor
  581. // and register a Timer Callback
  582. // the gate will be implemented in the GetAvailable function
  583. //
  584. //
  585. /////////////////////////////////////////////////////////////////////
  586. CMonitorEvents::CMonitorEvents():
  587. m_bInit(FALSE),
  588. m_bRegistred(FALSE)
  589. {
  590. InitializeCriticalSection(&m_cs);
  591. };
  592. CMonitorEvents::~CMonitorEvents()
  593. {
  594. DeleteCriticalSection(&m_cs);
  595. }
  596. BOOL WINAPI
  597. CMonitorEvents::MonitorCtrlHandler( DWORD dwCtrlType )
  598. {
  599. BOOL bRet = FALSE;
  600. switch(dwCtrlType)
  601. {
  602. case CTRL_SHUTDOWN_EVENT:
  603. GLOB_GetMonitor()->m_WDMListener.Unregister();
  604. #ifdef DEBUG_ADAP
  605. DBG_PRINTFA((pBuff,"WDM Handles closed\n"));
  606. #endif
  607. bRet = TRUE;
  608. break;
  609. default:
  610. bRet = FALSE;
  611. };
  612. return bRet;
  613. };
  614. BOOL
  615. CMonitorEvents::Init()
  616. {
  617. if (m_bInit)
  618. return TRUE;
  619. Lock();
  620. if (m_bInit)
  621. {
  622. Unlock();
  623. return TRUE;
  624. }
  625. m_dwSig = 'VEOM';
  626. m_CntsEvts.Init();
  627. m_dwADAPDelaySec = WMIADAP_DEFAULT_DELAY;
  628. m_dwLodCtrDelaySec = WMIADAP_DEFAULT_DELAY_LODCTR;
  629. m_dwTimeToFull = WMIADAP_DEFAULT_TIMETOFULL;
  630. m_dwTimeToKillAdap = MAX_PROCESS_WAIT;
  631. memset(&m_FileTime,0,sizeof(m_FileTime));
  632. RegRead();
  633. for (DWORD i=0;i<RESYNC_TYPE_MAX;i++)
  634. {
  635. m_ResyncTasks[i].dwSig = SIG_RESYNC_PERF;
  636. m_ResyncTasks[i].bFree = TRUE;
  637. m_ResyncTasks[i].pMonitor = this;
  638. m_ResyncTasks[i].hTimer = NULL;
  639. m_ResyncTasks[i].hWaitHandle = NULL;
  640. m_ResyncTasks[i].hProcess = NULL;
  641. m_ResyncTasks[i].Enabled = TRUE;
  642. }
  643. //m_ResyncTasks[RESYNC_TYPE_LODCTR].CmdType // to be decided by DeltaDredge
  644. m_ResyncTasks[RESYNC_TYPE_INITIAL].dwTimeDue = (m_dwADAPDelaySec)*1000;
  645. m_ResyncTasks[RESYNC_TYPE_LODCTR].CmdType = RESYNC_DELTA_THROTTLE;
  646. m_ResyncTasks[RESYNC_TYPE_LODCTR].dwTimeDue = (m_dwLodCtrDelaySec)*1000;
  647. // //RESYNC_TYPE_CLASSCREATION is the same
  648. m_ResyncTasks[RESYNC_TYPE_WDMEVENT].CmdType = RESYNC_RADAPD_THROTTLE;
  649. m_ResyncTasks[RESYNC_TYPE_WDMEVENT].dwTimeDue = (m_dwLodCtrDelaySec)*1000;
  650. m_ResyncTasks[RESYNC_TYPE_PENDING_TASKS].CmdType = RESYNC_FULL_RADAPD_NOTHROTTLE;
  651. m_ResyncTasks[RESYNC_TYPE_PENDING_TASKS].dwTimeDue = 500; // hard coded
  652. //
  653. // set up the console handler
  654. //
  655. SetConsoleCtrlHandler( MonitorCtrlHandler, TRUE );
  656. //
  657. // let's asses some initial state for the IdleTask business
  658. //
  659. m_OutStandingProcesses = 0;
  660. m_bFullReverseNeeded = FALSE;
  661. m_bInit = TRUE;
  662. Unlock();
  663. return TRUE;
  664. };
  665. BOOL
  666. CMonitorEvents::Uninit()
  667. {
  668. if (!m_bInit)
  669. return TRUE;
  670. Lock();
  671. if (!m_bInit)
  672. {
  673. Unlock();
  674. return TRUE;
  675. }
  676. for (DWORD i=0;i<RESYNC_TYPE_MAX;i++)
  677. {
  678. if (m_ResyncTasks[i].hTimer)
  679. {
  680. DeleteTimerQueueTimer(NULL,m_ResyncTasks[i].hTimer,NULL);
  681. m_ResyncTasks[i].hTimer = NULL;
  682. }
  683. if (m_ResyncTasks[i].hWaitHandle)
  684. {
  685. UnregisterWaitEx(m_ResyncTasks[i].hWaitHandle,NULL);
  686. m_ResyncTasks[i].hWaitHandle = NULL;
  687. }
  688. if (m_ResyncTasks[i].hProcess)
  689. {
  690. CloseHandle(m_ResyncTasks[i].hProcess);
  691. m_ResyncTasks[i].hProcess = NULL;
  692. }
  693. m_ResyncTasks[i].dwSig = (DWORD)'eerf';
  694. }
  695. m_CntsEvts.UnInit();
  696. //
  697. // tear-down the console handler
  698. //
  699. SetConsoleCtrlHandler( MonitorCtrlHandler, FALSE );
  700. m_bInit = FALSE;
  701. m_dwSig = 'veom';
  702. Unlock();
  703. return TRUE;
  704. };
  705. //
  706. //
  707. // called in the running/continue
  708. //
  709. /////////////
  710. DWORD
  711. CMonitorEvents::Register()
  712. {
  713. m_CntsEvts.Register();
  714. m_WDMListener.Register();
  715. m_bRegistred = TRUE;
  716. return 0;
  717. };
  718. //
  719. //
  720. // called in the pause/stop
  721. //
  722. //////////////////////////////////////////////////////////
  723. DWORD
  724. CMonitorEvents::Unregister(BOOL bIsSystemShutDown)
  725. {
  726. m_bRegistred = FALSE;
  727. if (!bIsSystemShutDown)
  728. {
  729. m_CntsEvts.Unregister();
  730. m_WDMListener.Unregister();
  731. }
  732. return 0;
  733. };
  734. //
  735. //
  736. //
  737. /////////////////////////////////////////////////////////
  738. VOID
  739. CMonitorEvents::RegRead()
  740. {
  741. // Read the initialization information
  742. LONG lRet;
  743. HKEY hKey;
  744. DWORD dwTemp;
  745. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  746. _T("Software\\Microsoft\\WBEM\\CIMOM"),
  747. NULL,
  748. KEY_READ|KEY_WRITE,
  749. &hKey);
  750. if (ERROR_SUCCESS == lRet)
  751. {
  752. DWORD dwType;
  753. DWORD dwSize = sizeof(DWORD);
  754. lRet = RegQueryValueEx(hKey,
  755. _T("ADAPDelay"),
  756. NULL,
  757. &dwType,
  758. (BYTE *)&m_dwADAPDelaySec,
  759. &dwSize);
  760. if (ERROR_SUCCESS == lRet)
  761. {
  762. //This is what we want
  763. }
  764. else if ( ERROR_FILE_NOT_FOUND == lRet )
  765. {
  766. dwTemp = WMIADAP_DEFAULT_DELAY;
  767. RegSetValueEx(hKey,
  768. _T("ADAPDelay"),
  769. NULL,
  770. REG_DWORD,
  771. (BYTE *)&dwTemp,
  772. sizeof(DWORD));
  773. }
  774. else
  775. {
  776. // Error
  777. ERRORTRACE( ( LOG_WINMGMT, "ResyncPerf experienced an error while attempting to read the WMIADAPDelay value in the CIMOM subkey. Continuing using a default value.\n" ) );
  778. }
  779. lRet = RegQueryValueEx(hKey,
  780. _T("LodCtrDelay"),
  781. NULL,
  782. &dwType,
  783. (BYTE *)&m_dwLodCtrDelaySec,
  784. &dwSize);
  785. if (ERROR_SUCCESS == lRet)
  786. {
  787. //This is what we want
  788. }
  789. else if ( ERROR_FILE_NOT_FOUND == lRet )
  790. {
  791. dwTemp = WMIADAP_DEFAULT_DELAY_LODCTR;
  792. RegSetValueEx(hKey,
  793. _T("LodCtrDelay"),
  794. NULL,
  795. REG_DWORD,
  796. (BYTE *)&dwTemp,
  797. sizeof(DWORD));
  798. }
  799. else
  800. {
  801. // Error
  802. ERRORTRACE( ( LOG_WINMGMT, "ResyncPerf experienced an error while attempting to read the WMIADAPDelay value in the CIMOM subkey. Continuing using a default value.\n" ) );
  803. }
  804. lRet = RegQueryValueEx(hKey,
  805. ADAP_TIME_TO_FULL,
  806. NULL,
  807. &dwType,
  808. (BYTE *)&m_dwTimeToFull,
  809. &dwSize);
  810. if (ERROR_SUCCESS == lRet)
  811. {
  812. //This is what we want
  813. }
  814. else if ( ERROR_FILE_NOT_FOUND == lRet )
  815. {
  816. dwTemp = WMIADAP_DEFAULT_TIMETOFULL;
  817. RegSetValueEx(hKey,
  818. ADAP_TIME_TO_FULL,
  819. NULL,
  820. REG_DWORD,
  821. (BYTE *)&dwTemp,
  822. sizeof(DWORD));
  823. }
  824. else
  825. {
  826. // Error
  827. ERRORTRACE( ( LOG_WINMGMT, "ResyncPerf experienced an error while attempting to read the WMIADAPDelay value in the CIMOM subkey. Continuing using a default value.\n" ) );
  828. }
  829. lRet = RegQueryValueEx(hKey,
  830. ADAP_TIME_TO_KILL_ADAP,
  831. NULL,
  832. &dwType,
  833. (BYTE *)&m_dwTimeToKillAdap,
  834. &dwSize);
  835. if (ERROR_SUCCESS == lRet)
  836. {
  837. //This is what we want
  838. }
  839. else if ( ERROR_FILE_NOT_FOUND == lRet )
  840. {
  841. dwTemp = MAX_PROCESS_WAIT;
  842. RegSetValueEx(hKey,
  843. ADAP_TIME_TO_KILL_ADAP,
  844. NULL,
  845. REG_DWORD,
  846. (BYTE *)&dwTemp,
  847. sizeof(DWORD));
  848. }
  849. else
  850. {
  851. // Error
  852. ERRORTRACE( ( LOG_WINMGMT, "ResyncPerf experienced an error while attempting to read the %S value in the CIMOM subkey. Continuing using a default value.\n",ADAP_TIME_TO_KILL_ADAP));
  853. }
  854. //ADAP_TIMESTAMP_FULL
  855. dwSize = sizeof(FILETIME);
  856. lRet = RegQueryValueEx(hKey,
  857. ADAP_TIMESTAMP_FULL,
  858. NULL,
  859. &dwType,
  860. (BYTE *)&m_FileTime,
  861. &dwSize);
  862. RegCloseKey(hKey);
  863. }
  864. else
  865. {
  866. // Error
  867. ERRORTRACE( ( LOG_WINMGMT, "ResyncPerf could not open the CIMOM subkey to read initialization data. Continuing using a default value.\n" ) );
  868. }
  869. }
  870. //
  871. //
  872. //
  873. ////////////////////////////////////////////////////////
  874. ResyncPerfTask *
  875. CMonitorEvents::GetAvailable(DWORD dwReason)
  876. {
  877. ResyncPerfTask * pPerf = NULL;
  878. EnterCriticalSection(&m_cs);
  879. if (m_ResyncTasks[dwReason].bFree)
  880. {
  881. m_ResyncTasks[dwReason].bFree = FALSE;
  882. m_ResyncTasks[dwReason].Type = dwReason;
  883. pPerf = &m_ResyncTasks[dwReason];
  884. }
  885. LeaveCriticalSection(&m_cs);
  886. return pPerf;
  887. }
  888. TCHAR * g_Strings[] = {
  889. _T("/F /T"), // FULL Throttle
  890. _T("/D /T"), // DELTA Throttle
  891. _T("/R /T"), // REVERSE_ADAPTER Throttle
  892. _T("/F /R /T"), // FULL REVERSE_ADAPTER Throttle
  893. _T("/D /R /T"), // DELTA REVERSE_ADAPTER Throttle
  894. _T("/F /R") // FULL REVERSE no Throttle
  895. };
  896. void inline DoUnThrottleDredges()
  897. {
  898. #ifdef DEBUG_ADAP
  899. DBG_PRINTFA((pBuff,"DoUnThrottleDredges\n"));
  900. #endif
  901. RegSetDWORD(HKEY_LOCAL_MACHINE,HOME_REG_PATH,DO_THROTTLE,0);
  902. return;
  903. }
  904. void inline DoThrottleDredges()
  905. {
  906. #ifdef DEBUG_ADAP
  907. DBG_PRINTFA((pBuff,"DoThrottleDredges\n"));
  908. #endif
  909. RegSetDWORD(HKEY_LOCAL_MACHINE,HOME_REG_PATH,DO_THROTTLE,1);
  910. return;
  911. }
  912. BOOL
  913. CMonitorEvents::CreateProcess_(TCHAR * pCmdLine,
  914. CMonitorEvents * pMonitor,
  915. ResyncPerfTask * pPerf)
  916. {
  917. BOOL bRes = FALSE;
  918. STARTUPINFO si;
  919. PROCESS_INFORMATION ProcInfo;
  920. memset(&si,0,sizeof(STARTUPINFO));
  921. si.cb = sizeof(STARTUPINFO);
  922. si.dwFlags = STARTF_FORCEOFFFEEDBACK;
  923. // Get the appropriate cmdline and attach the proper command line switches
  924. LPTSTR pWriteableBuff = GetWMIADAPCmdLine( 64 );
  925. CVectorDeleteMe<TCHAR> vdm( pWriteableBuff );
  926. if ( NULL == pWriteableBuff )
  927. {
  928. ERRORTRACE((LOG_WINMGMT,"Memory Allocation error spawning dredger!\n"));
  929. pMonitor->Lock();
  930. pPerf->bFree = TRUE;
  931. pMonitor->Unlock();
  932. return bRes;
  933. }
  934. #ifdef DEBUG_ADAP
  935. DBG_PRINTFA((pBuff,"Creating process: %S\n",pCmdLine));
  936. #endif
  937. DEBUGTRACE((LOG_WMIADAP,"Creating process: %S\n",pCmdLine));
  938. bRes = CreateProcess(pWriteableBuff,
  939. pCmdLine,
  940. NULL,
  941. NULL,
  942. FALSE,
  943. CREATE_NO_WINDOW,
  944. NULL,
  945. NULL,
  946. &si,
  947. &ProcInfo);
  948. if (bRes)
  949. {
  950. CloseHandle(ProcInfo.hThread);
  951. pPerf->hProcess = ProcInfo.hProcess;
  952. if (RegisterWaitForSingleObject(&pPerf->hWaitHandle,
  953. pPerf->hProcess,
  954. CMonitorEvents::EventCallBack,
  955. pPerf,
  956. pMonitor->m_dwTimeToKillAdap,
  957. WT_EXECUTEONLYONCE|WT_EXECUTEINWAITTHREAD))
  958. {
  959. //
  960. // we don't need to free the slot,
  961. // because the event callback will do that
  962. //
  963. }
  964. else
  965. {
  966. DEBUGTRACE((LOG_WMIADAP,"Unable to schedule WmiADAP process termination handler: err %d\n",GetLastError()));
  967. CloseHandle(pPerf->hProcess);
  968. pPerf->hProcess = NULL;
  969. pMonitor->Lock();
  970. pPerf->bFree = TRUE;
  971. pMonitor->Unlock();
  972. }
  973. }
  974. else
  975. {
  976. ERRORTRACE((LOG_WINMGMT,"CreatProcess %S err: %d\n",pWriteableBuff,GetLastError()));
  977. pMonitor->Lock();
  978. pPerf->bFree = TRUE;
  979. pMonitor->Unlock();
  980. }
  981. return bRes;
  982. }
  983. VOID NTAPI
  984. CMonitorEvents::EventCallBack(VOID * pContext,BOOLEAN bTimerFired)
  985. {
  986. if (!GLOB_Monitor_IsRegistred())
  987. {
  988. return;
  989. }
  990. ResyncPerfTask * pPerf = (ResyncPerfTask *)pContext;
  991. if (!pPerf || (SIG_RESYNC_PERF != pPerf->dwSig))
  992. {
  993. return;
  994. }
  995. CMonitorEvents * pMonitor = pPerf->pMonitor;
  996. HANDLE hProcess = pPerf->hProcess;
  997. if(bTimerFired)
  998. {
  999. //
  1000. // The LONG time-out for our process has expired
  1001. // Kill The Process
  1002. //
  1003. TerminateProcess(pPerf->hProcess,0);
  1004. #ifdef DEBUG_ADAP
  1005. DBG_PRINTFA((pBuff,"WmiADAP did not finish within %d msec\n",pMonitor->m_dwTimeToKillAdap));
  1006. #endif
  1007. ERRORTRACE((LOG_WMIADAP,"the ResyncTask of type %d timed-out and has been killed\n",pPerf->Type));
  1008. }
  1009. else
  1010. {
  1011. //
  1012. // the handle has been signaled, meaning that
  1013. // the process exited normally
  1014. //
  1015. #ifdef DEBUG_ADAP
  1016. DBG_PRINTFA((pBuff,"ResyncPerf for task %d completed\n",pPerf->Type));
  1017. #endif
  1018. }
  1019. CloseHandle(pPerf->hProcess);
  1020. //
  1021. // if there was a call to ProcessIdleTasks
  1022. // if we were forced to unthrottle the running tasks
  1023. // revert back
  1024. //
  1025. if (RESYNC_TYPE_PENDING_TASKS == pPerf->Type)
  1026. {
  1027. pMonitor->m_bFullReverseNeeded = FALSE;
  1028. DoThrottleDredges();
  1029. #ifdef DEBUG_ADAP
  1030. DBG_PRINTFA((pBuff,"Setting the WMI_ProcessIdleTasksComplete\n"));
  1031. #endif
  1032. if (GLOB_GetMonitor()->IsRegistred())
  1033. SetEvent(GLOB_GetMonitor()->GetTaskCompleteEvent());
  1034. }
  1035. else // a process has exited or it has been terminated
  1036. {
  1037. LONG nProc = InterlockedDecrement(&pMonitor->m_OutStandingProcesses);
  1038. #ifdef DEBUG_ADAP
  1039. DBG_PRINTFA((pBuff,"(-) Outstanding Tasks %d\n",pMonitor->m_OutStandingProcesses));
  1040. #endif
  1041. if (0 == nProc &&
  1042. pMonitor->m_bFullReverseNeeded)
  1043. {
  1044. // Create Here the process
  1045. CMonitorEvents * pMonitor = GLOB_GetMonitor();
  1046. ResyncPerfTask * pPerfTask = pMonitor->GetAvailable(RESYNC_TYPE_PENDING_TASKS);
  1047. if (pPerfTask)
  1048. {
  1049. TCHAR pCmdLine[64];
  1050. _tcscpy(pCmdLine,_T("wmiadap.exe "));
  1051. _tcscat(pCmdLine,g_Strings[pPerfTask->CmdType]);
  1052. CMonitorEvents::CreateProcess_(pCmdLine,pMonitor,pPerfTask);
  1053. }
  1054. else
  1055. {
  1056. #ifdef DEBUG_ADAP
  1057. DBG_PRINTFA((pBuff,"GetAvailable(RESYNC_TYPE_PENDING_TASKS) returned NULL\n"));
  1058. #endif
  1059. }
  1060. }
  1061. }
  1062. pPerf->hProcess = NULL;
  1063. pMonitor->Lock();
  1064. pPerf->bFree = TRUE;
  1065. pMonitor->Unlock();
  1066. UnregisterWaitEx(pPerf->hWaitHandle,NULL);
  1067. pPerf->hWaitHandle = NULL;
  1068. }
  1069. VOID NTAPI
  1070. CMonitorEvents::TimerCallBack(VOID * pContext,BOOLEAN bTimerFired)
  1071. {
  1072. if (!GLOB_Monitor_IsRegistred())
  1073. {
  1074. return;
  1075. }
  1076. if(bTimerFired)
  1077. {
  1078. ResyncPerfTask * pPerf = (ResyncPerfTask *)pContext;
  1079. CMonitorEvents * pMonitor = pPerf->pMonitor;
  1080. BOOL bFreeSlot = FALSE;
  1081. #ifdef DEBUG_ADAP
  1082. DBG_PRINTFA((pBuff,"TIMER: Command Type %x\n",pPerf->Type));
  1083. #endif
  1084. if (!pPerf->Enabled)
  1085. {
  1086. #ifdef DEBUG_ADAP
  1087. DBG_PRINTFA((pBuff,"Task %d was disabled on the fly\n",pPerf->Type));
  1088. #endif
  1089. bFreeSlot = TRUE;
  1090. goto unregister_timer;
  1091. }
  1092. BOOL bDoSomething = TRUE;
  1093. BOOL RunDeltaLogic = TRUE;
  1094. BOOL AddReverseAdapter = FALSE;
  1095. BOOL WDMTriggeredReverseAdapter = FALSE;
  1096. BOOL bDoFullSystemReverseHere = FALSE;
  1097. if (RESYNC_TYPE_PENDING_TASKS == pPerf->Type)
  1098. {
  1099. pMonitor->Lock();
  1100. // here disable tasks that are on the wait list
  1101. for (DWORD i=0;i<RESYNC_TYPE_MAX;i++)
  1102. {
  1103. if (RESYNC_TYPE_PENDING_TASKS != i)
  1104. {
  1105. if (pMonitor->m_ResyncTasks[i].hTimer)
  1106. {
  1107. #ifdef DEBUG_ADAP
  1108. DBG_PRINTFA((pBuff,"Disabling the pending task %d\n",i));
  1109. #endif
  1110. pMonitor->m_ResyncTasks[i].Enabled = FALSE;
  1111. }
  1112. }
  1113. }
  1114. pMonitor->Unlock();
  1115. // now check if the are processes running
  1116. DoUnThrottleDredges();
  1117. if (pMonitor->m_OutStandingProcesses)
  1118. {
  1119. pMonitor->m_bFullReverseNeeded = TRUE;
  1120. // no need to CreateProcess, the last outstanding process will do that
  1121. #ifdef DEBUG_ADAP
  1122. DBG_PRINTFA((pBuff,"OutStandingProcess, no CreateProcessHere\n"));
  1123. #endif
  1124. bFreeSlot = TRUE;
  1125. goto unregister_timer;
  1126. }
  1127. else // no processes outstanding, create the process now
  1128. {
  1129. bDoFullSystemReverseHere = TRUE;
  1130. #ifdef DEBUG_ADAP
  1131. DBG_PRINTFA((pBuff,"GOTO CreateProcess\n"));
  1132. #endif
  1133. goto createprocess_label;
  1134. }
  1135. }
  1136. if (RESYNC_TYPE_INITIAL == pPerf->Type )
  1137. {
  1138. // check if the Reverse Adapters need a Delta
  1139. LONG lRet;
  1140. HKEY hKey;
  1141. DWORD dwTemp;
  1142. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1143. WBEM_REG_REVERSE_KEY,
  1144. NULL,
  1145. KEY_READ|KEY_WRITE,
  1146. &hKey);
  1147. if (ERROR_SUCCESS == lRet)
  1148. {
  1149. DWORD dwType;
  1150. DWORD dwSize = sizeof(DWORD);
  1151. DWORD dwVal;
  1152. lRet = RegQueryValueEx(hKey,
  1153. WBEM_REG_REVERSE_VALUE,
  1154. NULL,
  1155. &dwType,
  1156. (BYTE *)&dwVal,
  1157. &dwSize);
  1158. // if the key is there, is NULL and it is of the right type
  1159. // OR if the key is not there
  1160. if( ERROR_SUCCESS == lRet &&
  1161. REG_DWORD == dwType &&
  1162. dwVal )
  1163. {
  1164. AddReverseAdapter = TRUE;
  1165. #ifdef DEBUG_ADAP
  1166. DBG_PRINTFA((pBuff,"\"Performance Refresh\" key set to %d\n",dwVal));
  1167. #endif
  1168. DEBUGTRACE((LOG_WMIADAP,"\"Performance Refresh\" key set to %d\n",dwVal));
  1169. }
  1170. RegCloseKey(hKey);
  1171. }
  1172. // check the WDM stuff
  1173. if (!AddReverseAdapter)
  1174. {
  1175. #ifdef DBG
  1176. if (!HeapValidate(GetProcessHeap(),0,NULL))
  1177. {
  1178. DebugBreak();
  1179. }
  1180. if (!HeapValidate(CWin32DefaultArena::GetArenaHeap(),0,NULL))
  1181. {
  1182. DebugBreak();
  1183. }
  1184. #endif
  1185. CWMIBinMof BinMof;
  1186. //=============================================================================
  1187. // Note: this combo will always succeed, as all the initialize is doing is
  1188. // setting a flag to FALSE and returning S_OK
  1189. //=============================================================================
  1190. if( SUCCEEDED( BinMof.Initialize(NULL,FALSE) ) )
  1191. {
  1192. WDMTriggeredReverseAdapter = BinMof.BinaryMofsHaveChanged();
  1193. if (WDMTriggeredReverseAdapter)
  1194. {
  1195. // override the previous decition
  1196. AddReverseAdapter = TRUE;
  1197. #ifdef DEBUG_ADAP
  1198. DBG_PRINTFA((pBuff,"BinaryMofs DO HAVE changed\n"));
  1199. #endif
  1200. DEBUGTRACE((LOG_WMIADAP,"CWMIBinMof.BinaryMofsHaveChanged == TRUE\n"));
  1201. }
  1202. #ifdef DBG
  1203. if (!HeapValidate(GetProcessHeap(),0,NULL))
  1204. {
  1205. DebugBreak();
  1206. }
  1207. if (!HeapValidate(CWin32DefaultArena::GetArenaHeap(),0,NULL))
  1208. {
  1209. DebugBreak();
  1210. }
  1211. #endif
  1212. }
  1213. }
  1214. // overrides delta with full, if the case
  1215. if (WMIADAP_DEFAULT_TIMETOFULL == pMonitor->GetFullTime())
  1216. {
  1217. // no override
  1218. }
  1219. else // read timestamp and decide
  1220. {
  1221. ULARGE_INTEGER li;
  1222. li.LowPart = pMonitor->GetTimeStamp().dwLowDateTime;
  1223. li.HighPart = pMonitor->GetTimeStamp().dwHighDateTime;
  1224. __int64 Seconds = pMonitor->GetFullTime();
  1225. Seconds *= 10000000; // number of 100ns units in 1 second
  1226. ULARGE_INTEGER liNow;
  1227. GetSystemTimeAsFileTime((FILETIME *)&liNow);
  1228. if ((li.QuadPart + Seconds) < liNow.QuadPart)
  1229. {
  1230. pPerf->CmdType = RESYNC_FULL_THROTTLE;
  1231. RunDeltaLogic = FALSE;
  1232. }
  1233. }
  1234. } // end if command type initial
  1235. if ((RESYNC_TYPE_INITIAL == pPerf->Type) && RunDeltaLogic)
  1236. {
  1237. DWORD ret = DeltaDredge2(0,NULL);
  1238. // DBG_PRINTFA((pBuff,"DeltaDredge ret %d\n",ret));
  1239. switch(ret)
  1240. {
  1241. case FULL_DREDGE:
  1242. pPerf->CmdType = RESYNC_FULL_THROTTLE;
  1243. break;
  1244. case PARTIAL_DREDGE:
  1245. pPerf->CmdType = RESYNC_DELTA_THROTTLE;
  1246. break;
  1247. case NO_DREDGE:
  1248. //
  1249. // this is the case where we do nothing
  1250. ERRORTRACE((LOG_WINMGMT,"No Dredge to run\n"));
  1251. //
  1252. bDoSomething = FALSE;
  1253. break;
  1254. default:
  1255. //
  1256. // never here
  1257. //
  1258. break;
  1259. }
  1260. #ifdef DEBUG_ADAP
  1261. DBG_PRINTFA((pBuff,"DeltaDredge() ret = %d, bDoSomething = %d \n",ret,bDoSomething));
  1262. #endif
  1263. DEBUGTRACE((LOG_WMIADAP,"DeltaDredge() ret = %d, bDoSomething = %d \n",ret,bDoSomething));
  1264. }
  1265. if (bDoSomething || AddReverseAdapter)
  1266. {
  1267. createprocess_label:
  1268. TCHAR pCmdLine[64];
  1269. _tcscpy(pCmdLine,_T("wmiadap.exe "));
  1270. if (bDoFullSystemReverseHere)
  1271. {
  1272. _tcscat(pCmdLine,g_Strings[pPerf->CmdType]);
  1273. }
  1274. else
  1275. {
  1276. if (bDoSomething && AddReverseAdapter)
  1277. {
  1278. _tcscat(pCmdLine,g_Strings[pPerf->CmdType]);
  1279. _tcscat(pCmdLine,_T(" /R"));
  1280. }
  1281. if (bDoSomething && !AddReverseAdapter)
  1282. {
  1283. _tcscat(pCmdLine,g_Strings[pPerf->CmdType]);
  1284. }
  1285. if (!bDoSomething && AddReverseAdapter)
  1286. {
  1287. _tcscat(pCmdLine,g_Strings[RESYNC_RADAPD_THROTTLE]);
  1288. }
  1289. }
  1290. CMonitorEvents::CreateProcess_(pCmdLine,pMonitor,pPerf);
  1291. if (GLOB_GetMonitor()->IsRegistred())
  1292. {
  1293. if (!bDoFullSystemReverseHere)
  1294. {
  1295. InterlockedIncrement(&(GLOB_GetMonitor()->m_OutStandingProcesses));
  1296. #ifdef DEBUG_ADAP
  1297. DBG_PRINTFA((pBuff,"(+) Outstanding Tasks %d\n",GLOB_GetMonitor()->m_OutStandingProcesses));
  1298. #endif
  1299. }
  1300. //ResetEvent(GLOB_GetMonitor()->GetTaskCompleteEvent());
  1301. }
  1302. }
  1303. else
  1304. {
  1305. pMonitor->Lock();
  1306. pPerf->bFree = TRUE;
  1307. pMonitor->Unlock();
  1308. }
  1309. unregister_timer:
  1310. if (bFreeSlot)
  1311. {
  1312. pMonitor->Lock();
  1313. pPerf->bFree = TRUE;
  1314. pMonitor->Unlock();
  1315. }
  1316. DeleteTimerQueueTimer(NULL,pPerf->hTimer,NULL);
  1317. pPerf->hTimer = NULL;
  1318. pPerf->Enabled = TRUE;
  1319. }
  1320. else
  1321. {
  1322. // never here
  1323. DebugBreak();
  1324. }
  1325. }
  1326. //
  1327. //
  1328. //
  1329. ///////////////////////////////////////////////
  1330. DWORD ResyncPerf(DWORD dwReason)
  1331. {
  1332. if(!GLOB_IsResyncAllowed())
  1333. {
  1334. ERRORTRACE((LOG_WINMGMT,"ResyncPerf disable g_fSetup or g_fDoResync\n"));
  1335. return 0;
  1336. }
  1337. ResyncPerfTask * pPerfTask = GLOB_GetMonitor()->GetAvailable(dwReason);
  1338. if (pPerfTask)
  1339. {
  1340. // here you have the slot for execution
  1341. // tell Reverse_Adapter that it's scheduled
  1342. if (RESYNC_TYPE_WDMEVENT == dwReason ||
  1343. RESYNC_TYPE_CLASSCREATION == dwReason)
  1344. {
  1345. LONG lRet;
  1346. HKEY hKey;
  1347. DWORD dwTemp;
  1348. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1349. WBEM_REG_REVERSE_KEY,
  1350. NULL,
  1351. KEY_READ|KEY_WRITE,
  1352. &hKey);
  1353. if (ERROR_SUCCESS == lRet)
  1354. {
  1355. DWORD dwType;
  1356. DWORD dwSize = sizeof(DWORD);
  1357. DWORD dwVal;
  1358. lRet = RegQueryValueEx(hKey,
  1359. WBEM_REG_REVERSE_VALUE,
  1360. NULL,
  1361. &dwType,
  1362. (BYTE *)&dwVal,
  1363. &dwSize);
  1364. // if the key is there, is NULL and it is of the right type
  1365. // OR if the key is not there
  1366. if((ERROR_SUCCESS == lRet &&
  1367. REG_DWORD == dwType &&
  1368. 0 == dwVal) ||
  1369. (ERROR_FILE_NOT_FOUND == lRet))
  1370. {
  1371. dwVal = 1;
  1372. RegSetValueEx(hKey,
  1373. WBEM_REG_REVERSE_VALUE,
  1374. 0,
  1375. REG_DWORD,
  1376. (BYTE *)&dwVal,
  1377. sizeof(DWORD));
  1378. }
  1379. RegCloseKey(hKey);
  1380. }
  1381. };
  1382. if (CreateTimerQueueTimer(&pPerfTask->hTimer,
  1383. NULL,
  1384. CMonitorEvents::TimerCallBack,
  1385. pPerfTask,
  1386. pPerfTask->dwTimeDue,
  1387. 0,
  1388. WT_EXECUTEONLYONCE|WT_EXECUTELONGFUNCTION))
  1389. {
  1390. return 0;
  1391. }
  1392. else
  1393. {
  1394. // ERRORTRACE
  1395. return GetLastError();
  1396. }
  1397. }
  1398. else
  1399. {
  1400. // no slot availables
  1401. return ERROR_BUSY;
  1402. }
  1403. }
  1404. //
  1405. //
  1406. // This function is called by the Hook installed in wbemcore
  1407. // that monitors class creation
  1408. //
  1409. ///////////////////////////////////////////
  1410. DWORD __stdcall
  1411. DredgeRA(VOID * pReserved)
  1412. {
  1413. //DBG_PRINTFA((pBuff,"Classes\n"));
  1414. return ResyncPerf(RESYNC_TYPE_CLASSCREATION);
  1415. };