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.

2273 lines
56 KiB

  1. /*++
  2. Copyright (C) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. winmgmt.cpp
  5. Abstract:
  6. the Service main function, initialization routines, ecc
  7. --*/
  8. #include "precomp.h"
  9. #include <winsvc.h>
  10. #include <persistcfg.h>
  11. #include <winntsec.h>
  12. #include "cntserv.h"
  13. #include "winmgmt.h"
  14. #include "sched.h"
  15. #include "resync2.h"
  16. #include <delayimp.h>
  17. #include <malloc.h>
  18. #include <map>
  19. #include "wstlallc.h"
  20. //
  21. // Defines
  22. //
  23. //***********************************************************************
  24. #define CORE_PROVIDER_UNLOAD_TIMEOUT ( 30 * 1000 )
  25. //***********************************************************************
  26. //
  27. // Globals
  28. //
  29. //***********************************************************************
  30. HINSTANCE g_hInstance;
  31. //***********************************************************************
  32. //
  33. // Dll Entry points and export points
  34. //
  35. //***********************************************************************
  36. BOOL APIENTRY DllMain( HINSTANCE hModule,
  37. DWORD ul_reason_for_call,
  38. LPVOID lpReserved
  39. )
  40. {
  41. BOOL bRet = TRUE;
  42. switch(ul_reason_for_call)
  43. {
  44. case DLL_PROCESS_ATTACH:
  45. g_hInstance = hModule;
  46. DisableThreadLibraryCalls(hModule);
  47. bRet = CStaticCritSec::anyFailure()?FALSE:TRUE;
  48. break;
  49. case DLL_PROCESS_DETACH:
  50. break;
  51. }
  52. return bRet;
  53. };
  54. //
  55. //
  56. // InitialBreak
  57. //
  58. ///////////////////////////////////////////////////////////
  59. BOOL
  60. InitialBreak()
  61. {
  62. HKEY hKey;
  63. LONG lRet;
  64. BOOL bRet = FALSE;
  65. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  66. HOME_REG_PATH,
  67. 0,
  68. KEY_READ,
  69. &hKey);
  70. if (ERROR_SUCCESS == lRet)
  71. {
  72. DWORD dwType;
  73. DWORD dwVal;
  74. DWORD dwSize = sizeof(DWORD);
  75. lRet = RegQueryValueEx(hKey,
  76. INITIAL_BREAK,
  77. NULL,
  78. &dwType,
  79. (BYTE *)&dwVal,
  80. &dwSize);
  81. if (ERROR_SUCCESS == lRet &&
  82. dwType == REG_DWORD &&
  83. dwVal)
  84. {
  85. bRet = TRUE;
  86. }
  87. RegCloseKey(hKey);
  88. }
  89. return bRet;
  90. }
  91. //
  92. // the global structure
  93. //
  94. struct _PROG_RESOURCES g_ProgRes;
  95. void
  96. _PROG_RESOURCES::Init()
  97. {
  98. m_bOleInitialized = NULL;
  99. m_pLoginFactory = NULL;
  100. m_pBackupFactory = NULL;
  101. m_dwLoginClsFacReg = 0;
  102. m_dwBackupClsFacReg = 0;
  103. g_fSetup = FALSE;
  104. g_fDoResync = TRUE;
  105. hMainMutex = NULL;
  106. bShuttingDownWinMgmt = FALSE;
  107. gbCoreLoaded = FALSE;
  108. ServiceStatus = SERVICE_STOPPED;
  109. ghCoreCanUnload = NULL;
  110. ghProviderCanUnload = NULL;
  111. ghMofDirChange = NULL;
  112. szHotMofDirectory = NULL;
  113. pWbemVssWriter = NULL;
  114. bWbemVssWriterSubscribed = false;
  115. dwWaitThreadID = GetCurrentThreadId();
  116. };
  117. BOOL
  118. _PROG_RESOURCES::Phase1Build()
  119. {
  120. hMainMutex = CreateMutex(NULL, FALSE, NULL);
  121. g_fSetup = CheckSetupSwitch();
  122. if ( g_fSetup )
  123. {
  124. SetNoShellADAPSwitch();
  125. }
  126. // Look in the registry to decide if we will launch a resync perf or not
  127. g_fDoResync = CheckNoResyncSwitch();
  128. //
  129. // set this to have the Console Control Handler notification
  130. //
  131. SetProcessShutdownParameters(0x400,0);
  132. //
  133. // set to some defined value parames that might be outstanding if someone killed us
  134. //
  135. RegSetDWORD(HKEY_LOCAL_MACHINE,HOME_REG_PATH,DO_THROTTLE,1);
  136. return hMainMutex?TRUE:FALSE;
  137. };
  138. BOOL
  139. _PROG_RESOURCES::Phase2Build(HANDLE hTerminateEvt)
  140. {
  141. ghCoreCanUnload = CreateEvent(NULL,FALSE,FALSE,
  142. TEXT("WINMGMT_COREDLL_CANSHUTDOWN"));
  143. if (NULL == ghCoreCanUnload)
  144. {
  145. // create a non-named event that nobody will set
  146. ghCoreCanUnload = CreateEvent(NULL,FALSE,FALSE,NULL);
  147. if (NULL == ghCoreCanUnload) return FALSE;
  148. }
  149. ghProviderCanUnload = CreateEvent(NULL,FALSE,FALSE,
  150. TEXT("WINMGMT_PROVIDER_CANSHUTDOWN"));
  151. if (NULL == ghProviderCanUnload)
  152. {
  153. // create a non-named event that nobody will set
  154. ghProviderCanUnload = CreateEvent(NULL,FALSE,FALSE,NULL);
  155. if (NULL == ghProviderCanUnload) return FALSE;
  156. }
  157. if (!m_Monitor.Init())
  158. {
  159. return FALSE;
  160. }
  161. // don't create a writer if during setup
  162. if (!g_fSetup)
  163. {
  164. pWbemVssWriter = new CWbemVssWriter;
  165. if (!pWbemVssWriter)
  166. {
  167. TRACE((LOG_WINMGMT,"WINMGMT could not create the VssWriter\n"));
  168. return FALSE;
  169. }
  170. }
  171. return TRUE;
  172. }
  173. CForwardFactory g_FactoryLogin(CLSID_InProcWbemLevel1Login);
  174. BOOL
  175. _PROG_RESOURCES::RegisterLogin()
  176. {
  177. HRESULT sc;
  178. DWORD dwFlags = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER;
  179. g_ProgRes.m_pLoginFactory = &g_FactoryLogin;
  180. g_ProgRes.m_pLoginFactory->AddRef();
  181. sc = CoRegisterClassObject(CLSID_WbemLevel1Login,
  182. g_ProgRes.m_pLoginFactory,
  183. dwFlags,
  184. REGCLS_MULTIPLEUSE,
  185. &g_ProgRes.m_dwLoginClsFacReg);
  186. if(sc != S_OK)
  187. {
  188. DEBUGTRACE((LOG_WINMGMT,"Failed to register the "
  189. "CLSID_WbemLevel1Login class factory, "
  190. "sc = 0x%x\n", sc));
  191. return FALSE;
  192. }
  193. else
  194. {
  195. DEBUGTRACE((LOG_WINMGMT, "Registered class factory with flags: 0x%X\n",dwFlags));
  196. return TRUE;
  197. }
  198. }
  199. BOOL
  200. _PROG_RESOURCES::RevokeLogin()
  201. {
  202. if(m_pLoginFactory)
  203. {
  204. CoRevokeClassObject(m_dwLoginClsFacReg);
  205. m_dwLoginClsFacReg = 0;
  206. m_pLoginFactory->Release();
  207. m_pLoginFactory = NULL;
  208. }
  209. return TRUE;
  210. }
  211. CForwardFactory g_FactoryBackUp(CLSID_WbemBackupRestore);
  212. BOOL
  213. _PROG_RESOURCES::RegisterBackup()
  214. {
  215. HRESULT sc;
  216. DWORD dwFlags = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER;
  217. g_ProgRes.m_pBackupFactory = &g_FactoryBackUp;
  218. g_ProgRes.m_pBackupFactory->AddRef();
  219. sc = CoRegisterClassObject(CLSID_WbemBackupRestore,
  220. g_ProgRes.m_pBackupFactory,
  221. dwFlags,
  222. REGCLS_MULTIPLEUSE,
  223. &g_ProgRes.m_dwBackupClsFacReg);
  224. if(sc != S_OK)
  225. {
  226. TRACE((LOG_WINMGMT,"Failed to register the "
  227. "Backup/recovery class factory, "
  228. "sc = 0x%x\n", sc));
  229. return FALSE;
  230. }
  231. else
  232. {
  233. return TRUE;
  234. }
  235. }
  236. BOOL
  237. _PROG_RESOURCES::RevokeBackup()
  238. {
  239. if(m_pBackupFactory)
  240. {
  241. CoRevokeClassObject(m_dwBackupClsFacReg);
  242. m_dwBackupClsFacReg = 0;
  243. m_pBackupFactory->Release();
  244. m_pBackupFactory = NULL;
  245. }
  246. return TRUE;
  247. }
  248. _PROG_RESOURCES::Phase1Delete(BOOL bIsSystemShutdown)
  249. {
  250. if (!bIsSystemShutdown)
  251. {
  252. if(ghCoreCanUnload)
  253. {
  254. CloseHandle(ghCoreCanUnload);
  255. ghCoreCanUnload = NULL;
  256. };
  257. if(ghProviderCanUnload)
  258. {
  259. CloseHandle(ghProviderCanUnload);
  260. ghProviderCanUnload = NULL;
  261. }
  262. if(ghMofDirChange)
  263. {
  264. CloseHandle(ghMofDirChange);
  265. ghMofDirChange = NULL;
  266. }
  267. }
  268. if (m_Monitor.IsRegistred())
  269. {
  270. m_Monitor.Unregister(bIsSystemShutdown);
  271. }
  272. if (!bIsSystemShutdown)
  273. {
  274. m_Monitor.Uninit();
  275. if(szHotMofDirectory)
  276. {
  277. delete [] szHotMofDirectory;
  278. szHotMofDirectory = NULL;
  279. }
  280. }
  281. // shut down and delete our writer for volume snapshot backup
  282. if (pWbemVssWriter && !bIsSystemShutdown)
  283. {
  284. if (bWbemVssWriterSubscribed)
  285. {
  286. HRESULT hRes = pWbemVssWriter->Unsubscribe();
  287. if (SUCCEEDED(hRes))
  288. {
  289. bWbemVssWriterSubscribed = false;
  290. }
  291. else
  292. {
  293. TRACE((LOG_WINMGMT,"WINMGMT Could not unsubscribe the VssWriter\n"));
  294. }
  295. }
  296. delete pWbemVssWriter;
  297. pWbemVssWriter = NULL;
  298. }
  299. return TRUE;
  300. }
  301. _PROG_RESOURCES::Phase2Delete(BOOL bIsSystemShutdown)
  302. {
  303. // do anyway COM cleanup
  304. // we are on Server now, we can afford it
  305. RevokeLogin();
  306. RevokeBackup();
  307. if(m_bOleInitialized)
  308. {
  309. CoUninitialize();
  310. m_bOleInitialized = FALSE;
  311. }
  312. return TRUE;
  313. }
  314. BOOL
  315. _PROG_RESOURCES::Phase3Delete()
  316. {
  317. if (hMainMutex)
  318. {
  319. CloseHandle(hMainMutex);
  320. hMainMutex = NULL;
  321. }
  322. return TRUE;
  323. }
  324. //
  325. //
  326. // IsShutDown
  327. //
  328. //
  329. /////////////////////////////////////////////////////////////////
  330. BOOL WINAPI IsShutDown(void)
  331. {
  332. return g_ProgRes.bShuttingDownWinMgmt;
  333. }
  334. //
  335. //
  336. // ShutDownCore
  337. //
  338. //
  339. /////////////////////////////////////////////////////////////////
  340. bool ShutDownCore(BOOL bProcessShutdown,BOOL bIsSystemShutDown)
  341. {
  342. SCODE sc = WBEM_E_FAILED;
  343. HMODULE hCoreModule = LoadLibrary(__TEXT("wbemcore.dll"));
  344. if(hCoreModule)
  345. {
  346. pfnShutDown pfn = (pfnShutDown)GetProcAddress(hCoreModule, "Shutdown");
  347. if(pfn)
  348. {
  349. sc = (pfn)(bProcessShutdown,bIsSystemShutDown);
  350. DEBUGTRACE((LOG_WINMGMT, "core is being shut down by WinMgmt, it returned 0x%x\n",sc));
  351. }
  352. FreeLibrary(hCoreModule);
  353. }
  354. return sc == S_OK;
  355. }
  356. //
  357. //
  358. // void Cleanup
  359. //
  360. // Revokes Factories and close Ole etc.
  361. //
  362. ///////////////////////////////////////////////////////////////////
  363. void Cleanup(BOOL bIsSystemShutDown)
  364. {
  365. if (!bIsSystemShutDown)
  366. {
  367. DEBUGTRACE((LOG_WINMGMT,"+ Cleanup(%d), ID = %x\n", bIsSystemShutDown,GetCurrentProcessId()));
  368. }
  369. g_ProgRes.Phase1Delete(bIsSystemShutDown);
  370. // If the core is still loaded, call its shutdown function
  371. ShutDownCore(TRUE,bIsSystemShutDown);
  372. if (!bIsSystemShutDown)
  373. {
  374. CoFreeUnusedLibrariesEx ( 0 , 0 ) ;
  375. CoFreeUnusedLibrariesEx ( 0 , 0 ) ;
  376. }
  377. g_ProgRes.Phase2Delete(bIsSystemShutDown);
  378. if (!bIsSystemShutDown)
  379. {
  380. DEBUGTRACE((LOG_WINMGMT,"- Cleanup()\n"));
  381. }
  382. }
  383. //
  384. //
  385. // BOOL Initialize
  386. //
  387. //
  388. ///////////////////////////////////////////////////////////////
  389. BOOL Initialize(HANDLE hTerminateEvt)
  390. {
  391. if (NULL == hTerminateEvt) return FALSE;
  392. // Set the error mode. This is used to provent the system from putting up dialog boxs to
  393. // open files
  394. UINT errormode = SetErrorMode(0);
  395. errormode |= SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS;
  396. SetErrorMode(errormode);
  397. DEBUGTRACE((LOG_WINMGMT,"+ Initialize, pid = %x\n", GetCurrentProcessId()));
  398. if(!InitHotMofStuff(&g_ProgRes))
  399. return FALSE;
  400. if (!g_ProgRes.Phase2Build(hTerminateEvt))
  401. return FALSE;
  402. // Initialize Ole
  403. SCODE sc;
  404. sc = CoInitializeEx(NULL,COINIT_MULTITHREADED);
  405. if(FAILED(sc))
  406. {
  407. ERRORTRACE((LOG_WINMGMT,"WINMGMT Could not initialize Ole\n"));
  408. return FALSE;
  409. }
  410. else
  411. {
  412. g_ProgRes.m_bOleInitialized = TRUE;
  413. }
  414. //
  415. // Call the initialize function in core
  416. //
  417. HMODULE hCoreModule = NULL;
  418. if (GetModuleHandleEx(0,__TEXT("wbemcore.dll"),&hCoreModule))
  419. {
  420. OnDelete<HMODULE,BOOL(*)(HMODULE),FreeLibrary> flm(hCoreModule);
  421. HRESULT (STDAPICALLTYPE *pfn)(DWORD);
  422. pfn = (long (__stdcall *)(DWORD))GetProcAddress(hCoreModule, "Reinitialize");
  423. if(pfn)
  424. {
  425. sc = (*pfn)(0);
  426. DEBUGTRACE((LOG_WINMGMT, "wbemcore!Reinitialize() returned 0x%x\n",sc));
  427. }
  428. else
  429. {
  430. DEBUGTRACE((LOG_WINMGMT, "failed to re-initialize core\n"));
  431. return FALSE;
  432. }
  433. }
  434. g_ProgRes.RegisterLogin();
  435. g_ProgRes.RegisterBackup();
  436. g_ProgRes.ServiceStatus = SERVICE_RUNNING;
  437. // initialize our writer for volume snapshot backup
  438. // this must be after CoInitializeEx and after wbem is initialized
  439. // (this pointer will be NULL during setup)
  440. if (g_ProgRes.pWbemVssWriter)
  441. {
  442. HRESULT hRes = g_ProgRes.pWbemVssWriter->Initialize();
  443. if (SUCCEEDED(hRes))
  444. {
  445. hRes = g_ProgRes.pWbemVssWriter->Subscribe();
  446. if (SUCCEEDED(hRes))
  447. {
  448. g_ProgRes.bWbemVssWriterSubscribed = true;
  449. }
  450. else
  451. {
  452. DEBUGTRACE((LOG_WINMGMT,"WINMGMT Could not subscribe the VssWriter\n"));
  453. }
  454. }
  455. else
  456. {
  457. DEBUGTRACE((LOG_WINMGMT,"WINMGMT Could not initialize the VssWriter\n"));
  458. }
  459. }
  460. DEBUGTRACE((LOG_WINMGMT,"- Initialize\n"));
  461. return TRUE;
  462. }
  463. //
  464. //
  465. // WaitingFunction
  466. //
  467. // DESCRIPTION:
  468. //
  469. // Here is where we wait for messages and events during WinMgmt execution.
  470. // We return from here when the program/service is being stopped.
  471. //
  472. //////////////////////////////////////////////////////////////////
  473. void WaitingFunction(HANDLE hTerminate)
  474. {
  475. DEBUGTRACE((LOG_WINMGMT,"+ WaitingFunction\n"));
  476. CSched sched;
  477. HANDLE hEvents[] = {hTerminate,
  478. g_ProgRes.ghCoreCanUnload,
  479. g_ProgRes.ghProviderCanUnload,
  480. g_ProgRes.ghMofDirChange // important, must be last entry!!!!
  481. };
  482. int iNumEvents = sizeof(hEvents) / sizeof(HANDLE);
  483. DWORD dwFlags;
  484. SCODE sc;
  485. CPersistentConfig per;
  486. per.TidyUp();
  487. sched.SetWorkItem(PossibleStartCore, 60000);
  488. //Load any MOFs in the MOF directory if needed...
  489. LoadMofsInDirectory(g_ProgRes.szHotMofDirectory);
  490. // resync the perf counters if
  491. // we haven't turned this off for debugging AND
  492. // we are not running during setup
  493. if(GLOB_IsResyncAllowed())
  494. {
  495. ResyncPerf(RESYNC_TYPE_INITIAL);
  496. GLOB_GetMonitor()->Register();
  497. }
  498. while(TRUE)
  499. {
  500. DWORD dwDelay = sched.GetWaitPeriod();
  501. DWORD dwObj = WaitForMultipleObjects(iNumEvents, hEvents, FALSE, dwDelay);
  502. switch (dwObj)
  503. {
  504. case 0: // bail out for terminate event
  505. {
  506. if (SERVICE_SHUTDOWN != g_ProgRes.ServiceStatus)
  507. {
  508. DEBUGTRACE((LOG_WINMGMT,"hTerminate set: reason %x\n",g_ProgRes.ServiceStatus));
  509. }
  510. {
  511. CInMutex im(g_ProgRes.hMainMutex);
  512. g_ProgRes.bShuttingDownWinMgmt = TRUE;
  513. }
  514. // call cleanup outside of a Mutex
  515. Cleanup((g_ProgRes.ServiceStatus == SERVICE_SHUTDOWN)?TRUE:FALSE);
  516. }
  517. return;
  518. case 1: // core can unload
  519. DEBUGTRACE((LOG_WINMGMT,"Got a core can unload event\n"));
  520. sched.SetWorkItem(FirstCoreShutdown, 30000); // 30 seconds until next unloac;
  521. break;
  522. case 2: // provider can unload
  523. {
  524. DEBUGTRACE((LOG_WINMGMT,"Got a provider can unload event\n"));
  525. CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ;
  526. CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ;
  527. sched.SetWorkItem(FinalCoreShutdown, CORE_PROVIDER_UNLOAD_TIMEOUT); // 11 minutes until next unloac;
  528. }
  529. break;
  530. case 3: // change in the hot mof directory
  531. {
  532. DEBUGTRACE((LOG_WINMGMT,"Got change in the hot mof directory\n"));
  533. LoadMofsInDirectory(g_ProgRes.szHotMofDirectory);
  534. //Continue to monitor changes
  535. if (!FindNextChangeNotification(g_ProgRes.ghMofDirChange))
  536. {
  537. iNumEvents--;
  538. }
  539. }
  540. break;
  541. case WAIT_TIMEOUT:
  542. DEBUGTRACE((LOG_WINMGMT,"Got a TIMEOUT work item\n"));
  543. if(sched.IsWorkItemDue(FirstCoreShutdown))
  544. {
  545. // All the clients have left the core and a decent time interval has passed. Set the
  546. // WINMGMT_CORE_CAN_BACKUP event. When the core is done, it will set the WINMGMT_CORE_BACKUP_DONE
  547. // event which will start the final unloading.
  548. DEBUGTRACE((LOG_WINMGMT,"Got a FirstCoreShutdown work item\n"));
  549. sched.ClearWorkItem(FirstCoreShutdown);
  550. CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ;
  551. CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ;
  552. }
  553. if(sched.IsWorkItemDue(FinalCoreShutdown))
  554. {
  555. CInMutex im(g_ProgRes.hMainMutex);
  556. DEBUGTRACE((LOG_WINMGMT,"Got a FinalCoreShutdown work item\n"));
  557. CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ;
  558. CoFreeUnusedLibrariesEx ( CORE_PROVIDER_UNLOAD_TIMEOUT , 0 ) ;
  559. sched.ClearWorkItem(FinalCoreShutdown);
  560. }
  561. if(sched.IsWorkItemDue(PossibleStartCore))
  562. {
  563. sched.StartCoreIfEssNeeded();
  564. sched.ClearWorkItem(PossibleStartCore);
  565. }
  566. break;
  567. }
  568. }
  569. }
  570. //***************************************************************************
  571. //
  572. // MyService::MyService
  573. //
  574. // DESCRIPTION:
  575. //
  576. // Constructor.
  577. //
  578. //***************************************************************************
  579. MyService::MyService(DWORD CtrlAccepted):CNtService(CtrlAccepted)
  580. {
  581. m_hStopEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  582. if(m_hStopEvent == NULL)
  583. {
  584. DEBUGTRACE((LOG_WINMGMT,"MyService could not initialize\n"));
  585. }
  586. }
  587. //***************************************************************************
  588. //
  589. // MyService::~MyService
  590. //
  591. // DESCRIPTION:
  592. //
  593. // Destructor.
  594. //
  595. //***************************************************************************
  596. MyService::~MyService()
  597. {
  598. if(m_hStopEvent)
  599. CloseHandle(m_hStopEvent);
  600. }
  601. //***************************************************************************
  602. //
  603. // DWORD MyService::WorkerThread
  604. //
  605. // DESCRIPTION:
  606. //
  607. // Where the service runs. In this case, the service just waits for
  608. // the terminate event to be set.
  609. //
  610. // RETURN VALUE:
  611. //
  612. // 0
  613. //***************************************************************************
  614. DWORD MyService::WorkerThread()
  615. {
  616. DEBUGTRACE((LOG_WINMGMT,"+ Service::WorkerThread\n"));
  617. if(!::Initialize(m_hStopEvent))
  618. return 0;
  619. WaitingFunction(m_hStopEvent);
  620. if (SERVICE_SHUTDOWN != g_ProgRes.ServiceStatus )
  621. {
  622. DEBUGTRACE((LOG_WINMGMT,"- Service::WorkerThread\n"));
  623. }
  624. return 0;
  625. }
  626. //
  627. //
  628. // VOID MyService::Log
  629. //
  630. ///////////////////////////////////////////////////////////////////
  631. VOID MyService::Log(
  632. IN LPCSTR lpszMsg)
  633. {
  634. TRACE((LOG_WINMGMT,lpszMsg));
  635. }
  636. //
  637. //
  638. // the stop function
  639. //
  640. //////////////////////////////////////////////////////////////////
  641. VOID MyService::Stop(BOOL bSystemShutDownCalled)
  642. {
  643. if (bSystemShutDownCalled)
  644. {
  645. WbemSetMachineShutdown(TRUE);
  646. }
  647. g_ProgRes.ServiceStatus = (bSystemShutDownCalled)?SERVICE_SHUTDOWN:SERVICE_STOPPED;
  648. SetEvent(m_hStopEvent);
  649. };
  650. //
  651. // MyService::Pause
  652. //
  653. ////////////////////////////////////////////////////////////////////
  654. HRESULT WbemPauseService()
  655. {
  656. HRESULT hr = WBEM_S_NO_ERROR;
  657. g_ProgRes.ServiceStatus = SERVICE_PAUSED;
  658. g_ProgRes.RevokeLogin();
  659. GLOB_GetMonitor()->Unregister(FALSE);
  660. SCODE sc = WBEM_E_FAILED;
  661. HMODULE hCoreModule = LoadLibraryEx(__TEXT("wbemcore.dll"),NULL,0);
  662. if(hCoreModule)
  663. {
  664. pfnShutDown pfn = (pfnShutDown)GetProcAddress(hCoreModule, "Shutdown");
  665. if(pfn)
  666. {
  667. sc = pfn(FALSE,FALSE);
  668. DEBUGTRACE((LOG_WINMGMT, "core is being shut down by WinMgmt, it returned 0x%x\n",sc));
  669. }
  670. else
  671. hr = WBEM_E_CRITICAL_ERROR;
  672. FreeLibrary(hCoreModule);
  673. }
  674. else
  675. hr = WBEM_E_CRITICAL_ERROR;
  676. return hr;
  677. }
  678. VOID MyService::Pause()
  679. {
  680. WbemPauseService();
  681. }
  682. //
  683. // MyService::Continue
  684. //
  685. ////////////////////////////////////////////////////////////////////
  686. HRESULT WbemContinueService()
  687. {
  688. HRESULT hr = WBEM_S_NO_ERROR;
  689. SCODE sc = WBEM_E_FAILED;
  690. HMODULE hCoreModule = LoadLibraryEx(__TEXT("wbemcore.dll"),NULL,0);
  691. if(hCoreModule)
  692. {
  693. HRESULT (STDAPICALLTYPE *pfn)(DWORD);
  694. pfn = (long (__stdcall *)(DWORD))GetProcAddress(hCoreModule, "Reinitialize");
  695. if(pfn)
  696. {
  697. sc = (*pfn)(0);
  698. DEBUGTRACE((LOG_WINMGMT, "core is being resumed: it returned 0x%x\n",sc));
  699. }
  700. else
  701. hr = WBEM_E_CRITICAL_ERROR;
  702. FreeLibrary(hCoreModule);
  703. }
  704. else
  705. hr = WBEM_E_CRITICAL_ERROR;
  706. g_ProgRes.RegisterLogin();
  707. GLOB_GetMonitor()->Register();
  708. g_ProgRes.ServiceStatus = SERVICE_RUNNING;
  709. return hr;
  710. }
  711. VOID MyService::Continue()
  712. {
  713. WbemContinueService();
  714. }
  715. //
  716. //
  717. // this function will be executed before
  718. // the final SetServiceStatus(SERVICE_STOPPED)
  719. //
  720. //////////////////////////////////////////////////////////
  721. VOID MyService::FinalCleanup()
  722. {
  723. g_ProgRes.Phase3Delete();
  724. RegSetDWORD(HKEY_LOCAL_MACHINE,
  725. HOME_REG_PATH,
  726. TEXT("ProcessID"),
  727. 0);
  728. }
  729. //
  730. //
  731. // publish process ID in the registry
  732. //
  733. ////////////////////////////////////////////////////
  734. DWORD
  735. RegSetDWORD(HKEY hKey,
  736. TCHAR * pName,
  737. TCHAR * pValue,
  738. DWORD dwValue)
  739. {
  740. HKEY hKey2;
  741. LONG lRet;
  742. lRet = RegOpenKeyEx(hKey,
  743. pName,
  744. 0,
  745. KEY_WRITE,
  746. &hKey2);
  747. if (ERROR_SUCCESS == lRet)
  748. {
  749. DWORD dwType = REG_DWORD;
  750. DWORD dwSize = sizeof(DWORD);
  751. lRet = RegSetValueEx(hKey2,
  752. pValue,
  753. NULL,
  754. dwType,
  755. (BYTE *)&dwValue,
  756. dwSize);
  757. RegCloseKey(hKey2);
  758. }
  759. return lRet;
  760. }
  761. DWORD
  762. RegGetDWORD(HKEY hKey,
  763. TCHAR * pName,
  764. TCHAR * pValue,
  765. DWORD * pdwValue)
  766. {
  767. HKEY hKey2;
  768. LONG lRet;
  769. if (0 == pdwValue)
  770. return ERROR_INVALID_PARAMETER;
  771. lRet = RegOpenKeyEx(hKey,
  772. pName,
  773. 0,
  774. KEY_READ,
  775. &hKey2);
  776. if (ERROR_SUCCESS == lRet)
  777. {
  778. DWORD dwSize = sizeof(DWORD);
  779. DWORD dwType =0;
  780. lRet = RegQueryValueEx(hKey2,
  781. pValue,
  782. NULL,
  783. &dwType,
  784. (BYTE *)pdwValue,
  785. &dwSize);
  786. if (ERROR_SUCCESS == lRet && REG_DWORD != dwType)
  787. {
  788. lRet = ERROR_INVALID_DATATYPE;
  789. }
  790. RegCloseKey(hKey2);
  791. }
  792. return lRet;
  793. }
  794. //
  795. //
  796. // Interceptor
  797. //
  798. //
  799. ///////////////////////////////////////////////////////////
  800. #ifdef INSTRUMENTED_BUILD
  801. #ifdef _X86_
  802. #include <malloc.h>
  803. struct HEAP_ENTRY {
  804. WORD Size;
  805. WORD PrevSize;
  806. BYTE SegmentIndex;
  807. BYTE Flags;
  808. BYTE UnusedBytes;
  809. BYTE SmallTagIndex;
  810. };
  811. #define HEAP_SLOW_FLAGS 0x7d030f60
  812. // only the "header"
  813. typedef struct _HEAP {
  814. HEAP_ENTRY Entry;
  815. ULONG Signature;
  816. ULONG Flags;
  817. ULONG ForceFlags;
  818. } HEAP;
  819. BOOL g_FaultHeapEnabled = FALSE;
  820. BOOL g_FaultFileEnabled = FALSE;
  821. ULONG g_Seed;
  822. ULONG g_Factor = 100000;
  823. ULONG g_Percent = 0x20;
  824. //ULONG g_RowOfFailures = 10;
  825. //LONG g_NumFailInARow = 0;
  826. //LONG g_NumFailedAllocation = 0;
  827. BOOL g_bDisableBreak = FALSE;
  828. LONG g_nSuccConn = 0;
  829. #define SIZE_JUMP_ADR 5
  830. #define SIZE_SAVED_INSTR 12
  831. void
  832. _declspec(naked) Prolog__ReadFile(){
  833. _asm {
  834. // this is the space for the "saved istructions"
  835. nop ;
  836. nop ;
  837. nop ;
  838. nop ;
  839. nop ;
  840. nop ;
  841. nop ;
  842. nop ;
  843. nop ;
  844. nop ;
  845. nop ;
  846. nop ;
  847. // this is the place for the JMP
  848. nop ;
  849. nop ;
  850. nop ;
  851. nop ;
  852. nop ;
  853. nop ; // dist
  854. nop ; // dist
  855. nop ; // dist
  856. nop ; // dist
  857. }
  858. }
  859. BOOL _I_ReadFile(
  860. HANDLE hFile, // handle to file
  861. LPVOID lpBuffer, // data buffer
  862. DWORD nNumberOfBytesToRead, // number of bytes to read
  863. LPDWORD lpNumberOfBytesRead, // number of bytes read
  864. LPOVERLAPPED lpOverlapped // offset
  865. ){
  866. DWORD * pDw = (DWORD *)_alloca(sizeof(DWORD));
  867. BOOL bRet;
  868. LONG Ret = RtlRandomEx(&g_Seed);
  869. if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent))
  870. {
  871. if (lpNumberOfBytesRead)
  872. *lpNumberOfBytesRead = 0;
  873. SetLastError(-1);
  874. return FALSE;
  875. }
  876. _asm{
  877. push lpOverlapped;
  878. push lpNumberOfBytesRead;
  879. push nNumberOfBytesToRead;
  880. push lpBuffer;
  881. push hFile;
  882. call Prolog__ReadFile;
  883. mov bRet,eax
  884. }
  885. return bRet;
  886. }
  887. void
  888. _declspec(naked) Prolog__WriteFile(){
  889. _asm {
  890. // this is the space for the "saved istructions"
  891. nop ;
  892. nop ;
  893. nop ;
  894. nop ;
  895. nop ;
  896. nop ;
  897. nop ;
  898. nop ;
  899. nop ;
  900. nop ;
  901. nop ;
  902. nop ;
  903. // this is the place for the JMP
  904. nop ;
  905. nop ;
  906. nop ;
  907. nop ;
  908. nop ;
  909. nop ; // dist
  910. nop ; // dist
  911. nop ; // dist
  912. }
  913. }
  914. BOOL _I_WriteFile(
  915. HANDLE hFile, // handle to file
  916. LPCVOID lpBuffer, // data buffer
  917. DWORD nNumberOfBytesToWrite, // number of bytes to write
  918. LPDWORD lpNumberOfBytesWritten, // number of bytes written
  919. LPOVERLAPPED lpOverlapped // overlapped buffer
  920. ){
  921. DWORD * pDw = (DWORD *)_alloca(sizeof(DWORD));
  922. BOOL bRet;
  923. LONG Ret = RtlRandomEx(&g_Seed);
  924. if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent))
  925. {
  926. if (lpNumberOfBytesWritten)
  927. *lpNumberOfBytesWritten = 0;
  928. SetLastError(-1);
  929. return FALSE;
  930. }
  931. _asm{
  932. push lpOverlapped;
  933. push lpNumberOfBytesWritten;
  934. push nNumberOfBytesToWrite;
  935. push lpBuffer;
  936. push hFile;
  937. call Prolog__WriteFile;
  938. mov bRet,eax
  939. }
  940. return bRet;
  941. }
  942. void
  943. _declspec(naked) Prolog__CreateEvent(){
  944. _asm {
  945. // this is the space for the "saved istructions"
  946. nop ;
  947. nop ;
  948. nop ;
  949. nop ;
  950. nop ;
  951. nop ;
  952. nop ;
  953. nop ;
  954. nop ;
  955. nop ;
  956. nop ;
  957. nop ;
  958. // this is the place for the JMP
  959. nop ;
  960. nop ;
  961. nop ;
  962. nop ;
  963. nop ;
  964. nop ; // dist
  965. nop ; // dist
  966. }
  967. }
  968. HANDLE _I_CreateEvent(
  969. LPSECURITY_ATTRIBUTES lpEventAttributes, // SD
  970. BOOL bManualReset, // reset type
  971. BOOL bInitialState, // initial state
  972. LPCWSTR lpName // object name
  973. )
  974. {
  975. DWORD * pDw = (DWORD *)_alloca(sizeof(DWORD));
  976. HANDLE hHandle;
  977. LONG Ret = RtlRandomEx(&g_Seed);
  978. if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent))
  979. {
  980. SetLastError(-1);
  981. return NULL;
  982. }
  983. _asm{
  984. push lpName;
  985. push bInitialState;
  986. push bManualReset;
  987. push lpEventAttributes
  988. call Prolog__CreateEvent;
  989. mov hHandle,eax
  990. }
  991. return hHandle;
  992. }
  993. void
  994. _declspec(naked) Prolog__RtlFreeHeap(){
  995. _asm {
  996. // this is the space for the "saved istructions"
  997. nop ;
  998. nop ;
  999. nop ;
  1000. nop ;
  1001. nop ;
  1002. nop ;
  1003. nop ;
  1004. nop ;
  1005. nop ;
  1006. nop ;
  1007. nop ;
  1008. nop ;
  1009. // this is the place for the JMP
  1010. nop ;
  1011. nop ;
  1012. nop ;
  1013. nop ;
  1014. nop ;
  1015. }
  1016. }
  1017. #define SPACE_STACK_ALLOC (4*sizeof(ULONG_PTR))
  1018. DWORD _I_RtlFreeHeap(VOID * pHeap,DWORD Flags,VOID * pBlock)
  1019. {
  1020. ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
  1021. Flags |= (((HEAP *)pHeap)->Flags) | (((HEAP *)pHeap)->ForceFlags);
  1022. DWORD dwRet;
  1023. if (pBlock && !(HEAP_SLOW_FLAGS & Flags))
  1024. {
  1025. HEAP_ENTRY * pEntry = (HEAP_ENTRY *)pBlock-1;
  1026. DWORD RealSize = pEntry->Size * sizeof(HEAP_ENTRY);
  1027. DWORD Size = RealSize - pEntry->UnusedBytes;
  1028. ULONG_PTR * pL = (ULONG_PTR *)pBlock;
  1029. if (0 == (pEntry->Flags & 0x01) ||0xf0f0f0f0 == pL[1] )
  1030. {
  1031. if (!g_bDisableBreak)
  1032. DebugBreak();
  1033. }
  1034. DWORD CanMemset = RealSize-sizeof(HEAP_ENTRY);
  1035. memset(pBlock,0xF0,(CanMemset > SPACE_STACK_ALLOC)?CanMemset-SPACE_STACK_ALLOC:CanMemset);
  1036. if (pEntry->Size >=4)
  1037. {
  1038. RtlCaptureStackBackTrace (1,
  1039. (4 == pEntry->Size)?4:6,
  1040. (PVOID *)(pEntry+2),
  1041. pLong);
  1042. }
  1043. }
  1044. _asm {
  1045. push pBlock ;
  1046. push Flags ;
  1047. push pHeap ;
  1048. call Prolog__RtlFreeHeap ;
  1049. mov dwRet,eax ;
  1050. }
  1051. return dwRet;
  1052. }
  1053. void
  1054. _declspec(naked) Prolog__RtlAllocateHeap(){
  1055. _asm {
  1056. // this is the space for the "saved istructions"
  1057. nop ;
  1058. nop ;
  1059. nop ;
  1060. nop ;
  1061. nop ;
  1062. nop ;
  1063. nop ;
  1064. nop ;
  1065. nop ;
  1066. nop ;
  1067. nop ;
  1068. nop ;
  1069. // this is the place for the JMP
  1070. nop ;
  1071. nop ;
  1072. nop ;
  1073. nop ;
  1074. nop ;
  1075. nop ; // to make this distinct
  1076. }
  1077. }
  1078. VOID * _I_RtlAllocateHeap(VOID * pHeap,DWORD Flags,DWORD Size)
  1079. {
  1080. ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
  1081. Flags |= (((HEAP *)pHeap)->Flags) | (((HEAP *)pHeap)->ForceFlags);
  1082. VOID * pRet;
  1083. DWORD NewSize = (Size < (3*sizeof(HEAP_ENTRY)))?(3*sizeof(HEAP_ENTRY)+SPACE_STACK_ALLOC):(Size+SPACE_STACK_ALLOC);
  1084. /*
  1085. if (g_FaultHeapEnabled && g_NumFailInARow)
  1086. {
  1087. InterlockedDecrement(&g_NumFailInARow);
  1088. goto here;
  1089. }
  1090. */
  1091. LONG Ret = RtlRandomEx(&g_Seed);
  1092. if (g_FaultHeapEnabled && (Ret%g_Factor < g_Percent))
  1093. {
  1094. // g_NumFailInARow = g_RowOfFailures;
  1095. //here:
  1096. // InterlockedIncrement(&g_NumFailedAllocation);
  1097. return NULL;
  1098. }
  1099. _asm {
  1100. push NewSize ;
  1101. push Flags ;
  1102. push pHeap ;
  1103. call Prolog__RtlAllocateHeap ;
  1104. mov pRet,eax ;
  1105. }
  1106. if (pRet && !(HEAP_SLOW_FLAGS & Flags) )
  1107. {
  1108. if (NewSize <= 0xffff)
  1109. NewSize = sizeof(HEAP_ENTRY)*((HEAP_ENTRY *)pRet-1)->Size;
  1110. if (!(HEAP_ZERO_MEMORY & Flags))
  1111. {
  1112. memset(pRet,0xc0,NewSize-sizeof(HEAP_ENTRY));
  1113. }
  1114. RtlCaptureStackBackTrace(1,
  1115. 4,
  1116. (PVOID *)((BYTE *)pRet+(NewSize-SPACE_STACK_ALLOC-sizeof(HEAP_ENTRY))),
  1117. pLong);
  1118. }
  1119. return pRet;
  1120. }
  1121. void
  1122. _declspec(naked) Prolog__RtlReAllocateHeap(){
  1123. _asm {
  1124. // this is the space for the "saved istructions"
  1125. nop ;
  1126. nop ;
  1127. nop ;
  1128. nop ;
  1129. nop ;
  1130. nop ;
  1131. nop ;
  1132. nop ;
  1133. nop ;
  1134. nop ;
  1135. nop ;
  1136. nop ;
  1137. // this is the place for the JMP
  1138. nop ;
  1139. nop ;
  1140. nop ;
  1141. nop ;
  1142. nop ;
  1143. nop ; // dist
  1144. nop ; // dist
  1145. nop ; // dist
  1146. nop ; // dist
  1147. nop ; // dist
  1148. }
  1149. }
  1150. VOID *
  1151. _I_RtlReAllocateHeap(
  1152. HANDLE pHeap, // handle to heap block
  1153. DWORD Flags, // heap reallocation options
  1154. LPVOID lpMem, // pointer to memory to reallocate
  1155. SIZE_T Size // number of bytes to reallocate
  1156. ){
  1157. ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
  1158. Flags |= (((HEAP *)pHeap)->Flags) | (((HEAP *)pHeap)->ForceFlags);
  1159. VOID * pRet;
  1160. DWORD NewSize = (Size < (3*sizeof(HEAP_ENTRY)))?(3*sizeof(HEAP_ENTRY)+SPACE_STACK_ALLOC):(Size+SPACE_STACK_ALLOC);
  1161. _asm {
  1162. push NewSize ;
  1163. push lpMem ;
  1164. push Flags ;
  1165. push pHeap ;
  1166. call Prolog__RtlReAllocateHeap ;
  1167. mov pRet,eax ;
  1168. }
  1169. if (pRet && !(HEAP_SLOW_FLAGS & Flags) )
  1170. {
  1171. if (NewSize <= 0xffff)
  1172. NewSize = sizeof(HEAP_ENTRY)*((HEAP_ENTRY *)pRet-1)->Size;
  1173. RtlCaptureStackBackTrace(1,
  1174. 4,
  1175. (PVOID *)((BYTE *)pRet+(NewSize-SPACE_STACK_ALLOC-sizeof(HEAP_ENTRY))),
  1176. pLong);
  1177. }
  1178. return pRet;
  1179. }
  1180. void
  1181. _declspec(naked) Prolog__RtlValidateHeap(){
  1182. _asm {
  1183. // this is the space for the "saved istructions"
  1184. nop ;
  1185. nop ;
  1186. nop ;
  1187. nop ;
  1188. nop ;
  1189. nop ;
  1190. nop ;
  1191. nop ;
  1192. nop ;
  1193. nop ;
  1194. nop ;
  1195. nop ;
  1196. // this is the place for the JMP
  1197. nop ;
  1198. nop ;
  1199. nop ;
  1200. nop ;
  1201. nop ;
  1202. nop ; // dist
  1203. nop ; // dist
  1204. nop ; // dist
  1205. nop ; // dist
  1206. nop ; // dist
  1207. nop ; // dist
  1208. }
  1209. }
  1210. BOOL
  1211. _I_RtlValidateHeap(
  1212. HANDLE pHeap, // handle to heap block
  1213. DWORD dwFlags, // heap reallocation options
  1214. LPVOID lpMem // pointer to memory to validate
  1215. ){
  1216. ULONG * pLong = (ULONG *)_alloca(sizeof(DWORD));
  1217. BOOL bRet;
  1218. g_bDisableBreak = TRUE;
  1219. _asm {
  1220. push lpMem ;
  1221. push dwFlags ;
  1222. push pHeap ;
  1223. call Prolog__RtlValidateHeap ;
  1224. mov bRet,eax ;
  1225. }
  1226. g_bDisableBreak = FALSE;
  1227. return bRet;
  1228. }
  1229. #if 0
  1230. #define MAX_REMEMBER (1024)
  1231. struct CSCCTrace
  1232. {
  1233. VOID * p1;
  1234. VOID * p2;
  1235. DWORD Tid;
  1236. ULONG_PTR Trace[5];
  1237. } g_CSCCTrace[MAX_REMEMBER];
  1238. LONG g_CSCCIndex = -1;
  1239. void
  1240. _declspec(naked) Prolog__CoSwitchCallContext(){
  1241. _asm {
  1242. // this is the space for the "saved istructions"
  1243. nop ;
  1244. nop ;
  1245. nop ;
  1246. nop ;
  1247. nop ;
  1248. nop ;
  1249. nop ;
  1250. nop ;
  1251. nop ;
  1252. nop ;
  1253. nop ;
  1254. nop ;
  1255. // this is the place for the JMP
  1256. nop ;
  1257. nop ;
  1258. nop ;
  1259. nop ;
  1260. nop ;
  1261. nop ; // dist
  1262. nop ; // dist
  1263. nop ; // dist
  1264. nop ; // dist
  1265. nop ; // dist
  1266. nop ; // dist
  1267. nop ; // dist
  1268. }
  1269. }
  1270. HRESULT WINAPI
  1271. _I_CoSwitchCallContext(IUnknown * pNew,
  1272. IUnknown ** ppOld)
  1273. {
  1274. ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG ));
  1275. long nIndex = InterlockedIncrement(&g_CSCCIndex);
  1276. nIndex %= MAX_REMEMBER;
  1277. CSCCTrace * pTrace = &g_CSCCTrace[nIndex];
  1278. pTrace->p1 = pNew;
  1279. if (ppOld)
  1280. pTrace->p2 = *ppOld;
  1281. else
  1282. pTrace->p2 = 0;
  1283. pTrace->Tid =GetCurrentThreadId();
  1284. RtlCaptureStackBackTrace (1,5,(PVOID *)pTrace->Trace,pLong);
  1285. HRESULT hRes;
  1286. _asm {
  1287. push ppOld;
  1288. push pNew;
  1289. call Prolog__CoSwitchCallContext;
  1290. mov hRes,eax;
  1291. };
  1292. return hRes;
  1293. }
  1294. #endif
  1295. void
  1296. _declspec(naked) Prolog__MoveFileW(){
  1297. _asm {
  1298. // this is the space for the "saved istructions"
  1299. nop ;
  1300. nop ;
  1301. nop ;
  1302. nop ;
  1303. nop ;
  1304. nop ;
  1305. nop ;
  1306. nop ;
  1307. nop ;
  1308. nop ;
  1309. nop ;
  1310. nop ;
  1311. // this is the place for the JMP
  1312. nop ;
  1313. nop ;
  1314. nop ;
  1315. nop ;
  1316. nop ;
  1317. nop ; // dist
  1318. nop ; // dist
  1319. nop ; // dist
  1320. nop ; // dist
  1321. nop ; // dist
  1322. nop ; // dist
  1323. nop ; // dist
  1324. nop ; // dist
  1325. }
  1326. }
  1327. BOOL WINAPI
  1328. _I_MoveFileW(WCHAR * lpExistingFileName,
  1329. WCHAR * lpNewFileName)
  1330. {
  1331. ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG ));
  1332. LONG Ret = RtlRandomEx(&g_Seed);
  1333. if (g_FaultFileEnabled && (Ret%g_Factor < g_Percent))
  1334. {
  1335. SetLastError(-1);
  1336. return FALSE;
  1337. }
  1338. BOOL bRet;
  1339. HRESULT hRes;
  1340. _asm {
  1341. push lpNewFileName;
  1342. push lpExistingFileName;
  1343. call Prolog__MoveFileW;
  1344. mov bRet,eax;
  1345. };
  1346. return bRet;
  1347. }
  1348. void
  1349. _declspec(naked) Prolog__NtOpenThreadToken(){
  1350. _asm {
  1351. // this is the space for the "saved istructions"
  1352. nop ;
  1353. nop ;
  1354. nop ;
  1355. nop ;
  1356. nop ;
  1357. nop ;
  1358. nop ;
  1359. nop ;
  1360. nop ;
  1361. nop ;
  1362. nop ;
  1363. nop ;
  1364. // this is the place for the JMP
  1365. nop ;
  1366. nop ;
  1367. nop ;
  1368. nop ;
  1369. nop ;
  1370. nop ; // dist
  1371. nop ; // dist
  1372. nop ; // dist
  1373. nop ; // dist
  1374. nop ; // dist
  1375. nop ; // dist
  1376. nop ; // dist
  1377. nop ; // dist
  1378. nop ; // dist
  1379. }
  1380. }
  1381. class TokenBackTrace
  1382. {
  1383. private:
  1384. CStaticCritSec cs_;
  1385. struct Trace
  1386. {
  1387. DWORD Tid_;
  1388. PVOID StackTrace_[6];
  1389. Trace()
  1390. {
  1391. ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG ));
  1392. Tid_ = GetCurrentThreadId();
  1393. RtlCaptureStackBackTrace (3,6,(PVOID *)StackTrace_,pLong);
  1394. }
  1395. };
  1396. typedef std::map<HANDLE,Trace,std::less<HANDLE>, wbem_allocator<Trace> > HandleMap;
  1397. HandleMap map_;
  1398. DWORD TlsIndex_;
  1399. struct SetUnsetTls
  1400. {
  1401. DWORD Idx;
  1402. SetUnsetTls(TokenBackTrace & TBT)
  1403. {
  1404. Idx = TBT.TlsIndex_;
  1405. LONG lVal = (LONG)TlsGetValue(Idx);
  1406. lVal++;
  1407. TlsSetValue(Idx,(LPVOID)lVal);
  1408. }
  1409. ~SetUnsetTls()
  1410. {
  1411. LONG lVal = (LONG)TlsGetValue(Idx);
  1412. lVal--;
  1413. TlsSetValue(Idx,(LPVOID)lVal);
  1414. }
  1415. };
  1416. public:
  1417. TokenBackTrace()
  1418. {
  1419. TlsIndex_ = TlsAlloc();
  1420. };
  1421. ~TokenBackTrace()
  1422. {
  1423. TlsFree(TlsIndex_);
  1424. }
  1425. void Add(HANDLE hToken)
  1426. {
  1427. LONG * pLong = (LONG * )_alloca(sizeof(LONG ));
  1428. //DbgPrintfA(0,"A Tid %08x\n",GetCurrentThreadId());
  1429. SetUnsetTls Tls(*this);
  1430. CInCritSec ics(&cs_);
  1431. try
  1432. {
  1433. map_.insert(HandleMap::value_type(hToken,Trace()));
  1434. }
  1435. catch(CX_Exception &) { };
  1436. }
  1437. void Remove(HANDLE hToken)
  1438. {
  1439. SetUnsetTls Tls(*this);
  1440. LONG lVal = (LONG)TlsGetValue(TlsIndex_);
  1441. if (lVal > 1) return;
  1442. //RTL_CRITICAL_SECTION * pcs = &cs_;
  1443. //DbgPrintfA(0,"R Tid %08x\n",GetCurrentThreadId());
  1444. //if (pcs->LockSemaphore && pcs->LockSemaphore == hToken) return;
  1445. CInCritSec ics(&cs_);
  1446. if (map_.empty()) return;
  1447. HandleMap::iterator it = map_.find(hToken);
  1448. if (map_.end() != it)
  1449. {
  1450. map_.erase(it);
  1451. }
  1452. }
  1453. void Empty()
  1454. {
  1455. CInCritSec ics(&cs_);
  1456. map_.clear();
  1457. }
  1458. } g_TBT;
  1459. BOOL WINAPI
  1460. _I_NtOpenThreadToken(HANDLE hThread,
  1461. DWORD DesiredAccess,
  1462. BOOL bOpenAsSelf,
  1463. HANDLE * phToken)
  1464. {
  1465. ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG ));
  1466. BOOL bRet;
  1467. HANDLE hToken = NULL;
  1468. HANDLE * phLocToken = &hToken;
  1469. _asm {
  1470. push phLocToken;
  1471. push bOpenAsSelf;
  1472. push DesiredAccess;
  1473. push hThread;
  1474. call Prolog__NtOpenThreadToken;
  1475. mov bRet,eax;
  1476. };
  1477. if (phToken) *phToken = hToken;
  1478. if (hToken)
  1479. {
  1480. g_TBT.Add(hToken);
  1481. }
  1482. return bRet;
  1483. }
  1484. void
  1485. _declspec(naked) Prolog__NtOpenProcessToken(){
  1486. _asm {
  1487. // this is the space for the "saved istructions"
  1488. nop ;
  1489. nop ;
  1490. nop ;
  1491. nop ;
  1492. nop ;
  1493. nop ;
  1494. nop ;
  1495. nop ;
  1496. nop ;
  1497. nop ;
  1498. nop ;
  1499. nop ;
  1500. // this is the place for the JMP
  1501. nop ;
  1502. nop ;
  1503. nop ;
  1504. nop ;
  1505. nop ;
  1506. nop ; // dist
  1507. nop ; // dist
  1508. nop ; // dist
  1509. nop ; // dist
  1510. nop ; // dist
  1511. nop ; // dist
  1512. nop ; // dist
  1513. nop ; // dist
  1514. nop ; // dist
  1515. nop ; // dist
  1516. }
  1517. }
  1518. BOOL WINAPI
  1519. _I_NtOpenProcessToken (HANDLE ProcessHandle,
  1520. DWORD DesiredAccess,
  1521. HANDLE * pTokenHandle)
  1522. {
  1523. ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG ));
  1524. BOOL bRet;
  1525. HANDLE hToken = NULL;
  1526. HANDLE * phLocToken = &hToken;
  1527. _asm {
  1528. push phLocToken;
  1529. push DesiredAccess;
  1530. push ProcessHandle;
  1531. call Prolog__NtOpenProcessToken;
  1532. mov bRet,eax;
  1533. };
  1534. if (pTokenHandle) *pTokenHandle = hToken;
  1535. if (hToken)
  1536. {
  1537. g_TBT.Add(hToken);
  1538. }
  1539. return bRet;
  1540. }
  1541. void
  1542. _declspec(naked) Prolog__NtClose(){
  1543. _asm {
  1544. // this is the space for the "saved istructions"
  1545. nop ;
  1546. nop ;
  1547. nop ;
  1548. nop ;
  1549. nop ;
  1550. nop ;
  1551. nop ;
  1552. nop ;
  1553. nop ;
  1554. nop ;
  1555. nop ;
  1556. nop ;
  1557. // this is the place for the JMP
  1558. nop ;
  1559. nop ;
  1560. nop ;
  1561. nop ;
  1562. nop ;
  1563. nop ; // dist
  1564. nop ; // dist
  1565. nop ; // dist
  1566. nop ; // dist
  1567. nop ; // dist
  1568. nop ; // dist
  1569. nop ; // dist
  1570. nop ; // dist
  1571. nop ; // dist
  1572. nop ; // dist
  1573. nop ; // dist
  1574. }
  1575. }
  1576. BOOL WINAPI
  1577. _I_NtClose(HANDLE hHandle)
  1578. {
  1579. ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG ));
  1580. if (hHandle) g_TBT.Remove(hHandle);
  1581. BOOL bRet;
  1582. _asm {
  1583. push hHandle;
  1584. call Prolog__NtClose;
  1585. mov bRet,eax;
  1586. };
  1587. return bRet;
  1588. }
  1589. void
  1590. _declspec(naked) Prolog__DuplicateTokenEx(){
  1591. _asm {
  1592. // this is the space for the "saved istructions"
  1593. nop ;
  1594. nop ;
  1595. nop ;
  1596. nop ;
  1597. nop ;
  1598. nop ;
  1599. nop ;
  1600. nop ;
  1601. nop ;
  1602. nop ;
  1603. nop ;
  1604. nop ;
  1605. // this is the place for the JMP
  1606. nop ;
  1607. nop ;
  1608. nop ;
  1609. nop ;
  1610. nop ;
  1611. nop ; // dist
  1612. nop ; // dist
  1613. nop ; // dist
  1614. nop ; // dist
  1615. nop ; // dist
  1616. nop ; // dist
  1617. nop ; // dist
  1618. nop ; // dist
  1619. nop ; // dist
  1620. nop ; // dist
  1621. nop ; // dist
  1622. nop ; // dist
  1623. }
  1624. }
  1625. BOOL WINAPI
  1626. _I_DuplicateTokenEx(HANDLE hExistingToken,
  1627. DWORD dwDesiredAccess,
  1628. LPSECURITY_ATTRIBUTES lpTokenAttributes,
  1629. SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
  1630. TOKEN_TYPE TokenType,
  1631. PHANDLE phNewToken)
  1632. {
  1633. ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG ));
  1634. BOOL bRet;
  1635. HANDLE hToken = NULL;
  1636. HANDLE * phLocToken = &hToken;
  1637. _asm {
  1638. push phLocToken;
  1639. push TokenType;
  1640. push ImpersonationLevel;
  1641. push lpTokenAttributes;
  1642. push dwDesiredAccess;
  1643. push hExistingToken;
  1644. call Prolog__DuplicateTokenEx;
  1645. mov bRet,eax;
  1646. };
  1647. if (phNewToken) *phNewToken = hToken;
  1648. if (hToken)
  1649. {
  1650. g_TBT.Add(hToken);
  1651. }
  1652. return bRet;
  1653. }
  1654. void
  1655. _declspec(naked) Prolog__DuplicateHandle(){
  1656. _asm {
  1657. // this is the space for the "saved istructions"
  1658. nop ;
  1659. nop ;
  1660. nop ;
  1661. nop ;
  1662. nop ;
  1663. nop ;
  1664. nop ;
  1665. nop ;
  1666. nop ;
  1667. nop ;
  1668. nop ;
  1669. nop ;
  1670. // this is the place for the JMP
  1671. nop ;
  1672. nop ;
  1673. nop ;
  1674. nop ;
  1675. nop ;
  1676. nop ; // dist
  1677. nop ; // dist
  1678. nop ; // dist
  1679. nop ; // dist
  1680. nop ; // dist
  1681. nop ; // dist
  1682. nop ; // dist
  1683. nop ; // dist
  1684. nop ; // dist
  1685. nop ; // dist
  1686. nop ; // dist
  1687. nop ; // dist
  1688. nop ; // dist
  1689. }
  1690. }
  1691. BOOL WINAPI
  1692. _I_DuplicateHandle( HANDLE hSourceProcessHandle,
  1693. HANDLE hSourceHandle,
  1694. HANDLE hTargetProcessHandle,
  1695. LPHANDLE lpTargetHandle,
  1696. DWORD dwDesiredAccess,
  1697. BOOL bInheritHandle,
  1698. DWORD dwOptions)
  1699. {
  1700. ULONG * pLong = (ULONG * )_alloca(sizeof(ULONG ));
  1701. BOOL bRet;
  1702. HANDLE hToken = NULL;
  1703. HANDLE * phLocToken = &hToken;
  1704. _asm
  1705. {
  1706. push dwOptions;
  1707. push bInheritHandle;
  1708. push dwDesiredAccess;
  1709. push phLocToken;
  1710. push hTargetProcessHandle;
  1711. push hSourceHandle;
  1712. push hSourceProcessHandle;
  1713. call Prolog__DuplicateHandle;
  1714. mov bRet,eax;
  1715. };
  1716. if (lpTargetHandle) *lpTargetHandle = hToken;
  1717. if (hToken)
  1718. {
  1719. g_TBT.Add(hToken);
  1720. }
  1721. return bRet;
  1722. }
  1723. void intercept2(WCHAR * Module,
  1724. LPSTR Function,
  1725. VOID * NewRoutine,
  1726. VOID * pPrologStorage,
  1727. DWORD Size)
  1728. {
  1729. FARPROC OldRoutine = GetProcAddress(GetModuleHandleW(Module),Function);
  1730. if (OldRoutine)
  1731. {
  1732. MEMORY_BASIC_INFORMATION MemBI;
  1733. DWORD dwOldProtect;
  1734. BOOL bRet, bRet2;
  1735. DWORD dwRet;
  1736. dwRet = VirtualQuery(OldRoutine,&MemBI,sizeof(MemBI));
  1737. bRet = VirtualProtect(MemBI.BaseAddress,
  1738. MemBI.RegionSize,
  1739. PAGE_EXECUTE_WRITECOPY,
  1740. &dwOldProtect);
  1741. dwRet = VirtualQuery(pPrologStorage,&MemBI,sizeof(MemBI));
  1742. bRet2 = VirtualProtect(MemBI.BaseAddress,
  1743. MemBI.RegionSize,
  1744. PAGE_EXECUTE_WRITECOPY,
  1745. &dwOldProtect);
  1746. if (bRet && bRet2)
  1747. {
  1748. VOID * pToJump = (VOID *)NewRoutine;
  1749. BYTE Arr[SIZE_JUMP_ADR] = { 0xe9 };
  1750. LONG * pOffset = (LONG *)&Arr[1];
  1751. * pOffset = (LONG)NewRoutine - (LONG)OldRoutine - SIZE_JUMP_ADR ;
  1752. // save the old code
  1753. memcpy(pPrologStorage,OldRoutine,Size);
  1754. // put the new code
  1755. memset(OldRoutine,0x90,Size);
  1756. memcpy(OldRoutine,Arr,SIZE_JUMP_ADR);
  1757. // adjust the prolog to continue
  1758. * pOffset = (LONG)OldRoutine + Size - (LONG)pPrologStorage - SIZE_SAVED_INSTR - SIZE_JUMP_ADR; // magic for nops
  1759. memcpy((BYTE *)pPrologStorage+SIZE_SAVED_INSTR,Arr,SIZE_JUMP_ADR);
  1760. }
  1761. }
  1762. else
  1763. {
  1764. OutputDebugStringA("GetProcAddress FAIL\n");
  1765. }
  1766. }
  1767. void unintercept(WCHAR * Module,
  1768. LPSTR Function,
  1769. VOID * pPrologStorage,
  1770. DWORD Size)
  1771. {
  1772. FARPROC OldRoutine = GetProcAddress(GetModuleHandleW(Module),Function);
  1773. if (OldRoutine)
  1774. {
  1775. memcpy((void *)OldRoutine,pPrologStorage,Size);
  1776. }
  1777. }
  1778. #endif /*_X86_*/
  1779. #ifndef STATUS_POSSIBLE_DEADLOCK
  1780. #define STATUS_POSSIBLE_DEADLOCK (0xC0000194L)
  1781. #endif
  1782. class CSetVectoredHandler
  1783. {
  1784. private:
  1785. // static ULONG_PTR Base;
  1786. // static ULONG_PTR Limit;
  1787. PVOID pVectorHandler;
  1788. enum ExceptionTypes
  1789. {
  1790. StatusAccessViolation,
  1791. CXXException,
  1792. StatusNoMemory,
  1793. OtherExceptions,
  1794. LastException
  1795. };
  1796. static LONG ExceptionCounters[LastException];
  1797. /*
  1798. BOOL GetDllLimits(WCHAR * pDllName)
  1799. {
  1800. UNICODE_STRING DllName;
  1801. RtlInitUnicodeString(&DllName,pDllName);
  1802. PEB_LDR_DATA * pLdr = NtCurrentPeb()->Ldr;
  1803. LIST_ENTRY * pHeadEntry = &pLdr->InLoadOrderModuleList;
  1804. LIST_ENTRY * pEntry = pLdr->InLoadOrderModuleList.Flink;
  1805. BOOL bFound = FALSE;
  1806. while (pHeadEntry != pEntry)
  1807. {
  1808. LDR_DATA_TABLE_ENTRY * pData = CONTAINING_RECORD(pEntry,
  1809. LDR_DATA_TABLE_ENTRY,
  1810. InLoadOrderLinks);
  1811. if (0 == wbem_wcsicmp(DllName.Buffer,pData->BaseDllName.Buffer))
  1812. {
  1813. //OutputDebugStringA("found\n");
  1814. Base = (ULONG_PTR)pData->DllBase;
  1815. Limit = Base + (ULONG_PTR)pData->SizeOfImage;
  1816. bFound = TRUE;
  1817. break;
  1818. }
  1819. pEntry = pEntry->Flink;
  1820. }
  1821. return bFound;
  1822. }
  1823. */
  1824. public:
  1825. CSetVectoredHandler()
  1826. {
  1827. pVectorHandler = NULL;
  1828. //if (GetDllLimits(L"fastprox.dll"))
  1829. //{
  1830. pVectorHandler = AddVectoredExceptionHandler(TRUE,CSetVectoredHandler::VectoredHandler);
  1831. //}
  1832. };
  1833. ~CSetVectoredHandler()
  1834. {
  1835. if (pVectorHandler)
  1836. RemoveVectoredExceptionHandler(pVectorHandler);
  1837. };
  1838. static LONG WINAPI VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo)
  1839. {
  1840. PEXCEPTION_RECORD pExr = ExceptionInfo->ExceptionRecord;
  1841. PCONTEXT pCxr = ExceptionInfo->ContextRecord;
  1842. switch (pExr->ExceptionCode)
  1843. {
  1844. case STATUS_PRIVILEGED_INSTRUCTION:
  1845. case STATUS_INVALID_HANDLE:
  1846. case STATUS_STACK_OVERFLOW:
  1847. case STATUS_POSSIBLE_DEADLOCK:
  1848. case STATUS_ACCESS_VIOLATION:
  1849. InterlockedIncrement(&ExceptionCounters[(LONG)StatusAccessViolation]);
  1850. DebugBreak();
  1851. break;
  1852. case 0xe06d7363:
  1853. InterlockedIncrement(&ExceptionCounters[(LONG)CXXException]);
  1854. break;
  1855. case STATUS_NO_MEMORY:
  1856. InterlockedIncrement(&ExceptionCounters[(LONG)StatusNoMemory]);
  1857. break;
  1858. default:
  1859. InterlockedIncrement(&ExceptionCounters[(LONG)OtherExceptions]);
  1860. break;
  1861. }
  1862. return EXCEPTION_CONTINUE_SEARCH;
  1863. }
  1864. } g_C;
  1865. LONG CSetVectoredHandler::ExceptionCounters[CSetVectoredHandler::LastException];
  1866. #endif
  1867. //
  1868. //
  1869. // Run The Serivce
  1870. //
  1871. ///////////////////////////////////////////////
  1872. void RunService(DWORD dwNumServicesArgs,
  1873. LPWSTR *lpServiceArgVectors)
  1874. {
  1875. MyService ThisService(SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_PAUSE_CONTINUE);
  1876. ThisService.Run(SERVICE_NAME,
  1877. dwNumServicesArgs,
  1878. lpServiceArgVectors,
  1879. (void *)&ThisService);
  1880. }
  1881. //
  1882. //
  1883. // ServiceMain
  1884. //
  1885. ///////////////////////////////////////////////////////////
  1886. VOID WINAPI
  1887. ServiceMain(DWORD dwNumServicesArgs,
  1888. LPWSTR *lpServiceArgVectors)
  1889. {
  1890. #ifdef INSTRUMENTED_BUILD
  1891. #ifdef _X86_
  1892. intercept2(L"ntdll.dll","RtlFreeHeap",_I_RtlFreeHeap,Prolog__RtlFreeHeap,5);
  1893. intercept2(L"ntdll.dll","RtlAllocateHeap",_I_RtlAllocateHeap,Prolog__RtlAllocateHeap,5);
  1894. intercept2(L"ntdll.dll","RtlReAllocateHeap",_I_RtlReAllocateHeap,Prolog__RtlReAllocateHeap,5);
  1895. intercept2(L"ntdll.dll","RtlValidateHeap",_I_RtlValidateHeap,Prolog__RtlValidateHeap,7);
  1896. intercept2(L"kernel32.dll","CreateEventW",_I_CreateEvent,Prolog__CreateEvent,6);
  1897. intercept2(L"kernel32.dll","WriteFile",_I_WriteFile,Prolog__WriteFile,7);
  1898. intercept2(L"kernel32.dll","ReadFile",_I_ReadFile,Prolog__ReadFile,7);
  1899. intercept2(L"kernel32.dll","MoveFileW",_I_MoveFileW,Prolog__MoveFileW,6);
  1900. /*
  1901. intercept2(L"ntdll.dll","NtClose",_I_NtClose,Prolog__NtClose,5);
  1902. intercept2(L"ntdll.dll","NtOpenThreadToken",_I_NtOpenThreadToken,Prolog__NtOpenThreadToken,5);
  1903. intercept2(L"ntdll.dll","NtOpenProcessToken",_I_NtOpenProcessToken,Prolog__NtOpenProcessToken,5);
  1904. intercept2(L"advapi32.dll","DuplicateTokenEx",_I_DuplicateTokenEx,Prolog__DuplicateTokenEx,6);
  1905. intercept2(L"kernel32.dll","DuplicateHandle",_I_DuplicateHandle,Prolog__DuplicateHandle,7);
  1906. */
  1907. g_nSuccConn = 0;
  1908. #endif /*_X86_*/
  1909. #endif
  1910. RegSetDWORD(HKEY_LOCAL_MACHINE,
  1911. HOME_REG_PATH,
  1912. TEXT("ProcessID"),
  1913. GetCurrentProcessId());
  1914. #ifdef DBG
  1915. if (InitialBreak())
  1916. {
  1917. DebugBreak();
  1918. }
  1919. #endif
  1920. g_ProgRes.Init();
  1921. g_ProgRes.Phase1Build();
  1922. RunService(dwNumServicesArgs,lpServiceArgVectors);
  1923. #ifdef INSTRUMENTED_BUILD
  1924. #ifdef _X86_
  1925. unintercept(L"ntdll.dll","RtlFreeHeap",Prolog__RtlFreeHeap,5);
  1926. unintercept(L"ntdll.dll","RtlAllocateHeap",Prolog__RtlAllocateHeap,5);
  1927. unintercept(L"ntdll.dll","RtlReAllocateHeap",Prolog__RtlReAllocateHeap,5);
  1928. unintercept(L"ntdll.dll","RtlValidateHeap",Prolog__RtlValidateHeap,7);
  1929. unintercept(L"kernel32.dll","CreateEventW",Prolog__CreateEvent,6);
  1930. unintercept(L"kernel32.dll","WriteFile",Prolog__WriteFile,7);
  1931. unintercept(L"kernel32.dll","ReadFile",Prolog__ReadFile,7);
  1932. unintercept(L"kernel32.dll","MoveFileW",Prolog__MoveFileW,6);
  1933. /*
  1934. unintercept(L"ntdll.dll","NtOpenThreadToken",Prolog__NtOpenThreadToken,5);
  1935. unintercept(L"ntdll.dll","NtOpenProcessToken",Prolog__NtOpenProcessToken,5);
  1936. unintercept(L"ntdll.dll","NtClose",Prolog__NtClose,5);
  1937. unintercept(L"advapi32.dll","DuplicateTokenEx",Prolog__DuplicateTokenEx,6);
  1938. unintercept(L"kernel32.dll","DuplicateHandle",Prolog__DuplicateHandle,7);
  1939. */
  1940. #endif /*_X86_*/
  1941. #endif
  1942. }