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.

599 lines
14 KiB

  1. ////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2000, Microsoft Corporation.
  4. //
  5. // All rights reserved.
  6. //
  7. // Module Name:
  8. //
  9. // WMIAdapter.cpp
  10. //
  11. // Abstract:
  12. //
  13. // implements functionality ( decides what to do :)) )
  14. //
  15. // History:
  16. //
  17. // initial a-marius
  18. //
  19. ////////////////////////////////////////////////////////////////////////////////////
  20. // resorces
  21. #include "PreComp.h"
  22. // guids
  23. #include <initguid.h>
  24. // debuging features
  25. #ifndef _INC_CRTDBG
  26. #include <crtdbg.h>
  27. #endif _INC_CRTDBG
  28. // new stores file/line info
  29. #ifdef _DEBUG
  30. #ifndef NEW
  31. #define NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
  32. #define new NEW
  33. #endif NEW
  34. #endif _DEBUG
  35. // messages ( event log )
  36. #include "WmiAdapterMessages.h"
  37. #include ".\WMIAdapter\resource.h"
  38. // declarations
  39. #include "WMIAdapter_Service.h"
  40. #include "WMIAdapter_App.h"
  41. // registration
  42. #include "Wmi_Adapter_Registry_Service.h"
  43. // enum
  44. #include <refreshergenerate.h>
  45. /////////////////////////////////////////////////////////////////////////////
  46. // VARIABLES
  47. /////////////////////////////////////////////////////////////////////////////
  48. // app
  49. WmiAdapterApp _App;
  50. // service module
  51. WmiAdapterService _Service;
  52. ////////////////////////////////////////////////////////////////////////////
  53. // ATL stuff
  54. ////////////////////////////////////////////////////////////////////////////
  55. // need atl wrappers
  56. #ifndef __ATLBASE_H__
  57. #include <atlbase.h>
  58. #endif __ATLBASE_H__
  59. // need registry
  60. #ifdef _ATL_STATIC_REGISTRY
  61. #include <statreg.h>
  62. #include <statreg.cpp>
  63. #endif
  64. #include <atlimpl.cpp>
  65. /////////////////////////////////////////////////////////////////////////////
  66. //
  67. // Helpers
  68. //
  69. /////////////////////////////////////////////////////////////////////////////
  70. CStaticCritSec g_cs; // synch object used to protect above globals
  71. LONG g_lRef = 0; // count of threads attached into Run Function
  72. __SmartHANDLE g_hDoneWorkEvt = NULL; // event to set when init/uninit is finished done ( nonsignaled )
  73. BOOL g_bWorking = FALSE; // boolean used to tell if init/unit in progress
  74. //Performs Initialization if necessary, waits until initialization is done if necessary.
  75. HRESULT DoInit()
  76. {
  77. HRESULT hRes = E_FAIL;
  78. BOOL bWait = TRUE;
  79. BOOL bDoWork = FALSE;
  80. while (bWait)
  81. {
  82. try
  83. {
  84. ::EnterCriticalSection ( &g_cs );
  85. }
  86. catch ( ... )
  87. {
  88. return E_OUTOFMEMORY;
  89. }
  90. if ( g_lRef == 0 )
  91. {
  92. bDoWork = TRUE;
  93. g_lRef++;
  94. g_bWorking = TRUE;
  95. ::ResetEvent(g_hDoneWorkEvt);
  96. bWait = FALSE;
  97. }
  98. else
  99. {
  100. if ( g_bWorking )
  101. {
  102. ::LeaveCriticalSection ( &g_cs );
  103. if ( WAIT_OBJECT_0 != ::WaitForSingleObject( g_hDoneWorkEvt, INFINITE ) )
  104. {
  105. return hRes;
  106. }
  107. }
  108. else
  109. {
  110. bWait = FALSE;
  111. g_lRef++;
  112. hRes = S_OK;
  113. }
  114. }
  115. }
  116. ::LeaveCriticalSection( &g_cs );
  117. if (bDoWork)
  118. {
  119. if SUCCEEDED ( hRes = _App.InitKill ( ) )
  120. {
  121. try
  122. {
  123. if SUCCEEDED ( hRes = ::CoInitializeSecurity( ( ( WmiSecurityAttributes* ) _App )->GetAbsoluteSecurityDescriptor(),
  124. -1,
  125. NULL,
  126. NULL,
  127. RPC_C_AUTHN_LEVEL_PKT,
  128. RPC_C_IMP_LEVEL_IDENTIFY,
  129. NULL,
  130. EOAC_DYNAMIC_CLOAKING | EOAC_SECURE_REFS,
  131. NULL
  132. )
  133. )
  134. {
  135. try
  136. {
  137. ////////////////////////////////////////////////////////////////////////
  138. // LOCATOR ( neccessary )
  139. ////////////////////////////////////////////////////////////////////////
  140. if ( ! ( (WmiAdapterStuff*) _App )->m_Stuff.m_spLocator )
  141. {
  142. hRes = ::CoCreateInstance
  143. (
  144. __uuidof ( WbemLocator ),
  145. NULL,
  146. CLSCTX_INPROC_SERVER,
  147. __uuidof ( IWbemLocator ),
  148. (void**) & ( ( (WmiAdapterStuff*) _App )->m_Stuff.m_spLocator )
  149. );
  150. }
  151. }
  152. catch ( ... )
  153. {
  154. hRes = E_UNEXPECTED;
  155. }
  156. }
  157. }
  158. catch ( ... )
  159. {
  160. hRes = E_UNEXPECTED;
  161. }
  162. }
  163. try
  164. {
  165. ::EnterCriticalSection ( &g_cs );
  166. }
  167. catch (...)
  168. {
  169. // no choice have to give others a chance!
  170. ::InterlockedDecrement ( &g_lRef );
  171. g_bWorking = FALSE;
  172. ::SetEvent(g_hDoneWorkEvt);
  173. return E_OUTOFMEMORY;
  174. }
  175. if (FAILED(hRes))
  176. {
  177. g_lRef--;
  178. }
  179. g_bWorking = FALSE;
  180. ::SetEvent(g_hDoneWorkEvt);
  181. ::LeaveCriticalSection ( &g_cs );
  182. }
  183. return hRes;
  184. }
  185. //Performs unitialization ONLY if necessary. While unitializing sets global g_bWorking to TRUE.
  186. void DoUninit()
  187. {
  188. BOOL bDoWork = FALSE;
  189. try
  190. {
  191. ::EnterCriticalSection ( &g_cs );
  192. }
  193. catch ( ... )
  194. {
  195. return;
  196. }
  197. if ( g_lRef == 1 )
  198. {
  199. bDoWork = TRUE;
  200. g_bWorking = TRUE;
  201. ::ResetEvent(g_hDoneWorkEvt);
  202. }
  203. else
  204. {
  205. g_lRef--;
  206. }
  207. ::LeaveCriticalSection( &g_cs );
  208. if (bDoWork)
  209. {
  210. try
  211. {
  212. if ( _App.m_hKill.GetHANDLE() )
  213. {
  214. ::SetEvent ( _App.m_hKill );
  215. }
  216. // is refresh of registry already done ?
  217. if ( ((WmiAdapterStuff*)_App)->RequestGet() )
  218. {
  219. ((WmiAdapterStuff*)_App)->Generate ( FALSE );
  220. }
  221. ////////////////////////////////////////////////////////////////////////
  222. // LOCATOR
  223. ////////////////////////////////////////////////////////////////////////
  224. try
  225. {
  226. ( ( WmiAdapterStuff* ) _App )->m_Stuff.m_spLocator.Release();
  227. }
  228. catch ( ... )
  229. {
  230. }
  231. }
  232. catch (...)
  233. {
  234. }
  235. try
  236. {
  237. ::EnterCriticalSection ( &g_cs );
  238. }
  239. catch ( ... )
  240. {
  241. //gotta give others a chance to work, risk it!
  242. ::InterlockedDecrement ( &g_lRef );
  243. g_bWorking = FALSE;
  244. ::SetEvent( g_hDoneWorkEvt );
  245. return;
  246. }
  247. g_lRef--;
  248. g_bWorking = FALSE;
  249. ::SetEvent( g_hDoneWorkEvt );
  250. ::LeaveCriticalSection ( &g_cs );
  251. }
  252. }
  253. /////////////////////////////////////////////////////////////////////////////
  254. //
  255. // WIN MAIN
  256. //
  257. /////////////////////////////////////////////////////////////////////////////
  258. extern "C" int WINAPI WinRun ( );
  259. extern "C" int WINAPI _tWinMain ( HINSTANCE hInstance, HINSTANCE, LPTSTR, int )
  260. {
  261. return WinMain ( hInstance, NULL, GetCommandLineA(), SW_SHOW );
  262. }
  263. extern "C" int WINAPI WinMain ( HINSTANCE, HINSTANCE, LPSTR, int )
  264. {
  265. if ( CStaticCritSec::anyFailure () )
  266. {
  267. //
  268. // some critical section was not
  269. // initialized properly due to low memory
  270. //
  271. return ERROR_NOT_ENOUGH_MEMORY ;
  272. }
  273. HRESULT nRet = S_FALSE;
  274. ////////////////////////////////////////////////////////////////////////
  275. // initialization
  276. ////////////////////////////////////////////////////////////////////////
  277. if SUCCEEDED ( nRet = _App.InitAttributes ( ) )
  278. {
  279. ////////////////////////////////////////////////////////////////////////
  280. // variables
  281. ////////////////////////////////////////////////////////////////////////
  282. WCHAR szTokens[] = L"-/";
  283. ////////////////////////////////////////////////////////////
  284. // initialization
  285. ////////////////////////////////////////////////////////////
  286. if SUCCEEDED ( nRet = _App.Init ( ) )
  287. {
  288. ////////////////////////////////////////////////////////////////////////
  289. // command line
  290. ////////////////////////////////////////////////////////////////////////
  291. LPWSTR lpCmdLine = GetCommandLineW();
  292. ////////////////////////////////////////////////////////////////////////
  293. // find behaviour
  294. ////////////////////////////////////////////////////////////////////////
  295. LPCWSTR lpszToken = WmiAdapterApp::FindOneOf(lpCmdLine, szTokens);
  296. BOOL bContinue = TRUE;
  297. try
  298. {
  299. while (lpszToken != NULL && bContinue)
  300. {
  301. if (lstrcmpiW(lpszToken, L"UnregServer")==0)
  302. {
  303. ////////////////////////////////////////////////////////////////
  304. // unregister service
  305. ////////////////////////////////////////////////////////////////
  306. if SUCCEEDED ( nRet = _Service.UnregisterService ( ) )
  307. {
  308. ((WmiAdapterStuff*)_App)->Generate( FALSE, UnRegistration );
  309. ////////////////////////////////////////////////////////////
  310. // unregister registry
  311. ////////////////////////////////////////////////////////////
  312. WmiAdapterRegistryService::__UpdateRegistrySZ( false );
  313. }
  314. bContinue = FALSE;
  315. }
  316. else
  317. {
  318. if (lstrcmpiW(lpszToken, L"RegServer")==0)
  319. {
  320. ////////////////////////////////////////////////////////////
  321. // register service
  322. ////////////////////////////////////////////////////////////
  323. if SUCCEEDED ( nRet = _Service.RegisterService ( ) )
  324. {
  325. ////////////////////////////////////////////////////////
  326. // create registry again
  327. ////////////////////////////////////////////////////////
  328. WmiAdapterRegistryService::__UpdateRegistrySZ( true );
  329. ((WmiAdapterStuff*)_App)->Generate( FALSE, Registration );
  330. }
  331. bContinue = FALSE;
  332. }
  333. }
  334. lpszToken = WmiAdapterApp::FindOneOf(lpszToken, szTokens);
  335. }
  336. if ( bContinue )
  337. {
  338. ////////////////////////////////////////////////////////////////
  339. // previous instance
  340. ////////////////////////////////////////////////////////////////
  341. if ( ! _App.Exists() )
  342. {
  343. ////////////////////////////////////////////////////////
  344. // initialization
  345. ////////////////////////////////////////////////////////
  346. _Service.Init ( );
  347. __SmartServiceHANDLE pSCM;
  348. if ( ( pSCM = OpenSCManager (
  349. NULL, // machine (NULL == local)
  350. NULL, // database (NULL == default)
  351. SC_MANAGER_ALL_ACCESS // access required
  352. ) ) != NULL )
  353. {
  354. __SmartServiceHANDLE pService;
  355. if ( ( pService = OpenServiceW ( pSCM, g_szAppName, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG ) )
  356. != NULL )
  357. {
  358. LPQUERY_SERVICE_CONFIG lpQSC = NULL;
  359. DWORD dwQSC = 0L;
  360. try
  361. {
  362. if ( ! QueryServiceConfig ( pService, lpQSC, 0, &dwQSC ) )
  363. {
  364. if ( ERROR_INSUFFICIENT_BUFFER == ::GetLastError () )
  365. {
  366. if ( ( lpQSC = (LPQUERY_SERVICE_CONFIG) LocalAlloc( LPTR, dwQSC ) ) != NULL )
  367. {
  368. if ( QueryServiceConfig ( pService, lpQSC, dwQSC, &dwQSC ) != 0 )
  369. {
  370. _App.m_bManual = ( lpQSC->dwStartType == SERVICE_DEMAND_START );
  371. }
  372. }
  373. }
  374. }
  375. }
  376. catch ( ... )
  377. {
  378. }
  379. LocalFree ( lpQSC );
  380. SERVICE_STATUS s;
  381. QueryServiceStatus ( pService, &s );
  382. // we are service, not running ???
  383. if( s.dwCurrentState != SERVICE_RUNNING )
  384. {
  385. if ( ! _Service.StartService () )
  386. {
  387. DWORD dwError = ERROR_SUCCESS;
  388. dwError = ::GetLastError();
  389. if FAILED ( HRESULT_FROM_WIN32 ( dwError ) )
  390. {
  391. nRet = HRESULT_FROM_WIN32 ( dwError );
  392. }
  393. else
  394. {
  395. nRet = HRESULT_FROM_WIN32 ( ERROR_NOT_READY );
  396. }
  397. }
  398. }
  399. else
  400. {
  401. DWORD dwError = ERROR_SUCCESS;
  402. dwError = ::GetLastError();
  403. if FAILED ( HRESULT_FROM_WIN32 ( dwError ) )
  404. {
  405. nRet = HRESULT_FROM_WIN32 ( dwError );
  406. }
  407. else
  408. {
  409. nRet = HRESULT_FROM_WIN32 ( ERROR_ALREADY_EXISTS );
  410. }
  411. }
  412. }
  413. else
  414. {
  415. DWORD dwError = ERROR_SUCCESS;
  416. dwError = ::GetLastError();
  417. if FAILED ( HRESULT_FROM_WIN32 ( dwError ) )
  418. {
  419. nRet = HRESULT_FROM_WIN32 ( dwError );
  420. }
  421. else
  422. {
  423. nRet = E_FAIL;
  424. }
  425. }
  426. }
  427. else
  428. {
  429. DWORD dwError = ERROR_SUCCESS;
  430. dwError = ::GetLastError();
  431. if FAILED ( HRESULT_FROM_WIN32 ( dwError ) )
  432. {
  433. nRet = HRESULT_FROM_WIN32 ( dwError );
  434. }
  435. else
  436. {
  437. nRet = E_FAIL;
  438. }
  439. }
  440. }
  441. else
  442. {
  443. ////////////////////////////////////////////////////////////
  444. // termination
  445. ////////////////////////////////////////////////////////////
  446. nRet = HRESULT_FROM_WIN32 ( ERROR_ALREADY_EXISTS );
  447. }
  448. }
  449. }
  450. catch ( ... )
  451. {
  452. // catastrophic failure
  453. nRet = E_FAIL;
  454. }
  455. // return
  456. if SUCCEEDED ( nRet )
  457. {
  458. nRet = _Service.GetServiceStatus()->dwWin32ExitCode;
  459. }
  460. _App.Term ();
  461. }
  462. }
  463. return nRet;
  464. }
  465. ///////////////////////////////////////////////////////////////////////////////
  466. //
  467. // RUN :))
  468. //
  469. ///////////////////////////////////////////////////////////////////////////////
  470. extern "C" int WINAPI WinRun( )
  471. {
  472. ///////////////////////////////////////////////////////////////////////////
  473. // INITIALIZATION
  474. ///////////////////////////////////////////////////////////////////////////
  475. LONG lRes = ERROR_SUCCESS;
  476. HRESULT hRes = E_FAIL;
  477. ///////////////////////////////////////////////////////////////////////////
  478. // COM INITIALIZATION
  479. ///////////////////////////////////////////////////////////////////////////
  480. if SUCCEEDED ( hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED) )
  481. {
  482. // mark service is running IMMEDIATELY
  483. _Service.SetServiceStatus ( SERVICE_RUNNING );
  484. if SUCCEEDED ( hRes = DoInit() )
  485. {
  486. try
  487. {
  488. if ( ( lRes = _Service.Work () ) != S_OK )
  489. {
  490. if ( _App.m_hKill.GetHANDLE() )
  491. {
  492. ::SetEvent ( _App.m_hKill );
  493. }
  494. }
  495. ::WaitForSingleObject ( _App.m_hKill, INFINITE );
  496. }
  497. catch ( ... )
  498. {
  499. lRes = E_UNEXPECTED;
  500. }
  501. ///////////////////////////////////////////////////////////////////
  502. // do real finishing stuff ( synchronize etc )
  503. ///////////////////////////////////////////////////////////////////
  504. DoUninit();
  505. }
  506. ///////////////////////////////////////////////////////////////////////
  507. // COM UNINITIALIZATION
  508. ///////////////////////////////////////////////////////////////////////
  509. ::CoUninitialize();
  510. }
  511. if FAILED ( hRes )
  512. {
  513. // something was wrong in helpers
  514. return hRes;
  515. }
  516. else
  517. {
  518. // result from real work
  519. return ( lRes == S_FALSE ) ? S_OK : lRes;
  520. }
  521. }