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.

647 lines
17 KiB

  1. ////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2000-2002, Microsoft Corporation.
  4. //
  5. // All rights reserved.
  6. //
  7. // Module Name:
  8. //
  9. // WMIAdapter_Service.cpp
  10. //
  11. // Abstract:
  12. //
  13. // module for service
  14. //
  15. // History:
  16. //
  17. // initial a-marius
  18. //
  19. ////////////////////////////////////////////////////////////////////////////////////
  20. #include "PreComp.h"
  21. // debuging features
  22. #ifndef _INC_CRTDBG
  23. #include <crtdbg.h>
  24. #endif _INC_CRTDBG
  25. // new stores file/line info
  26. #ifdef _DEBUG
  27. #ifndef NEW
  28. #define NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
  29. #define new NEW
  30. #endif NEW
  31. #endif _DEBUG
  32. // messaging
  33. #include "WMIAdapterMessages.h"
  34. // application
  35. #include "WMIAdapter_App.h"
  36. extern WmiAdapterApp _App;
  37. // service module
  38. #include "WMIAdapter_Service.h"
  39. extern WmiAdapterService _Service;
  40. extern LONG g_lRefLib; // refcount of libarries attached into process
  41. extern CStaticCritSec g_csInit; // synch object used to protect above globals
  42. /////////////////////////////////////////////////////////////////////////////////////////
  43. // destruction
  44. /////////////////////////////////////////////////////////////////////////////////////////
  45. WmiAdapterService::~WmiAdapterService()
  46. {
  47. ATLTRACE ( L"*************************************************************\n"
  48. L"WmiAdapterService destruction\n"
  49. L"*************************************************************\n" );
  50. if ( m_hServiceStatus )
  51. {
  52. // service status handle doesn't have to be closed
  53. // ::CloseHandle ( m_hServiceStatus );
  54. m_hServiceStatus = NULL;
  55. }
  56. ::DeleteCriticalSection ( &m_cs );
  57. }
  58. ///////////////////////////////////////////////////////////////////////////////////////////////
  59. // service status
  60. ///////////////////////////////////////////////////////////////////////////////////////////////
  61. BOOL WmiAdapterService::SetServiceStatus ( DWORD dwState )
  62. {
  63. ATLTRACE ( L"*************************************************************\n"
  64. L"WmiAdapterService set status\n"
  65. L"*************************************************************\n" );
  66. ////////////////////////////////////////////////////////////////////////
  67. // smart locking/unlocking
  68. ////////////////////////////////////////////////////////////////////////
  69. __Smart_CRITICAL_SECTION scs ( const_cast<LPCRITICAL_SECTION> ( &m_cs ) );
  70. m_ServiceStatus.dwCurrentState = dwState;
  71. try
  72. {
  73. return ::SetServiceStatus ( m_hServiceStatus, &m_ServiceStatus );
  74. }
  75. catch ( ... )
  76. {
  77. }
  78. return FALSE;
  79. }
  80. SERVICE_STATUS* WmiAdapterService::GetServiceStatus ( void ) const
  81. {
  82. ATLTRACE ( L"*************************************************************\n"
  83. L"WmiAdapterService get status\n"
  84. L"*************************************************************\n" );
  85. ////////////////////////////////////////////////////////////////////////
  86. // smart locking/unlocking
  87. ////////////////////////////////////////////////////////////////////////
  88. __Smart_CRITICAL_SECTION scs ( const_cast<LPCRITICAL_SECTION> ( &m_cs ) );
  89. return const_cast < SERVICE_STATUS* > ( &m_ServiceStatus );
  90. }
  91. /////////////////////////////////////////////////////////////////////////////////////////
  92. // run body :))
  93. /////////////////////////////////////////////////////////////////////////////////////////
  94. extern "C" int WINAPI WinRun ( );
  95. /////////////////////////////////////////////////////////////////////////////////////////
  96. // functions
  97. /////////////////////////////////////////////////////////////////////////////////////////
  98. void WINAPI WmiAdapterService::_ServiceMain(DWORD dwArgc, LPWSTR* lpszArgv)
  99. {
  100. _Service.ServiceMain(dwArgc, lpszArgv);
  101. }
  102. void WINAPI WmiAdapterService::_ServiceHandler(DWORD dwOpcode)
  103. {
  104. _Service.ServiceHandler(dwOpcode);
  105. }
  106. /////////////////////////////////////////////////////////////////////////////////////////
  107. // routine
  108. /////////////////////////////////////////////////////////////////////////////////////////
  109. inline void WmiAdapterService::ServiceMain( DWORD, LPWSTR* )
  110. {
  111. // Register the control request handler
  112. m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
  113. if ( ( m_hServiceStatus = RegisterServiceCtrlHandlerW(g_szAppName, _ServiceHandler) ) == NULL )
  114. {
  115. #ifdef __SUPPORT_EVENTVWR
  116. try
  117. {
  118. ((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_OPEN_SCM_FAIL, 0, 0, 0, 0 );
  119. }
  120. catch ( ... )
  121. {
  122. }
  123. #endif __SUPPORT_EVENTVWR
  124. return;
  125. }
  126. SetServiceStatus(SERVICE_START_PENDING);
  127. m_ServiceStatus.dwWin32ExitCode = S_OK;
  128. m_ServiceStatus.dwCheckPoint = 0;
  129. m_ServiceStatus.dwWaitHint = 0;
  130. try
  131. {
  132. m_ServiceStatus.dwWin32ExitCode = WinRun ( );
  133. }
  134. catch ( ... )
  135. {
  136. m_ServiceStatus.dwWin32ExitCode = static_cast < ULONG > ( E_UNEXPECTED );
  137. }
  138. SetServiceStatus ( SERVICE_STOPPED );
  139. }
  140. /////////////////////////////////////////////////////////////////////////////////////////
  141. // handler
  142. /////////////////////////////////////////////////////////////////////////////////////////
  143. inline void WmiAdapterService::ServiceHandler(DWORD dwOpcode)
  144. {
  145. // auto lock/unlock
  146. __Smart_CRITICAL_SECTION scs ( const_cast<LPCRITICAL_SECTION> ( &m_cs ) );
  147. switch (dwOpcode)
  148. {
  149. case SERVICE_CONTROL_STOP:
  150. {
  151. BOOL bStop = FALSE;
  152. if ( ::TryEnterCriticalSection ( &g_csInit ) )
  153. {
  154. if ( ( ::InterlockedCompareExchange ( &g_lRefLib, 0, 0 ) == 0 ) && ! _App.InUseGet() )
  155. {
  156. bStop = TRUE;
  157. }
  158. ::LeaveCriticalSection ( &g_csInit );
  159. }
  160. if ( bStop )
  161. {
  162. if ( SetServiceStatus ( SERVICE_STOP_PENDING ) )
  163. {
  164. if ( _App.m_hKill.GetHANDLE() )
  165. {
  166. // kill application
  167. ::SetEvent ( _App.m_hKill );
  168. }
  169. }
  170. }
  171. }
  172. break;
  173. case SERVICE_CONTROL_CONTINUE:
  174. {
  175. m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
  176. }
  177. break;
  178. case SERVICE_CONTROL_PAUSE:
  179. break;
  180. case SERVICE_CONTROL_INTERROGATE:
  181. break;
  182. case SERVICE_CONTROL_SHUTDOWN:
  183. break;
  184. default:
  185. {
  186. // bad service status :))
  187. }
  188. }
  189. }
  190. BOOL WmiAdapterService::StartService ( void )
  191. {
  192. SERVICE_TABLE_ENTRY st[] =
  193. {
  194. { const_cast < LPWSTR > ( g_szAppName ), _ServiceMain },
  195. { NULL, NULL }
  196. };
  197. if ( ! ::StartServiceCtrlDispatcher ( st ) )
  198. {
  199. return FALSE;
  200. }
  201. return TRUE;
  202. }
  203. /////////////////////////////////////////////////////////////////////////////////////////
  204. // initialization
  205. /////////////////////////////////////////////////////////////////////////////////////////
  206. HRESULT WmiAdapterService::Init ( void )
  207. {
  208. ATLTRACE ( L"*************************************************************\n"
  209. L"WmiAdapterService initialization\n"
  210. L"*************************************************************\n" );
  211. ////////////////////////////////////////////////////////////////////////
  212. // smart locking/unlocking
  213. ////////////////////////////////////////////////////////////////////////
  214. __Smart_CRITICAL_SECTION scs ( const_cast<LPCRITICAL_SECTION> ( &m_cs ) );
  215. m_hServiceStatus = NULL;
  216. m_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  217. m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  218. m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  219. m_ServiceStatus.dwWin32ExitCode = 0;
  220. m_ServiceStatus.dwServiceSpecificExitCode = 0;
  221. m_ServiceStatus.dwCheckPoint = 0;
  222. m_ServiceStatus.dwWaitHint = 0;
  223. return S_OK;
  224. }
  225. /////////////////////////////////////////////////////////////////////////////////////////
  226. // helper if installed
  227. /////////////////////////////////////////////////////////////////////////////////////////
  228. int WmiAdapterService::IsInstalled ( SC_HANDLE hSC )
  229. {
  230. int iResult = -1;
  231. if ( hSC )
  232. {
  233. __SmartServiceHANDLE hService;
  234. if ( ( hService = ::OpenServiceW ( hSC, g_szAppName, SERVICE_QUERY_CONFIG ) ) != NULL )
  235. {
  236. iResult = 1;
  237. }
  238. else
  239. {
  240. iResult = 0;
  241. }
  242. }
  243. return iResult;
  244. }
  245. /////////////////////////////////////////////////////////////////////////////////////////
  246. // register service
  247. /////////////////////////////////////////////////////////////////////////////////////////
  248. HRESULT WmiAdapterService::RegisterService ( void )
  249. {
  250. HRESULT hr = S_FALSE;
  251. // Unregister service ( could have bad variables )
  252. hr = UnregisterService ( false );
  253. ATLTRACE ( L"*************************************************************\n"
  254. L"WmiAdapterService registration\n"
  255. L"*************************************************************\n" );
  256. if SUCCEEDED ( hr )
  257. {
  258. // SCM has suggested wait a while if we were deleting
  259. if ( hr == S_OK )
  260. {
  261. // I do not like it either, but there is no way
  262. // to waitforsingleobject on some kernel object ...
  263. ::Sleep ( 3000 );
  264. }
  265. __SmartServiceHANDLE hSC;
  266. if ( ( hSC = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS) ) != NULL )
  267. {
  268. // Get the executable file path
  269. WCHAR wszFilePath[_MAX_PATH] = { L'\0' };
  270. ::GetModuleFileNameW(NULL, wszFilePath, _MAX_PATH-1);
  271. __SmartServiceHANDLE hService;
  272. // create service description
  273. LPWSTR wszServiceName = NULL;
  274. try
  275. {
  276. wszServiceName = LoadStringSystem ( ::GetModuleHandle( NULL ), IDS_NAME );
  277. }
  278. catch ( ... )
  279. {
  280. if ( wszServiceName )
  281. {
  282. delete [] wszServiceName;
  283. wszServiceName = NULL;
  284. }
  285. }
  286. if ( ( hService = ::CreateServiceW ( hSC,
  287. g_szAppName,
  288. ( wszServiceName != NULL ) ?
  289. wszServiceName :
  290. L"WMI Performance Adapter",
  291. SERVICE_ALL_ACCESS,
  292. SERVICE_WIN32_OWN_PROCESS,
  293. SERVICE_DEMAND_START,
  294. SERVICE_ERROR_NORMAL,
  295. wszFilePath,
  296. 0,
  297. 0,
  298. L"RPCSS\0",
  299. 0,
  300. 0
  301. ) )
  302. != NULL )
  303. {
  304. hr = E_OUTOFMEMORY;
  305. // create service description
  306. LPWSTR wszDescription = NULL;
  307. try
  308. {
  309. if ( ( wszDescription = LoadStringSystem ( ::GetModuleHandle( NULL ), IDS_DESCRIPTION ) ) != NULL )
  310. {
  311. hr = S_OK;
  312. SERVICE_DESCRIPTION sd;
  313. sd.lpDescription = wszDescription;
  314. if ( ! ChangeServiceConfig2 ( hService, SERVICE_CONFIG_DESCRIPTION, reinterpret_cast < LPVOID > ( &sd ) ) )
  315. {
  316. hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
  317. }
  318. }
  319. }
  320. catch ( ... )
  321. {
  322. hr = E_FAIL;
  323. }
  324. if ( wszDescription )
  325. {
  326. delete [] wszDescription;
  327. wszDescription = NULL;
  328. }
  329. }
  330. else
  331. {
  332. #ifdef __SUPPORT_EVENTVWR
  333. LPWSTR wszError = NULL;
  334. wszError = GetErrorMessageModule ( WMI_ADAPTER_CREATE_SC_FAIL, _App.m_hResources );
  335. ::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
  336. delete wszError;
  337. try
  338. {
  339. ((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_CREATE_SC_FAIL, 0, 0, 0, 0 );
  340. }
  341. catch ( ... )
  342. {
  343. }
  344. #endif __SUPPORT_EVENTVWR
  345. if ( wszServiceName )
  346. {
  347. delete [] wszServiceName;
  348. wszServiceName = NULL;
  349. }
  350. // unable to create service
  351. hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
  352. }
  353. if ( wszServiceName )
  354. {
  355. delete [] wszServiceName;
  356. wszServiceName = NULL;
  357. }
  358. }
  359. else
  360. {
  361. #ifdef __SUPPORT_EVENTVWR
  362. LPWSTR wszError = NULL;
  363. wszError = GetErrorMessageModule ( WMI_ADAPTER_OPEN_SCM_FAIL, _App.m_hResources );
  364. ::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
  365. delete wszError;
  366. try
  367. {
  368. ((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_OPEN_SCM_FAIL, 0, 0, 0, 0 );
  369. }
  370. catch ( ... )
  371. {
  372. }
  373. #endif __SUPPORT_EVENTVWR
  374. // unable to open service manager
  375. hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
  376. }
  377. }
  378. return hr;
  379. }
  380. /////////////////////////////////////////////////////////////////////////////////////////
  381. // unregister service
  382. /////////////////////////////////////////////////////////////////////////////////////////
  383. HRESULT WmiAdapterService::UnregisterService ( bool bStatus )
  384. {
  385. HRESULT hr = S_FALSE;
  386. ATLTRACE ( L"*************************************************************\n"
  387. L"WmiAdapterService unregistartion\n"
  388. L"*************************************************************\n" );
  389. __SmartServiceHANDLE hSCM;
  390. if ( ( hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS) ) != NULL )
  391. {
  392. if ( IsInstalled ( hSCM ) != 0 )
  393. {
  394. BOOL bContinue = TRUE;
  395. BOOL bSucceeded= FALSE;
  396. DWORD dwTry = 5;
  397. while ( bContinue && dwTry-- )
  398. {
  399. __SmartServiceHANDLE hService;
  400. if ( ( hService = ::OpenServiceW( hSCM, g_szAppName, SERVICE_QUERY_STATUS | SERVICE_STOP ) ) != NULL)
  401. {
  402. SERVICE_STATUS s;
  403. QueryServiceStatus ( hService, &s );
  404. // we are service what's our status
  405. if( s.dwCurrentState != SERVICE_STOPPED )
  406. {
  407. if ( ! ::ControlService( hService, SERVICE_CONTROL_STOP, &s ) )
  408. {
  409. DWORD dwError = ERROR_SUCCESS;
  410. dwError = ::GetLastError ();
  411. switch ( dwError )
  412. {
  413. case ERROR_SERVICE_NOT_ACTIVE:
  414. {
  415. bContinue = FALSE;
  416. bSucceeded= TRUE;
  417. }
  418. break;
  419. case ERROR_SERVICE_CANNOT_ACCEPT_CTRL:
  420. {
  421. if ( s.dwCurrentState == SERVICE_STOPPED )
  422. {
  423. bContinue = FALSE;
  424. bSucceeded= TRUE;
  425. }
  426. }
  427. break;
  428. default:
  429. {
  430. bContinue = FALSE;
  431. hr = HRESULT_FROM_WIN32 ( dwError );
  432. }
  433. break;
  434. }
  435. }
  436. else
  437. {
  438. bSucceeded = TRUE;
  439. }
  440. }
  441. else
  442. {
  443. bContinue = FALSE;
  444. bSucceeded= TRUE;
  445. }
  446. }
  447. else
  448. {
  449. #ifdef __SUPPORT_EVENTVWR
  450. LPWSTR wszError = NULL;
  451. wszError = GetErrorMessageModule ( WMI_ADAPTER_OPEN_SC_FAIL, _App.m_hResources );
  452. ::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
  453. delete wszError;
  454. try
  455. {
  456. ((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_OPEN_SC_FAIL, 0, 0, 0, 0 );
  457. }
  458. catch ( ... )
  459. {
  460. }
  461. #endif __SUPPORT_EVENTVWR
  462. // unable to open service
  463. hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
  464. bContinue = FALSE;
  465. }
  466. }
  467. if ( bSucceeded )
  468. {
  469. __SmartServiceHANDLE hService;
  470. if ( ( hService = ::OpenServiceW( hSCM, g_szAppName, DELETE ) ) != NULL)
  471. {
  472. BOOL bDelete = FALSE;
  473. if ( ( bDelete = ::DeleteService( hService ) ) == FALSE )
  474. {
  475. hr = S_FALSE;
  476. }
  477. else
  478. {
  479. hr = S_OK;
  480. }
  481. if ( bStatus )
  482. {
  483. #ifdef __SUPPORT_EVENTVWR
  484. LPWSTR wszError = NULL;
  485. wszError = GetErrorMessageModule ( WMI_ADAPTER_DELETE_SC_FAIL, _App.m_hResources );
  486. ::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
  487. delete wszError;
  488. try
  489. {
  490. ((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_DELETE_SC_FAIL, 0, 0, 0, 0 );
  491. }
  492. catch ( ... )
  493. {
  494. }
  495. #endif __SUPPORT_EVENTVWR
  496. }
  497. }
  498. else
  499. {
  500. #ifdef __SUPPORT_EVENTVWR
  501. LPWSTR wszError = NULL;
  502. wszError = GetErrorMessageModule ( WMI_ADAPTER_OPEN_SC_FAIL, _App.m_hResources );
  503. ::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
  504. delete wszError;
  505. try
  506. {
  507. ((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_OPEN_SC_FAIL, 0, 0, 0, 0 );
  508. }
  509. catch ( ... )
  510. {
  511. }
  512. #endif __SUPPORT_EVENTVWR
  513. // unable to open service
  514. hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
  515. bContinue = FALSE;
  516. }
  517. }
  518. }
  519. }
  520. else
  521. {
  522. #ifdef __SUPPORT_EVENTVWR
  523. LPWSTR wszError = NULL;
  524. wszError = GetErrorMessageModule ( WMI_ADAPTER_OPEN_SCM_FAIL, _App.m_hResources );
  525. ::MessageBoxW ( ::GetActiveWindow(), ( wszError ) ? wszError : L"error", g_szAppName, MB_OK | MB_ICONERROR );
  526. delete wszError;
  527. try
  528. {
  529. ((CPerformanceEventLogBase*)_App)->ReportEvent ( EVENTLOG_ERROR_TYPE, 0, WMI_ADAPTER_OPEN_SCM_FAIL, 0, 0, 0, 0 );
  530. }
  531. catch ( ... )
  532. {
  533. }
  534. #endif __SUPPORT_EVENTVWR
  535. // unable to open service manager
  536. hr = FAILED ( HRESULT_FROM_WIN32 ( ::GetLastError () ) ) ? HRESULT_FROM_WIN32 ( ::GetLastError () ) : E_FAIL;
  537. }
  538. return hr;
  539. }