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.

619 lines
16 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation.
  4. //
  5. // File: WLBSProvider.CPP
  6. //
  7. // Module: WLBS Instance Provider
  8. //
  9. // Purpose: Defines the CWLBSProvider class. An object of this class is
  10. // created by the class factory for each connection.
  11. //
  12. // History:
  13. //
  14. ////////////////////////////////////////////////////////////////////////////////
  15. #define ENABLE_PROFILE
  16. #include <objbase.h>
  17. #include <process.h>
  18. #include "WLBS_Provider.h"
  19. #include "ClusterWrapper.h"
  20. #include "ControlWrapper.h"
  21. #include "utils.h"
  22. ////////////////////////////////////////////////////////////////////////////////
  23. //
  24. //CWLBSProvider::CWLBSProvider
  25. // CWLBSProvider::~CWLBSProvider
  26. //
  27. ////////////////////////////////////////////////////////////////////////////////
  28. CWLBSProvider::CWLBSProvider(
  29. BSTR a_strObjectPath,
  30. BSTR a_strUser,
  31. BSTR a_strPassword,
  32. IWbemContext * a_pContex
  33. )
  34. {
  35. m_pNamespace = NULL;
  36. InterlockedIncrement(&g_cComponents);
  37. return;
  38. }
  39. CWLBSProvider::~CWLBSProvider(void)
  40. {
  41. InterlockedDecrement(&g_cComponents);
  42. return;
  43. }
  44. ////////////////////////////////////////////////////////////////////////////////
  45. //
  46. // CWLBSProvider::Initialize
  47. //
  48. // Purpose: This is the implementation of IWbemProviderInit. The method
  49. // is called by WinMgMt.
  50. //
  51. ////////////////////////////////////////////////////////////////////////////////
  52. STDMETHODIMP CWLBSProvider::Initialize(
  53. LPWSTR a_pszUser,
  54. LONG a_lFlags,
  55. LPWSTR a_pszNamespace,
  56. LPWSTR a_pszLocale,
  57. IWbemServices * a_pNamespace,
  58. IWbemContext * a_pCtx,
  59. IWbemProviderInitSink * a_pInitSink
  60. )
  61. {
  62. PROFILE("CWLBSProvider::Initialize");
  63. try {
  64. //!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  65. //g_pWlbsControl must be initialized when the first COM instance is invoked
  66. //and it must stay alive for the lifetime of the DLL, i.e. do NOT DESTROY
  67. //it in the destructor of this CLASS until the API cache of the Cluster IP
  68. //and Password are REMOVED.
  69. //DO NOT INITIALIZE g_pWlbsControl in DLLMain. DLLMain is invoked with regsvr32
  70. //and we do not want to initialize WinSock at that time!!! This will BREAK the
  71. //installation process of the provider.
  72. //!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  73. if( g_pWlbsControl == NULL ) {
  74. g_pWlbsControl = new CWlbsControlWrapper();
  75. if( g_pWlbsControl == NULL)
  76. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  77. }
  78. g_pWlbsControl->Initialize();
  79. return CImpersonatedProvider::Initialize
  80. (
  81. a_pszUser,
  82. a_lFlags,
  83. a_pszNamespace,
  84. a_pszLocale,
  85. a_pNamespace,
  86. a_pCtx,
  87. a_pInitSink
  88. );
  89. }
  90. catch (...)
  91. {
  92. #ifdef DBG // In debug version, popup a message box for AV
  93. MessageBoxExA(NULL,"Wlbs Provider Failure.","Wlbs Provider Access Violation",
  94. MB_TOPMOST | MB_ICONHAND | MB_OK | MB_SERVICE_NOTIFICATION,LANG_USER_DEFAULT);
  95. #endif
  96. return WBEM_E_FAILED;
  97. }
  98. }
  99. ////////////////////////////////////////////////////////////////////////////////
  100. //
  101. // CWLBSProvider::CreateInstanceEnumAsync
  102. //
  103. // Purpose: Asynchronously enumerates the instances.
  104. //
  105. ////////////////////////////////////////////////////////////////////////////////
  106. STDMETHODIMP CWLBSProvider::DoCreateInstanceEnumAsync(
  107. BSTR a_strClass,
  108. long a_lFlags,
  109. IWbemContext * a_pIContex,
  110. IWbemObjectSink * a_pIResponseHandler
  111. )
  112. {
  113. ASSERT(g_pWlbsControl);
  114. if (g_pWlbsControl)
  115. {
  116. //
  117. // Re-enumerate all the clusters
  118. //
  119. g_pWlbsControl->ReInitialize();
  120. }
  121. try {
  122. auto_ptr<CWlbs_Root> pMofClass;
  123. //create an instance of the appropriate MOF support class
  124. HRESULT hRes = GetMOFSupportClass(a_strClass, pMofClass, a_pIResponseHandler);
  125. //call the appropriate wrapper class GetInstance method
  126. if( SUCCEEDED( hRes ) && pMofClass.get() != NULL)
  127. hRes = pMofClass->EnumInstances( a_strClass );
  128. return hRes;
  129. }
  130. catch(_com_error HResErr ) {
  131. a_pIResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  132. return HResErr.Error();
  133. }
  134. catch(...) {
  135. #ifdef DBG // In debug version, popup a message box for AV
  136. MessageBoxExA(NULL,"Wlbs Provider Failure.","Wlbs Provider Access Violation",
  137. MB_TOPMOST | MB_ICONHAND | MB_OK | MB_SERVICE_NOTIFICATION,LANG_USER_DEFAULT);
  138. #endif
  139. a_pIResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, NULL);
  140. return WBEM_E_FAILED;
  141. }
  142. }
  143. ////////////////////////////////////////////////////////////////////////////////
  144. //
  145. // CWLBSProvider::GetObjectAsync
  146. //
  147. // Purpose: Gets an instance for a particular object path
  148. //
  149. ////////////////////////////////////////////////////////////////////////////////
  150. STDMETHODIMP CWLBSProvider::DoGetObjectAsync(
  151. BSTR a_strObjectPath,
  152. long a_lFlags,
  153. IWbemContext * a_pIContex,
  154. IWbemObjectSink * a_pIResponseHandler
  155. )
  156. {
  157. ASSERT(g_pWlbsControl);
  158. if (g_pWlbsControl)
  159. {
  160. //
  161. // Re-enumerate all the clusters
  162. //
  163. g_pWlbsControl->ReInitialize();
  164. }
  165. ParsedObjectPath* pParsedPath = NULL;
  166. try {
  167. auto_ptr<CWlbs_Root> pMofClass;
  168. //parse the object path
  169. ParseObjectPath( a_strObjectPath, &pParsedPath );
  170. //create an instance of the appropriate MOF support class
  171. HRESULT hRes = GetMOFSupportClass( pParsedPath->m_pClass, pMofClass, a_pIResponseHandler );
  172. //call the appropriate wrapper class GetInstance method
  173. if( SUCCEEDED( hRes ) && pMofClass.get() != NULL)
  174. hRes = pMofClass->GetInstance( pParsedPath );
  175. if( pParsedPath )
  176. CObjectPathParser().Free( pParsedPath );
  177. return hRes;
  178. }
  179. catch(_com_error HResErr) {
  180. a_pIResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  181. if( pParsedPath )
  182. CObjectPathParser().Free( pParsedPath );
  183. return HResErr.Error();
  184. }
  185. catch(...) {
  186. #ifdef DBG // In debug version, popup a message box for AV
  187. MessageBoxExA(NULL,"Wlbs Provider Failure.","Wlbs Provider Access Violation",
  188. MB_TOPMOST | MB_ICONHAND | MB_OK | MB_SERVICE_NOTIFICATION,LANG_USER_DEFAULT);
  189. #endif
  190. if( pParsedPath )
  191. CObjectPathParser().Free( pParsedPath );
  192. a_pIResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, NULL);
  193. return WBEM_E_FAILED;
  194. }
  195. }
  196. ////////////////////////////////////////////////////////////////////////////////
  197. //
  198. // CWLBSProvider::DoDeleteInstanceAsync
  199. //
  200. // Purpose: Gets an instance from a particular object path
  201. //
  202. ////////////////////////////////////////////////////////////////////////////////
  203. STDMETHODIMP CWLBSProvider::DoDeleteInstanceAsync(
  204. BSTR a_strObjectPath,
  205. long a_lFlags,
  206. IWbemContext * a_pIContex,
  207. IWbemObjectSink * a_pIResponseHandler
  208. )
  209. {
  210. ASSERT(g_pWlbsControl);
  211. if (g_pWlbsControl)
  212. {
  213. //
  214. // Re-enumerate all the clusters
  215. //
  216. g_pWlbsControl->ReInitialize();
  217. }
  218. ParsedObjectPath* pParsedPath = NULL;
  219. try {
  220. auto_ptr<CWlbs_Root> pMofClass;
  221. //parse the object path
  222. ParseObjectPath( a_strObjectPath, &pParsedPath );
  223. //create an instance of the appropriate MOF support class
  224. HRESULT hRes = GetMOFSupportClass( pParsedPath->m_pClass, pMofClass, a_pIResponseHandler );
  225. //call the appropriate wrapper class GetInstance method
  226. if( SUCCEEDED( hRes ) && pMofClass.get() != NULL)
  227. hRes = pMofClass->DeleteInstance( pParsedPath );
  228. if( pParsedPath )
  229. CObjectPathParser().Free( pParsedPath );
  230. return hRes;
  231. }
  232. catch(_com_error HResErr) {
  233. a_pIResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  234. if( pParsedPath )
  235. CObjectPathParser().Free( pParsedPath );
  236. return HResErr.Error();
  237. }
  238. catch(...) {
  239. #ifdef DBG // In debug version, popup a message box for AV
  240. MessageBoxExA(NULL,"Wlbs Provider Failure.","Wlbs Provider Access Violation",
  241. MB_TOPMOST | MB_ICONHAND | MB_OK | MB_SERVICE_NOTIFICATION,LANG_USER_DEFAULT);
  242. #endif
  243. if( pParsedPath )
  244. CObjectPathParser().Free( pParsedPath );
  245. a_pIResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, NULL);
  246. return WBEM_E_FAILED;
  247. }
  248. }
  249. ////////////////////////////////////////////////////////////////////////////////
  250. //
  251. // CWLBSProvider::ExecMethodAsync
  252. //
  253. // Purpose: Executes a MOF class method.
  254. //
  255. ////////////////////////////////////////////////////////////////////////////////
  256. STDMETHODIMP CWLBSProvider::DoExecMethodAsync(
  257. BSTR a_strObjectPath,
  258. BSTR a_strMethodName,
  259. long a_lFlags,
  260. IWbemContext * a_pIContex,
  261. IWbemClassObject * a_pIInParams,
  262. IWbemObjectSink * a_pIResponseHandler
  263. )
  264. {
  265. ASSERT(g_pWlbsControl);
  266. if (g_pWlbsControl)
  267. {
  268. //
  269. // Re-enumerate all the clusters
  270. //
  271. g_pWlbsControl->ReInitialize();
  272. }
  273. ParsedObjectPath* pParsedPath = NULL;
  274. try {
  275. //parse the object path
  276. auto_ptr<CWlbs_Root> pMofClass;
  277. //parse the object path
  278. ParseObjectPath(a_strObjectPath, &pParsedPath);
  279. //create an instance of the appropriate MOF support class
  280. HRESULT hRes = GetMOFSupportClass(pParsedPath->m_pClass, pMofClass, a_pIResponseHandler);
  281. //execute MOF class method
  282. if( SUCCEEDED( hRes ) && pMofClass.get() != NULL)
  283. hRes = pMofClass->ExecMethod( pParsedPath,
  284. a_strMethodName,
  285. 0,
  286. NULL,
  287. a_pIInParams );
  288. if( pParsedPath )
  289. CObjectPathParser().Free( pParsedPath );
  290. return hRes;
  291. }
  292. catch(_com_error HResErr) {
  293. a_pIResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  294. if( pParsedPath )
  295. CObjectPathParser().Free( pParsedPath );
  296. return HResErr.Error();
  297. }
  298. catch(...) {
  299. #ifdef DBG // In debug version, popup a message box for AV
  300. MessageBoxExA(NULL,"Wlbs Provider Failure.","Wlbs Provider Access Violation",
  301. MB_TOPMOST | MB_ICONHAND | MB_OK | MB_SERVICE_NOTIFICATION,LANG_USER_DEFAULT);
  302. #endif
  303. if( pParsedPath )
  304. CObjectPathParser().Free( pParsedPath );
  305. a_pIResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, NULL);
  306. return WBEM_E_FAILED;
  307. }
  308. }
  309. ////////////////////////////////////////////////////////////////////////////////
  310. //
  311. // CWLBSProvider::PutInstanceAsync
  312. //
  313. // Purpose: Creates or modifies an instance
  314. //
  315. ////////////////////////////////////////////////////////////////////////////////
  316. STDMETHODIMP CWLBSProvider::DoPutInstanceAsync
  317. (
  318. IWbemClassObject* a_pInst,
  319. long a_lFlags,
  320. IWbemContext* a_pIContex,
  321. IWbemObjectSink* a_pIResponseHandler
  322. )
  323. {
  324. ASSERT(g_pWlbsControl);
  325. if (g_pWlbsControl)
  326. {
  327. //
  328. // Re-enumerate all the clusters
  329. //
  330. g_pWlbsControl->ReInitialize();
  331. }
  332. ParsedObjectPath* pParsedPath = NULL;
  333. HRESULT hRes = 0;
  334. try {
  335. wstring szClass;
  336. auto_ptr<CWlbs_Root> pMofClass;
  337. //retrieve the class name
  338. GetClass( a_pInst, szClass );
  339. //create an instance of the appropriate MOF support class
  340. hRes = GetMOFSupportClass( szClass.c_str(), pMofClass, a_pIResponseHandler );
  341. //call the appropriate wrapper class PutInstance method
  342. if( SUCCEEDED( hRes ) && pMofClass.get() != NULL)
  343. hRes = pMofClass->PutInstance( a_pInst );
  344. if( pParsedPath )
  345. CObjectPathParser().Free( pParsedPath );
  346. }
  347. catch(_com_error HResErr) {
  348. a_pIResponseHandler->SetStatus(0, HResErr.Error(), NULL, NULL);
  349. if( pParsedPath )
  350. CObjectPathParser().Free( pParsedPath );
  351. hRes = HResErr.Error();
  352. }
  353. catch(...) {
  354. #ifdef DBG // In debug version, popup a message box for AV
  355. MessageBoxExA(NULL,"Wlbs Provider Failure.","Wlbs Provider Access Violation",
  356. MB_TOPMOST | MB_ICONHAND | MB_OK | MB_SERVICE_NOTIFICATION,LANG_USER_DEFAULT);
  357. #endif
  358. if( pParsedPath )
  359. CObjectPathParser().Free( pParsedPath );
  360. a_pIResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, NULL);
  361. hRes = WBEM_E_FAILED;
  362. }
  363. return hRes;
  364. }
  365. ////////////////////////////////////////////////////////////////////////////////
  366. //
  367. // CWLBSProvider::GetMOFSupportClass
  368. //
  369. // Purpose: Determines which MOF class is requested and instantiates the
  370. // appropriate internal support class.
  371. //
  372. ////////////////////////////////////////////////////////////////////////////////
  373. HRESULT CWLBSProvider::GetMOFSupportClass(
  374. LPCWSTR a_szObjectClass,
  375. auto_ptr<CWlbs_Root>& a_pMofClass,
  376. IWbemObjectSink* a_pResponseHandler )
  377. {
  378. HRESULT hRes = 0;
  379. try {
  380. for( DWORD i = 0; i < MOF_CLASSES::NumClasses; i++ ) {
  381. if( _wcsicmp( a_szObjectClass, MOF_CLASSES::g_szMOFClassList[i] ) == 0) {
  382. a_pMofClass = auto_ptr<CWlbs_Root>
  383. (MOF_CLASSES::g_pCreateFunc[i]( m_pNamespace, a_pResponseHandler ));
  384. break;
  385. }
  386. }
  387. }
  388. catch(CErrorWlbsControl Err) {
  389. IWbemClassObject* pWbemExtStat = NULL;
  390. CWlbs_Root::CreateExtendedStatus( m_pNamespace,
  391. &pWbemExtStat,
  392. Err.Error(),
  393. (PWCHAR)(Err.Description()) );
  394. a_pResponseHandler->SetStatus(0, WBEM_E_FAILED, NULL, pWbemExtStat);
  395. //do not return WBEM_E_FAILED, this causes a race condition
  396. hRes = WBEM_S_NO_ERROR;
  397. pWbemExtStat->Release();
  398. }
  399. return hRes;
  400. }
  401. ////////////////////////////////////////////////////////////////////////////////
  402. //
  403. // CWLBSProvider::ParseObjectPath
  404. //
  405. // Purpose:
  406. //
  407. ////////////////////////////////////////////////////////////////////////////////
  408. void CWLBSProvider::ParseObjectPath(
  409. const BSTR a_strObjectPath,
  410. ParsedObjectPath **a_pParsedObjectPath )
  411. {
  412. CObjectPathParser PathParser;
  413. ASSERT( a_pParsedObjectPath );
  414. //make sure this is NULL
  415. *a_pParsedObjectPath = NULL;
  416. int nStatus = PathParser.Parse(a_strObjectPath, a_pParsedObjectPath);
  417. if(nStatus != 0) {
  418. if( *a_pParsedObjectPath)
  419. PathParser.Free( *a_pParsedObjectPath );
  420. throw _com_error( WBEM_E_FAILED );
  421. }
  422. }
  423. ////////////////////////////////////////////////////////////////////////////////
  424. //
  425. // CWLBSProvider::GetClass
  426. //
  427. // Purpose: Retrieve the class name from an IWbemClassObject.
  428. //
  429. ////////////////////////////////////////////////////////////////////////////////
  430. void CWLBSProvider::GetClass(
  431. IWbemClassObject* a_pClassObject,
  432. wstring& a_szClass )
  433. {
  434. BSTR strClassName = NULL;
  435. VARIANT vClassName;
  436. HRESULT hRes;
  437. try {
  438. VariantInit( &vClassName );
  439. strClassName = SysAllocString( L"__Class" );
  440. if( !strClassName )
  441. throw _com_error( WBEM_E_OUT_OF_MEMORY );
  442. hRes = a_pClassObject->Get( strClassName,
  443. 0,
  444. &vClassName,
  445. NULL,
  446. NULL);
  447. if( FAILED( hRes ) )
  448. throw _com_error( hRes );
  449. a_szClass.assign( static_cast<LPWSTR>(vClassName.bstrVal) );
  450. // CLD: Need to check return code for error
  451. if (S_OK != VariantClear( &vClassName ))
  452. throw _com_error( WBEM_E_FAILED );
  453. if( strClassName ) {
  454. SysFreeString( strClassName );
  455. strClassName = NULL;
  456. }
  457. }
  458. catch( ... ) {
  459. // CLD: Need to check return code for error
  460. // No throw here since we are already throwing an exception.
  461. VariantClear( &vClassName );
  462. if( strClassName ) {
  463. SysFreeString( strClassName );
  464. strClassName = NULL;
  465. }
  466. throw;
  467. }
  468. }