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.

679 lines
21 KiB

  1. /////////////////////////////////////////////////////////////////////
  2. //
  3. // WMIProv.CPP
  4. //
  5. // Module: WMI Provider class methods
  6. //
  7. // Purpose: Provider class definition. An object of this class is
  8. // created by the class factory for each connection.
  9. //
  10. // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
  11. //
  12. /////////////////////////////////////////////////////////////////////
  13. #include "precomp.h"
  14. long glInits = -1;
  15. long glEventsRegistered = -1;
  16. long glProvObj = 0;
  17. extern CWMIEvent * g_pBinaryMofEvent;
  18. extern CCriticalSection * g_pSharedLocalEventsCs;
  19. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  20. void VerifyLocalEventsAreRegistered()
  21. {
  22. if( InterlockedIncrement(&glEventsRegistered) == 1 )
  23. {
  24. if( g_pBinaryMofEvent )
  25. {
  26. if( !g_pBinaryMofEvent->RegisterForInternalEvents())
  27. {
  28. glEventsRegistered = 0; // start over again next time
  29. }
  30. else
  31. {
  32. ERRORTRACE((THISPROVIDER,"Successfully Registered for Mof Events\n"));
  33. }
  34. }
  35. }
  36. ERRORTRACE((THISPROVIDER,"Local Events Verified called, glEventsRegistered: %ld\n", glEventsRegistered));
  37. }
  38. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  39. HRESULT SetupLocalEvents()
  40. {
  41. HRESULT hr = S_OK;
  42. CAutoBlock Block(g_pSharedLocalEventsCs);
  43. if( g_pBinaryMofEvent == NULL )
  44. {
  45. g_pBinaryMofEvent = (CWMIEvent *)new CWMIEvent(INTERNAL_EVENT); // This is the global guy that catches events of new drivers being added at runtime.
  46. if(g_pBinaryMofEvent)
  47. {
  48. glEventsRegistered = 0;
  49. VerifyLocalEventsAreRegistered();
  50. }
  51. else
  52. {
  53. hr = E_OUTOFMEMORY;
  54. }
  55. }
  56. return hr;
  57. }
  58. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  59. void DeleteLocalEvents()
  60. {
  61. CAutoBlock Block(g_pSharedLocalEventsCs);
  62. if( g_pBinaryMofEvent )
  63. {
  64. g_pBinaryMofEvent->DeleteAllLeftOverEvents();
  65. g_pBinaryMofEvent->DeleteBinaryMofResourceEvent();
  66. g_pBinaryMofEvent->ReleaseAllPointers();
  67. SAFE_DELETE_PTR(g_pBinaryMofEvent);
  68. glEventsRegistered = -1;
  69. ERRORTRACE((THISPROVIDER,"No longer registered for Mof events\n"));
  70. }
  71. }
  72. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  73. void ProcessAllBinaryMofs(CHandleMap * pMap, IWbemServices __RPC_FAR *pNamespace,IWbemContext __RPC_FAR *pCtx,BOOL bProcessMofs)
  74. {
  75. CWMIBinMof Mof;
  76. if( SUCCEEDED( Mof.Initialize(pMap,TRUE,WMIGUID_EXECUTE|WMIGUID_QUERY,pNamespace,NULL,pCtx)))
  77. {
  78. RevertToSelf();
  79. if(bProcessMofs)
  80. {
  81. Mof.ProcessListOfWMIBinaryMofsFromWMI();
  82. }
  83. //==============================================================
  84. // Register for hardcoded event to be notified of WMI updates
  85. // make it a member var, so it stays around for the life
  86. // of the provider
  87. //==============================================================
  88. if( g_pBinaryMofEvent )
  89. {
  90. CAutoBlock Block(g_pSharedLocalEventsCs);
  91. g_pBinaryMofEvent->SetEventServices(pNamespace);
  92. g_pBinaryMofEvent->SetEventContext(pCtx);
  93. g_pBinaryMofEvent->ReadyForInternalEvents(TRUE);
  94. VerifyLocalEventsAreRegistered();
  95. }
  96. }
  97. CheckImpersonationLevelAndVerifyInternalEvents(FALSE);
  98. }
  99. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  100. //*********************************************************************
  101. // Check the impersonation level
  102. //*********************************************************************
  103. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. HRESULT CheckImpersonationLevelAndVerifyInternalEvents(BOOL fVerifyLocalEvents)
  105. {
  106. HRESULT hr = WBEM_E_ACCESS_DENIED;
  107. HANDLE hThreadTok;
  108. if (IsNT())
  109. {
  110. if( GetUserThreadToken(&hThreadTok) )
  111. {
  112. DWORD dwImp, dwBytesReturned;
  113. if (GetTokenInformation( hThreadTok, TokenImpersonationLevel, &dwImp, sizeof(DWORD), &dwBytesReturned)){
  114. if( fVerifyLocalEvents )
  115. {
  116. if( glEventsRegistered < 2 )
  117. {
  118. VerifyLocalEventsAreRegistered();
  119. }
  120. }
  121. // Is the impersonation level Impersonate?
  122. if ((dwImp == SecurityImpersonation) || ( dwImp == SecurityDelegation) )
  123. {
  124. hr = WBEM_S_NO_ERROR;
  125. }
  126. else
  127. {
  128. hr = WBEM_E_ACCESS_DENIED;
  129. ERRORTRACE((THISPROVIDER,IDS_ImpersonationFailed));
  130. }
  131. }
  132. else
  133. {
  134. hr = WBEM_E_FAILED;
  135. ERRORTRACE((THISPROVIDER,IDS_ImpersonationFailed));
  136. }
  137. // Done with this handle
  138. CloseHandle(hThreadTok);
  139. }
  140. }
  141. else
  142. {
  143. // let win9X in...
  144. hr = WBEM_S_NO_ERROR;
  145. }
  146. return hr;
  147. }
  148. ////////////////////////////////////////////////////////////////////
  149. //
  150. //
  151. //
  152. ////////////////////////////////////////////////////////////////////
  153. HRESULT CWMI_Prov::PutInstanceAsync(IWbemClassObject __RPC_FAR * pIWbemClassObject,
  154. long lFlags,
  155. IWbemContext __RPC_FAR *pCtx,
  156. IWbemObjectSink __RPC_FAR *pHandler )
  157. {
  158. HRESULT hr = WBEM_E_FAILED;
  159. SetStructuredExceptionHandler seh;
  160. if(pIWbemClassObject == NULL || pHandler == NULL )
  161. {
  162. return WBEM_E_INVALID_PARAMETER;
  163. }
  164. //===========================================================
  165. // Get the class name
  166. //===========================================================
  167. CVARIANT vName;
  168. hr = pIWbemClassObject->Get(L"__CLASS", 0, &vName, NULL, NULL);
  169. if( SUCCEEDED(hr))
  170. {
  171. CWMIStandardShell WMI;
  172. if( SUCCEEDED(WMI.Initialize(vName.GetStr(),FALSE,&m_HandleMap,TRUE,WMIGUID_SET|WMIGUID_QUERY,m_pIWbemServices,pHandler,pCtx)))
  173. {
  174. if (SUCCEEDED(hr = CheckImpersonationLevelAndVerifyInternalEvents(TRUE)))
  175. {
  176. //=======================================================
  177. // If there is not a context object, then we know we are
  178. // supposed to put the whole thing, otherwise we are
  179. // supposed to put only the properties specified.
  180. //=======================================================
  181. try
  182. {
  183. if( !pCtx )
  184. {
  185. hr = WMI.FillInAndSubmitWMIDataBlob(pIWbemClassObject,PUT_WHOLE_INSTANCE,vName);
  186. }
  187. else
  188. {
  189. //===================================================
  190. // If we have a ctx object and the __PUT_EXTENSIONS
  191. // property is not specified, then we know we are
  192. // supposed to put the whole thing
  193. //===================================================
  194. CVARIANT vPut;
  195. if( SUCCEEDED(pCtx->GetValue(L"__PUT_EXT_PROPERTIES", 0, &vPut)))
  196. {
  197. hr = WMI.FillInAndSubmitWMIDataBlob(pIWbemClassObject,PUT_PROPERTIES_IN_LIST_ONLY,vPut);
  198. }
  199. else
  200. {
  201. hr = WMI.FillInAndSubmitWMIDataBlob(pIWbemClassObject,PUT_WHOLE_INSTANCE,vPut);
  202. }
  203. }
  204. }
  205. STANDARD_CATCH
  206. }
  207. }
  208. hr = WMI.SetErrorMessage(hr);
  209. }
  210. return hr;
  211. }
  212. ////////////////////////////////////////////////////////////////////
  213. //******************************************************************
  214. //
  215. // PUBLIC FUNCTIONS
  216. //
  217. //******************************************************************
  218. ////////////////////////////////////////////////////////////////////
  219. ////////////////////////////////////////////////////////////////////
  220. //
  221. // CWMI_Prov::CWMI_Prov
  222. //
  223. ////////////////////////////////////////////////////////////////////
  224. CWMI_Prov::CWMI_Prov()
  225. {
  226. #if defined(_AMD64_) || defined(_IA64_)
  227. m_Allocator = NULL;
  228. m_HashTable = NULL;
  229. m_ID = 0;
  230. try
  231. {
  232. InitializeCriticalSection(&m_CS);
  233. WmiAllocator t_Allocator ;
  234. WmiStatusCode t_StatusCode = t_Allocator.New (
  235. ( void ** ) & m_Allocator ,
  236. sizeof ( WmiAllocator )
  237. ) ;
  238. if ( t_StatusCode == e_StatusCode_Success )
  239. {
  240. :: new ( ( void * ) m_Allocator ) WmiAllocator ;
  241. t_StatusCode = m_Allocator->Initialize () ;
  242. if ( t_StatusCode != e_StatusCode_Success )
  243. {
  244. t_Allocator.Delete ( ( void * ) m_Allocator ) ;
  245. m_Allocator = NULL;
  246. DeleteCriticalSection(&m_CS);
  247. }
  248. else
  249. {
  250. m_HashTable = ::new WmiHashTable <LONG, ULONG_PTR, 17> ( *m_Allocator ) ;
  251. t_StatusCode = m_HashTable->Initialize () ;
  252. if ( t_StatusCode != e_StatusCode_Success )
  253. {
  254. m_HashTable->UnInitialize () ;
  255. ::delete m_HashTable;
  256. m_HashTable = NULL;
  257. m_Allocator->UnInitialize ();
  258. t_Allocator.Delete ( ( void * ) m_Allocator ) ;
  259. m_Allocator = NULL;
  260. DeleteCriticalSection(&m_CS);
  261. }
  262. }
  263. }
  264. else
  265. {
  266. m_Allocator = NULL;
  267. DeleteCriticalSection(&m_CS);
  268. }
  269. }
  270. catch (...)
  271. {
  272. }
  273. #endif
  274. m_cRef=0;
  275. m_pIWbemServices = NULL;
  276. InterlockedIncrement(&g_cObj);
  277. InterlockedIncrement(&glProvObj);
  278. ERRORTRACE((THISPROVIDER,"Instance Provider constructed\n"));
  279. }
  280. ////////////////////////////////////////////////////////////////////
  281. //
  282. // CWMI_Prov::~CWMI_Prov
  283. //
  284. ////////////////////////////////////////////////////////////////////
  285. CWMI_Prov::~CWMI_Prov(void)
  286. {
  287. SAFE_RELEASE_PTR( m_pIWbemServices );
  288. InterlockedDecrement(&g_cObj);
  289. if(InterlockedDecrement(&glProvObj) == 0)
  290. {
  291. glInits = -1;
  292. }
  293. ERRORTRACE((THISPROVIDER,"Instance Provider destructed\n"));
  294. #if defined(_AMD64_) || defined(_IA64_)
  295. if (m_HashTable)
  296. {
  297. WmiAllocator t_Allocator ;
  298. m_HashTable->UnInitialize () ;
  299. ::delete m_HashTable;
  300. m_HashTable = NULL;
  301. m_Allocator->UnInitialize ();
  302. t_Allocator.Delete ( ( void * ) m_Allocator ) ;
  303. m_Allocator = NULL;
  304. DeleteCriticalSection(&m_CS);
  305. }
  306. #endif
  307. }
  308. ////////////////////////////////////////////////////////////////////
  309. //
  310. // QueryInterface
  311. //
  312. ////////////////////////////////////////////////////////////////////
  313. STDMETHODIMP CWMI_Prov::QueryInterface(REFIID riid, PPVOID ppvObj)
  314. {
  315. HRESULT hr = E_NOINTERFACE;
  316. *ppvObj = NULL;
  317. if (IsEqualIID(riid, IID_IUnknown))
  318. {
  319. *ppvObj =(IWbemServices *) this ;
  320. }
  321. else if (IsEqualIID(riid, IID_IWbemServices))
  322. {
  323. *ppvObj =(IWbemServices *) this ;
  324. }
  325. else if (IsEqualIID(riid, IID_IWbemProviderInit))
  326. {
  327. *ppvObj = (IWbemProviderInit *) this ;
  328. }
  329. else if(riid == IID_IWbemProviderInit)
  330. {
  331. *ppvObj = (LPVOID)(IWbemProviderInit*)this;
  332. }
  333. else if (riid == IID_IWbemHiPerfProvider)
  334. {
  335. *ppvObj = (LPVOID)(IWbemHiPerfProvider*)this;
  336. }
  337. if(*ppvObj)
  338. {
  339. AddRef();
  340. hr = NOERROR;
  341. }
  342. return hr;
  343. }
  344. /////////////////////////////////////////////////////////////////////
  345. HRESULT CWMI_Prov::Initialize(
  346. /* [in] */ LPWSTR pszUser,
  347. /* [in] */ LONG lFlags,
  348. /* [in] */ LPWSTR pszNamespace,
  349. /* [in] */ LPWSTR pszLocale,
  350. /* [in] */ IWbemServices __RPC_FAR *pNamespace,
  351. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  352. /* [in] */ IWbemProviderInitSink __RPC_FAR *pInitSink)
  353. {
  354. if(pNamespace == NULL){
  355. return WBEM_E_INVALID_PARAMETER;
  356. }
  357. //===============================================
  358. m_pIWbemServices = pNamespace;
  359. m_pIWbemServices->AddRef();
  360. if( InterlockedIncrement(&glInits) == 0 )
  361. {
  362. ProcessAllBinaryMofs(&m_HandleMap, pNamespace, pCtx);
  363. }
  364. pInitSink->SetStatus(WBEM_S_NO_ERROR, 0);
  365. return WBEM_S_NO_ERROR;
  366. }
  367. //////////////////////////////////////////////////////////////////////
  368. STDMETHODIMP_(ULONG) CWMI_Prov::AddRef(void)
  369. {
  370. return InterlockedIncrement((long*)&m_cRef);
  371. }
  372. STDMETHODIMP_(ULONG) CWMI_Prov::Release(void)
  373. {
  374. ULONG cRef = InterlockedDecrement( (long*) &m_cRef);
  375. if ( !cRef ){
  376. delete this;
  377. return 0;
  378. }
  379. return cRef;
  380. }
  381. ////////////////////////////////////////////////////////////////////
  382. //
  383. // CWMI_Prov::OpenNamespace
  384. //
  385. ////////////////////////////////////////////////////////////////////
  386. HRESULT CWMI_Prov::OpenNamespace(
  387. /* [in] */ BSTR Namespace,
  388. /* [in] */ long lFlags,
  389. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  390. /* [unique][in][out] */ IWbemServices __RPC_FAR *__RPC_FAR *ppWorkingNamespace,
  391. /* [unique][in][out] */ IWbemCallResult __RPC_FAR *__RPC_FAR *ppResult)
  392. {
  393. return WBEM_E_PROVIDER_NOT_CAPABLE ;
  394. }
  395. ////////////////////////////////////////////////////////////////////
  396. //
  397. // CWMI_Prov::CreateInstanceEnumAsync
  398. //
  399. // Purpose: Asynchronously enumerates the instances of the
  400. // given class.
  401. //
  402. ////////////////////////////////////////////////////////////////
  403. HRESULT CWMI_Prov::CreateInstanceEnumAsync(BSTR wcsClass,
  404. long lFlags,
  405. IWbemContext __RPC_FAR *pCtx,
  406. IWbemObjectSink __RPC_FAR * pHandler)
  407. {
  408. HRESULT hr = WBEM_E_FAILED;
  409. SetStructuredExceptionHandler seh;
  410. CWMIStandardShell WMI;
  411. if( SUCCEEDED(WMI.Initialize(wcsClass,FALSE,&m_HandleMap,TRUE,WMIGUID_QUERY,m_pIWbemServices,pHandler,pCtx)))
  412. {
  413. if (SUCCEEDED(hr = CheckImpersonationLevelAndVerifyInternalEvents(TRUE)))
  414. {
  415. //============================================================
  416. // Init and get the WMI Data block
  417. //============================================================
  418. if( pHandler != NULL )
  419. {
  420. //============================================================
  421. // Parse through all of it
  422. //============================================================
  423. try
  424. {
  425. hr = WMI.ProcessAllInstances();
  426. }
  427. STANDARD_CATCH
  428. }
  429. }
  430. WMI.SetErrorMessage(hr);
  431. }
  432. return hr;
  433. }
  434. //***************************************************************************
  435. HRESULT CWMI_Prov::ExecQueryAsync( BSTR QueryLanguage,
  436. BSTR Query,
  437. long lFlags,
  438. IWbemContext __RPC_FAR *pCtx,
  439. IWbemObjectSink __RPC_FAR *pHandler)
  440. {
  441. WCHAR wcsClass[_MAX_PATH+2];
  442. HRESULT hr = WBEM_E_FAILED;
  443. SetStructuredExceptionHandler seh;
  444. BOOL fRc = FALSE;
  445. //============================================================
  446. // Do a check of arguments and make sure we have pointers
  447. //============================================================
  448. if( pHandler == NULL )
  449. {
  450. return WBEM_E_INVALID_PARAMETER;
  451. }
  452. try
  453. {
  454. //============================================================
  455. // Get the properties and class to get
  456. //============================================================
  457. fRc = GetParsedPropertiesAndClass(Query,wcsClass);
  458. }
  459. STANDARD_CATCH
  460. CWMIStandardShell WMI;
  461. if( SUCCEEDED(WMI.Initialize(wcsClass,FALSE,&m_HandleMap,TRUE,WMIGUID_NOTIFICATION|WMIGUID_QUERY,m_pIWbemServices,pHandler,pCtx)))
  462. {
  463. if( fRc )
  464. {
  465. hr = CheckImpersonationLevelAndVerifyInternalEvents(TRUE);
  466. }
  467. hr = WMI.SetErrorMessage(hr);
  468. }
  469. return hr;
  470. }
  471. //***************************************************************************
  472. //
  473. // CWMI_Prov::GetObjectAsync
  474. //
  475. // Purpose: Asynchronously creates an instance given a particular path value.
  476. //
  477. // NOTE 1: If there is an instance name in the returned WNODE, then this is a
  478. // dynamic instance. You can tell because the pWNSI->OffsetInstanceName
  479. // field will not be blank. If this is the case, then the name will not
  480. // be contained within the datablock, but must instead be retrieved
  481. // from the WNODE. See NOTE 1, below.
  482. //
  483. //***************************************************************************
  484. HRESULT CWMI_Prov::GetObjectAsync(BSTR ObjectPath, long lFlags,
  485. IWbemContext __RPC_FAR *pCtx,
  486. IWbemObjectSink __RPC_FAR * pHandler )
  487. {
  488. HRESULT hr = WBEM_E_NOT_FOUND;
  489. SetStructuredExceptionHandler seh;
  490. WCHAR wcsClass[_MAX_PATH*2];
  491. WCHAR wcsInstance[_MAX_PATH*2];
  492. //============================================================
  493. // Do a check of arguments and make sure we have pointers
  494. //============================================================
  495. if(ObjectPath == NULL || pHandler == NULL )
  496. {
  497. return WBEM_E_INVALID_PARAMETER;
  498. }
  499. try
  500. {
  501. memset(wcsClass,NULL,_MAX_PATH*2);
  502. //============================================================
  503. // Get the path and instance name
  504. //============================================================
  505. hr = GetParsedPath( ObjectPath,wcsClass,wcsInstance,m_pIWbemServices );
  506. }
  507. STANDARD_CATCH
  508. if( SUCCEEDED(hr) )
  509. {
  510. if (SUCCEEDED(hr = CheckImpersonationLevelAndVerifyInternalEvents(TRUE)))
  511. {
  512. try
  513. {
  514. CWMIStandardShell WMI;
  515. if( SUCCEEDED(WMI.Initialize(wcsClass,FALSE,&m_HandleMap,TRUE,WMIGUID_QUERY,m_pIWbemServices,pHandler,pCtx)))
  516. {
  517. //============================================================
  518. // Get the WMI Block
  519. //============================================================
  520. hr = WMI.ProcessSingleInstance(wcsInstance);
  521. hr = WMI.SetErrorMessage(hr);
  522. }
  523. }
  524. STANDARD_CATCH
  525. }
  526. }
  527. return hr;
  528. }
  529. /************************************************************************
  530. * *
  531. *CWMIMethod::ExecMethodAsync *
  532. * *
  533. *Purpose: This is the Async function implementation *
  534. ************************************************************************/
  535. STDMETHODIMP CWMI_Prov::ExecMethodAsync(BSTR ObjectPath,
  536. BSTR MethodName,
  537. long lFlags,
  538. IWbemContext __RPC_FAR * pCtx,
  539. IWbemClassObject __RPC_FAR * pIWbemClassObject,
  540. IWbemObjectSink __RPC_FAR * pHandler)
  541. {
  542. CVARIANT vName;
  543. HRESULT hr = WBEM_E_FAILED;
  544. IWbemClassObject * pClass = NULL; //This is an IWbemClassObject.
  545. WCHAR wcsClass[_MAX_PATH*2];
  546. WCHAR wcsInstance[_MAX_PATH*2];
  547. SetStructuredExceptionHandler seh;
  548. try
  549. {
  550. //============================================================
  551. // Get the path and instance name and check to make sure it
  552. // is valid
  553. //============================================================
  554. hr = GetParsedPath( ObjectPath,wcsClass,wcsInstance ,m_pIWbemServices);
  555. }
  556. STANDARD_CATCH
  557. CWMIStandardShell WMI;
  558. if( SUCCEEDED(WMI.Initialize(wcsClass,FALSE,&m_HandleMap,TRUE,WMIGUID_EXECUTE|WMIGUID_QUERY,m_pIWbemServices,pHandler,pCtx)))
  559. {
  560. if (SUCCEEDED(hr = CheckImpersonationLevelAndVerifyInternalEvents(TRUE)))
  561. {
  562. //================================================================
  563. // We are ok, so proceed
  564. //================================================================
  565. hr = m_pIWbemServices->GetObject(wcsClass, 0, pCtx, &pClass, NULL);
  566. if( SUCCEEDED(hr) )
  567. {
  568. //==========================================================
  569. // Now, get the list of Input and Output parameters
  570. //==========================================================
  571. IWbemClassObject * pOutClass = NULL; //This is an IWbemClassObject.
  572. IWbemClassObject * pInClass = NULL; //This is an IWbemClassObject.
  573. hr = pClass->GetMethod(MethodName, 0, &pInClass, &pOutClass);
  574. if( SUCCEEDED(hr) )
  575. {
  576. try
  577. {
  578. hr = WMI.ExecuteMethod( wcsInstance, MethodName,pClass, pIWbemClassObject,pInClass, pOutClass);
  579. }
  580. STANDARD_CATCH
  581. }
  582. SAFE_RELEASE_PTR( pOutClass );
  583. SAFE_RELEASE_PTR( pInClass );
  584. SAFE_RELEASE_PTR( pClass );
  585. }
  586. }
  587. hr = WMI.SetErrorMessage(hr);
  588. }
  589. return hr;
  590. }
  591. /////////////////////////////////////////////////////////////////////
  592. HRESULT CWMIHiPerfProvider::Initialize(
  593. /* [in] */ LPWSTR pszUser,
  594. /* [in] */ LONG lFlags,
  595. /* [in] */ LPWSTR pszNamespace,
  596. /* [in] */ LPWSTR pszLocale,
  597. /* [in] */ IWbemServices __RPC_FAR *pNamespace,
  598. /* [in] */ IWbemContext __RPC_FAR *pCtx,
  599. /* [in] */ IWbemProviderInitSink __RPC_FAR *pInitSink)
  600. {
  601. if(pNamespace == NULL){
  602. return WBEM_E_INVALID_PARAMETER;
  603. }
  604. //===============================================
  605. m_pIWbemServices = pNamespace;
  606. m_pIWbemServices->AddRef();
  607. if( InterlockedIncrement(&glInits) == 0 )
  608. {
  609. ProcessAllBinaryMofs(&m_HandleMap, pNamespace, pCtx,FALSE);
  610. }
  611. pInitSink->SetStatus(WBEM_S_NO_ERROR, 0);
  612. return WBEM_S_NO_ERROR;
  613. }
  614. ////////////////////////////////////////////////////////////////////
  615. //******************************************************************
  616. //
  617. // PRIVATE FUNCTIONS
  618. //
  619. //******************************************************************
  620. ////////////////////////////////////////////////////////////////////