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.

515 lines
16 KiB

  1. ////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMI OLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. ////////////////////////////////////////////////////////////////////////////////////////////////
  7. #include "headers.h"
  8. ////////////////////////////////////////////////////////////////////////////////////////////////
  9. //
  10. // Constructor
  11. //
  12. ////////////////////////////////////////////////////////////////////////////////////////////////
  13. CDataSource::CDataSource( LPUNKNOWN pUnkOuter ) : CBaseObj(BOT_DATASOURCE, pUnkOuter)
  14. {
  15. //===============================================
  16. // Initialize simple member vars
  17. //===============================================
  18. m_cRef = 0L;
  19. m_fDSOInitialized = FALSE;
  20. m_fDBSessionCreated = FALSE;
  21. m_pUtilProp = NULL;
  22. //===============================================
  23. // Initially, NULL all contained interfaces
  24. //===============================================
  25. m_pIDBInitialize = NULL;
  26. m_pIDBProperties = NULL;
  27. m_pIDBInfo = NULL;
  28. m_pIDBCreateSession = NULL;
  29. m_pIPersistFile = NULL;
  30. m_pWbemWrap = NULL;
  31. m_pISupportErrorInfo = NULL;
  32. m_pIDBDataSourceAdmin = NULL;
  33. m_pIObjectAccessControl = NULL;
  34. m_pISecurityInfo = NULL;
  35. m_strPersistFileName = Wmioledb_SysAllocString(NULL);
  36. m_bIsPersitFileDirty = TRUE;
  37. //===============================================
  38. // Increment global object count.
  39. //===============================================
  40. InterlockedIncrement(&g_cObj);
  41. }
  42. ////////////////////////////////////////////////////////////////////////////////////////////////
  43. //
  44. // Destructor
  45. //
  46. ////////////////////////////////////////////////////////////////////////////////////////////////
  47. CDataSource:: ~CDataSource( void )
  48. {
  49. ULONG ulRefCount;
  50. //===============================================
  51. // Decrement the ref count on the data conversion
  52. // object
  53. //===============================================
  54. if( g_pIDataConvert ){
  55. ulRefCount = g_pIDataConvert->Release();
  56. //===========================================
  57. // Is it gone for good?
  58. //===========================================
  59. if( !ulRefCount )
  60. g_pIDataConvert = NULL;
  61. }
  62. //===============================================
  63. // Free properties management object and
  64. // contained interfaces
  65. //===============================================
  66. SAFE_DELETE_PTR( m_pUtilProp );
  67. SAFE_DELETE_PTR( m_pIDBInitialize );
  68. SAFE_DELETE_PTR( m_pIDBProperties );
  69. SAFE_DELETE_PTR( m_pIDBInfo );
  70. SAFE_DELETE_PTR( m_pIDBCreateSession );
  71. SAFE_DELETE_PTR( m_pIPersistFile );
  72. SAFE_DELETE_PTR( m_pWbemWrap );
  73. SAFE_DELETE_PTR( m_pISupportErrorInfo );
  74. SAFE_DELETE_PTR(m_pIDBDataSourceAdmin);
  75. SAFE_DELETE_PTR(m_pIObjectAccessControl);
  76. SAFE_DELETE_PTR(m_pISecurityInfo);
  77. SysFreeString(m_strPersistFileName);
  78. //===============================================
  79. // Decrement global object count.
  80. //===============================================
  81. InterlockedDecrement(&g_cObj);
  82. }
  83. //////////////////////////////////////////////////////////////////////////////////////////////////
  84. // Initialize the command Object
  85. //
  86. ////////////////////////////////////////////////////////////////////////////////////////////////
  87. HRESULT CDataSource::FInit( void )
  88. {
  89. HRESULT hr = S_OK;
  90. BOOL bRet = TRUE;
  91. //================================================
  92. // Instantiate the data conversion service object
  93. //================================================
  94. if( !g_pIDataConvert ){
  95. hr = CoCreateInstance(CLSID_OLEDB_CONVERSIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, IID_IDataConvert, (void **)&g_pIDataConvert);
  96. }
  97. else
  98. {
  99. //============================================
  100. // Already instantiated, increment reference
  101. // count
  102. //============================================
  103. g_pIDataConvert->AddRef();
  104. }
  105. if(SUCCEEDED(hr))
  106. {
  107. IDCInfo *pDcInfo = NULL;
  108. DCINFO dcInfo[1];
  109. dcInfo[0].eInfoType = DCINFOTYPE_VERSION;
  110. V_VT(&dcInfo[0].vData) = VT_UI4;
  111. V_UI4(&dcInfo[0].vData) = 0x200;
  112. hr = g_pIDataConvert->QueryInterface(IID_IDCInfo,(void **)&pDcInfo);
  113. hr = pDcInfo->SetInfo(1,dcInfo);
  114. hr = E_OUTOFMEMORY;
  115. m_pWbemWrap = new CWbemConnectionWrapper();
  116. if(m_pWbemWrap == NULL)
  117. {
  118. hr = E_OUTOFMEMORY;
  119. }
  120. else
  121. if(SUCCEEDED(hr = m_pWbemWrap->FInit()))
  122. {
  123. //================================================
  124. // Allocate properties management object
  125. //================================================
  126. m_pUtilProp = new CUtilProp;
  127. // NTRaid: 136443
  128. // 07/05/00
  129. if(m_pUtilProp == NULL)
  130. {
  131. hr = E_OUTOFMEMORY;
  132. }
  133. else
  134. if(SUCCEEDED(hr = m_pUtilProp->FInit(DATASOURCEPROP)))
  135. {
  136. //================================================
  137. // Allocate contained interface objects
  138. //================================================
  139. m_pIDBInitialize = new CImpIDBInitialize( this );
  140. m_pIDBProperties = new CImpIDBProperties( this );
  141. m_pIDBInfo = new CImpIDBInfo( this );
  142. m_pIDBCreateSession = new CImpIDBCreateSession( this );
  143. m_pIPersistFile = new CImpIPersistFile( this );
  144. m_pISupportErrorInfo = new CImpISupportErrorInfo(this);
  145. m_pIDBDataSourceAdmin = new CImpIDBDataSrcAdmin(this);
  146. m_pIObjectAccessControl = new CImpIObjectAccessControl(this);
  147. m_pISecurityInfo = new CImpISecurityInfo(this);
  148. if(m_pUtilProp && m_pIDBInitialize && m_pIDBInfo && m_pIDBProperties &&
  149. m_pIDBCreateSession && m_pIPersistFile && m_pISupportErrorInfo &&
  150. m_pIDBDataSourceAdmin && m_pIObjectAccessControl && m_pISecurityInfo)
  151. {
  152. hr = S_OK;
  153. }
  154. else
  155. {
  156. hr = E_OUTOFMEMORY;
  157. }
  158. }
  159. }
  160. }
  161. if(SUCCEEDED(hr))
  162. {
  163. hr = AddInterfacesForISupportErrorInfo();
  164. }
  165. return hr;
  166. }
  167. /////////////////////////////////////////////////////////////////////////////////////////////////////
  168. // Function to add interfaces to ISupportErrorInfo interface
  169. /////////////////////////////////////////////////////////////////////////////////////////////////////
  170. HRESULT CDataSource::AddInterfacesForISupportErrorInfo()
  171. {
  172. HRESULT hr = S_OK;
  173. if(SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IDBInitialize)) &&
  174. SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IDBInfo)) &&
  175. SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IDBProperties)) &&
  176. SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IPersist)) &&
  177. SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IDBDataSourceAdmin)) &&
  178. SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IObjectAccessControl)) &&
  179. SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_ISecurityInfo)))
  180. {
  181. hr = m_pISupportErrorInfo->AddInterfaceID(IID_IPersistFile);
  182. }
  183. if(SUCCEEDED(hr) && m_fDSOInitialized)
  184. {
  185. hr = m_pISupportErrorInfo->AddInterfaceID(IID_IDBCreateSession);
  186. }
  187. return hr;
  188. }
  189. ////////////////////////////////////////////////////////////////////////////////////////////////
  190. //
  191. // Returns a pointer to a specified interface.
  192. // Callers use QueryInterface to determine which interfaces the called object supports.
  193. //s
  194. // HRESULT indicating the status of the method
  195. // S_OK | Interface is supported and ppvObject is set.
  196. // E_NOINTERFACE | Interface is not supported by the object
  197. // E_INVALIDARG | One or more arguments are invalid.
  198. //
  199. ////////////////////////////////////////////////////////////////////////////////////////////////
  200. STDMETHODIMP CDataSource::QueryInterface( REFIID riid, //@parm IN | Interface ID of the interface being queried for.
  201. LPVOID * ppv //@parm OUT | Pointer to interface that was instantiated
  202. )
  203. {
  204. HRESULT hr = E_INVALIDARG;
  205. //=================================================
  206. // Is the pointer bad?
  207. //=================================================
  208. if (ppv != NULL){
  209. //=================================================
  210. // Place NULL in *ppv in case of failure and init
  211. // stuff
  212. //=================================================
  213. *ppv = NULL;
  214. hr = S_OK;
  215. //=================================================
  216. // This is the non-delegating IUnknown
  217. // implementation
  218. //=================================================
  219. if( riid == IID_IUnknown){
  220. *ppv = (LPVOID) this;
  221. }
  222. else if( riid == IID_IDBInitialize ){
  223. *ppv = (LPVOID) m_pIDBInitialize;
  224. }
  225. else if( riid == IID_IDBInfo && m_fDSOInitialized){
  226. *ppv = (LPVOID) m_pIDBInfo;
  227. }
  228. else if( riid == IID_IDBProperties ){
  229. *ppv = (LPVOID) m_pIDBProperties;
  230. }
  231. else if( riid == IID_IPersist || riid == IID_IPersistFile){
  232. *ppv = (LPVOID) m_pIPersistFile;
  233. }
  234. else if( riid == IID_IDBCreateSession && m_fDSOInitialized ){
  235. *ppv = (LPVOID)m_pIDBCreateSession;
  236. }
  237. else if(riid == IID_ISupportErrorInfo)
  238. {
  239. *ppv = (LPVOID)m_pISupportErrorInfo;
  240. }
  241. else if(riid == IID_IDBDataSourceAdmin)
  242. {
  243. *ppv = (LPVOID)m_pIDBDataSourceAdmin;
  244. }
  245. else if(riid == IID_IObjectAccessControl)
  246. {
  247. *ppv = (LPVOID)m_pIObjectAccessControl;
  248. }
  249. else if(riid == IID_ISecurityInfo)
  250. {
  251. *ppv = (LPVOID)m_pISecurityInfo;
  252. }
  253. //======================================
  254. // Special case for uninitialized.
  255. //======================================
  256. else if( *ppv && !m_fDSOInitialized ){
  257. *ppv = NULL;
  258. hr = E_UNEXPECTED;
  259. }
  260. else{
  261. //==================================
  262. // We don't support this interface
  263. //==================================
  264. hr = E_NOINTERFACE;
  265. }
  266. //==============================================
  267. // If we're going to return an interface,
  268. // AddRef it first
  269. //==============================================
  270. if( S_OK == hr){
  271. if (*ppv){
  272. ((LPUNKNOWN) *ppv)->AddRef();
  273. }
  274. }
  275. }
  276. return hr;
  277. }
  278. ////////////////////////////////////////////////////////////////////////////////////////////////
  279. //
  280. // Increments a persistence count for the object
  281. //
  282. ////////////////////////////////////////////////////////////////////////////////////////////////
  283. STDMETHODIMP_( ULONG ) CDataSource::AddRef( void )
  284. {
  285. return InterlockedIncrement((long*)&m_cRef);
  286. }
  287. ////////////////////////////////////////////////////////////////////////////////////////////////
  288. //
  289. // Decrements a persistence count for the object and if persistence count is 0, the object
  290. // destroys itself.
  291. //
  292. ////////////////////////////////////////////////////////////////////////////////////////////////
  293. STDMETHODIMP_( ULONG ) CDataSource::Release( void )
  294. {
  295. InterlockedDecrement((long*)&m_cRef);
  296. if (!m_cRef){
  297. delete this;
  298. return 0;
  299. }
  300. return m_cRef;
  301. }
  302. ////////////////////////////////////////////////////////////////////////////////////////////////
  303. // Get value of a property of datasource
  304. ////////////////////////////////////////////////////////////////////////////////////////////////
  305. HRESULT CDataSource::GetDataSrcProperty(DBPROPID propId , VARIANT & varValue)
  306. {
  307. DBPROPIDSET rgPropertyIDSets[1];
  308. ULONG cPropertySets = 0;
  309. DBPROPSET* prgPropertySets = NULL;
  310. DBPROPID rgPropId[1];
  311. HRESULT hr = S_OK;
  312. VariantClear(&varValue);
  313. //========================================================================
  314. // Get the value of the required property
  315. //========================================================================
  316. rgPropertyIDSets[0].guidPropertySet = DBPROPSET_DBINIT;
  317. rgPropertyIDSets[0].rgPropertyIDs = rgPropId;
  318. rgPropertyIDSets[0].cPropertyIDs = 1;
  319. rgPropId[0] = propId;
  320. if( S_OK == (hr = m_pUtilProp->GetProperties( PROPSET_DSOINIT, 1, rgPropertyIDSets,&cPropertySets, &prgPropertySets )))
  321. VariantCopy(&varValue,&prgPropertySets->rgProperties->vValue);
  322. //==========================================================================
  323. // Free memory we allocated to by GetProperties
  324. //==========================================================================
  325. m_pUtilProp->m_PropMemMgr.FreeDBPROPSET( cPropertySets, prgPropertySets);
  326. return hr;
  327. }
  328. //////////////////////////////////////////////////////////////////////////////////////////////
  329. // Function to adjust the privelige tokens as set in the properties
  330. //////////////////////////////////////////////////////////////////////////////////////////////
  331. HRESULT CDataSource::AdjustPreviligeTokens()
  332. {
  333. DBPROPIDSET rgPropertyIDSets[1];
  334. ULONG cPropertySets;
  335. DBPROPSET* prgPropertySets;
  336. HRESULT hr = S_OK;
  337. rgPropertyIDSets[0].guidPropertySet = DBPROPSET_WMIOLEDB_DBINIT;
  338. rgPropertyIDSets[0].rgPropertyIDs = NULL;
  339. rgPropertyIDSets[0].cPropertyIDs = 0;
  340. if(SUCCEEDED(hr = m_pUtilProp->GetProperties(PROPSET_DSO,1,rgPropertyIDSets,&cPropertySets,&prgPropertySets)))
  341. {
  342. if(!(m_pWbemWrap->AdjustTokenPrivileges(prgPropertySets->cProperties ,prgPropertySets->rgProperties)))
  343. {
  344. hr = E_FAIL;
  345. }
  346. //==========================================================================
  347. // Free memory we allocated to get the namespace property above
  348. //==========================================================================
  349. m_pUtilProp->m_PropMemMgr.FreeDBPROPSET( cPropertySets, prgPropertySets);
  350. }
  351. return hr;
  352. }
  353. HRESULT CDataSource::InitializeConnectionProperties()
  354. {
  355. HRESULT hr = S_OK;
  356. DBPROPIDSET rgPropertyIDSets[1];
  357. ULONG cPropertySets;
  358. DBPROPSET* prgPropertySets;
  359. DBPROPID rgPropId[7];
  360. DWORD dwAuthnLevel;
  361. DWORD dwImpLevel;
  362. rgPropId[0] = DBPROP_INIT_DATASOURCE;
  363. rgPropId[1] = DBPROP_INIT_PROTECTION_LEVEL;
  364. rgPropId[2] = DBPROP_INIT_IMPERSONATION_LEVEL;
  365. rgPropId[3] = DBPROP_AUTH_USERID;
  366. rgPropId[4] = DBPROP_AUTH_PASSWORD;
  367. rgPropId[5] = DBPROP_INIT_LCID;
  368. rgPropId[6] = DBPROP_WMIOLEDB_AUTHORITY;
  369. rgPropertyIDSets[0].guidPropertySet = DBPROPSET_DBINIT;
  370. rgPropertyIDSets[0].rgPropertyIDs = rgPropId;
  371. rgPropertyIDSets[0].cPropertyIDs = 7;
  372. //==============================================================================
  373. // Get the value of the DBPROP_INIT_DATASOURCE property, this is the namespace
  374. // to be opened.
  375. //==============================================================================
  376. hr = m_pUtilProp->GetProperties( PROPSET_DSO,1, rgPropertyIDSets,&cPropertySets,&prgPropertySets );
  377. if( SUCCEEDED(hr) )
  378. {
  379. //==========================================================================
  380. // now, set the namespace, if this isn't a valid namespace, then it reverts
  381. // to the default
  382. //==========================================================================
  383. m_pWbemWrap->SetValidNamespace(&(prgPropertySets[0].rgProperties[0].vValue));
  384. m_pWbemWrap->SetUserInfo(prgPropertySets[0].rgProperties[3].vValue.bstrVal,
  385. prgPropertySets[0].rgProperties[4].vValue.bstrVal,
  386. prgPropertySets[0].rgProperties[6].vValue.bstrVal);
  387. // convert the OLEDB prop value to the actual value
  388. dwAuthnLevel = GetAuthnLevel(prgPropertySets[0].rgProperties[1].vValue.lVal);
  389. dwImpLevel = GetImpLevel(prgPropertySets[0].rgProperties[2].vValue.lVal);
  390. m_pWbemWrap->SetLocale(prgPropertySets[0].rgProperties[5].vValue.lVal);
  391. m_pWbemWrap->SetConnAttributes(dwAuthnLevel,dwImpLevel);
  392. //==========================================================================
  393. // Free memory we allocated to get the namespace property above
  394. //==========================================================================
  395. m_pUtilProp->m_PropMemMgr.FreeDBPROPSET( cPropertySets, prgPropertySets);
  396. }
  397. return hr;
  398. }
  399. HRESULT CDataSource::CreateSession(IUnknown* pUnkOuter, //IN Controlling IUnknown if being aggregated
  400. REFIID riid, //IN The ID of the interface
  401. IUnknown** ppDBSession)
  402. {
  403. CDBSession* pDBSession = NULL;
  404. HRESULT hr = S_OK;
  405. try
  406. {
  407. //=========================================================
  408. // open a DBSession object
  409. //=========================================================
  410. pDBSession = new CDBSession( pUnkOuter );
  411. }
  412. catch(...)
  413. {
  414. SAFE_DELETE_PTR(pDBSession);
  415. throw;
  416. }
  417. if (!pDBSession){
  418. hr = E_OUTOFMEMORY;
  419. }
  420. else
  421. {
  422. //=====================================================
  423. // initialize the object
  424. //=====================================================
  425. if (FAILED(hr = pDBSession->FInit(this)))
  426. {
  427. SAFE_DELETE_PTR( pDBSession );
  428. }
  429. else
  430. {
  431. //=================================================
  432. // get requested interface pointer on DBSession
  433. //=================================================
  434. hr = pDBSession->QueryInterface( riid, (void **) ppDBSession );
  435. if (FAILED( hr ))
  436. {
  437. SAFE_DELETE_PTR( pDBSession );
  438. }
  439. else
  440. {
  441. //=============================================
  442. // all went well
  443. //=============================================
  444. m_fDBSessionCreated = TRUE;
  445. }
  446. }
  447. }
  448. return hr;
  449. }