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.

681 lines
18 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: cdso.cxx
  7. //
  8. // Contents: Microsoft OleDB/OleDS Data Source Object for ADSI
  9. //
  10. //
  11. // History: 08-01-96 shanksh Created.
  12. //
  13. //------------------------------------------------------------------------------
  14. #include "oleds.hxx"
  15. #pragma hdrstop
  16. extern LONG glnOledbObjCnt;
  17. //+---------------------------------------------------------------------------
  18. //
  19. // Function: CDSOObject::CreateDSOObject
  20. //
  21. // Synopsis: Creates a new DB Session object from the DSO, and returns the
  22. // requested interface on the newly created object.
  23. //
  24. // Arguments: pUnkOuter Controlling IUnknown if being aggregated
  25. // riid The ID of the interface
  26. // ppDBSession A pointer to memory in which to return the
  27. // interface pointer
  28. //
  29. // Returns:
  30. // S_OK The method succeeded.
  31. // E_INVALIDARG ppDBSession was NULL
  32. // DB_E_NOAGGREGATION pUnkOuter was not NULL (this object
  33. // does not support being aggregated)
  34. // E_FAIL Provider-specific error. This
  35. // E_OUTOFMEMORY Out of memory
  36. // E_NOINTERFACE Could not obtain requested interface on
  37. // DBSession object
  38. //
  39. // Modifies:
  40. //
  41. // History: 08-28-96 ShankSh Created.
  42. //
  43. //----------------------------------------------------------------------------
  44. HRESULT
  45. CDSOObject::CreateDSOObject(
  46. IUnknown * pUnkOuter,
  47. REFIID riid,
  48. void ** ppvObj
  49. )
  50. {
  51. CDSOObject* pDSO = NULL;
  52. HRESULT hr;
  53. //
  54. // check in-params and NULL out-params in case of error
  55. //
  56. if( ppvObj )
  57. *ppvObj = NULL;
  58. else
  59. RRETURN( E_INVALIDARG );
  60. if( pUnkOuter )// && !InlineIsEqualGUID(riid, IID_IUnknown) )
  61. RRETURN( DB_E_NOAGGREGATION );
  62. //
  63. // open a DBSession object
  64. //
  65. pDSO = new CDSOObject(pUnkOuter);
  66. if( !pDSO )
  67. RRETURN( E_OUTOFMEMORY );
  68. //
  69. // initialize the object
  70. //
  71. if( !pDSO->FInit() ) {
  72. delete pDSO;
  73. RRETURN( E_OUTOFMEMORY );
  74. }
  75. //
  76. // get requested interface pointer on DSO Object
  77. //
  78. hr = pDSO->QueryInterface( riid, (void **)ppvObj);
  79. if( FAILED( hr ) ) {
  80. delete pDSO;
  81. RRETURN( hr );
  82. }
  83. pDSO->Release();
  84. RRETURN( S_OK );
  85. }
  86. //+---------------------------------------------------------------------------
  87. //
  88. // Function: CDSOObject::Initialize
  89. //
  90. // Synopsis: Initializes the DataSource object.
  91. //
  92. // Arguments:
  93. //
  94. //
  95. // Returns: HRESULT
  96. // S_OK
  97. // E_FAIL
  98. //
  99. // Modifies:
  100. //
  101. // History: 08-28-96 ShankSh Created.
  102. //
  103. //----------------------------------------------------------------------------
  104. STDMETHODIMP
  105. CDSOObject::Initialize(
  106. void
  107. )
  108. {
  109. HRESULT hr = S_OK;
  110. if( _fDSOInitialized )
  111. RRETURN( DB_E_ALREADYINITIALIZED);
  112. if(IsIntegratedSecurity())
  113. {
  114. //
  115. // If using integrated security, we need to save the calling thread's
  116. // security context here. Reason is that when we actually connect to
  117. // the directory, we could be running on a different context, and we
  118. // need to impersonate this context to work correctly.
  119. //
  120. if (!OpenThreadToken(
  121. GetCurrentThread(),
  122. TOKEN_ALL_ACCESS,
  123. TRUE,
  124. &_ThreadToken))
  125. {
  126. //
  127. // If thread doesn't have a token, use process token
  128. //
  129. if (GetLastError() != ERROR_NO_TOKEN ||
  130. !OpenProcessToken(
  131. GetCurrentProcess(),
  132. TOKEN_ALL_ACCESS,
  133. &_ThreadToken))
  134. {
  135. GetLastError();
  136. BAIL_ON_FAILURE(hr = E_FAIL);
  137. }
  138. }
  139. }
  140. _fDSOInitialized = TRUE;
  141. error:
  142. RRETURN (hr);
  143. }
  144. //+---------------------------------------------------------------------------
  145. //
  146. // Function: CDSOObject::Uninitialize
  147. //
  148. // Synopsis: Returns the Data Source Object to an uninitialized state
  149. //
  150. // Arguments:
  151. //
  152. //
  153. // Returns: HRESULT
  154. // S_OK | The method succeeded
  155. // DB_E_OBJECTOPEN | A DBSession object was already created
  156. //
  157. // Modifies:
  158. //
  159. // History: 08-28-96 ShankSh Created.
  160. //
  161. //----------------------------------------------------------------------------
  162. STDMETHODIMP
  163. CDSOObject::Uninitialize(
  164. void
  165. )
  166. {
  167. //
  168. // data source object is not initialized; do nothing
  169. //
  170. if( !_fDSOInitialized ) {
  171. RRETURN( S_OK );
  172. }
  173. else {
  174. if( !IsSessionOpen() ) {
  175. //
  176. // DSO initialized, but no DBSession is open.
  177. // So, reset DSO to uninitialized state
  178. //
  179. if (_ThreadToken)
  180. {
  181. CloseHandle(_ThreadToken);
  182. _ThreadToken = NULL;
  183. }
  184. _fDSOInitialized = FALSE;
  185. RRETURN( S_OK );
  186. }
  187. else {
  188. //
  189. // DBSession has already been created; trying to uninit
  190. // the DSO now is an error
  191. //
  192. RRETURN( DB_E_OBJECTOPEN );
  193. }
  194. }
  195. }
  196. //+---------------------------------------------------------------------------
  197. //
  198. // Function: CDSOObject::GetProperties
  199. //
  200. // Synopsis: Returns current settings of all properties in the
  201. // DBPROPFLAGS_DATASOURCE property group
  202. //
  203. // Arguments:
  204. // cPropertySets count of restiction guids
  205. // rgPropertySets restriction guids
  206. // pcProperties count of properties returned
  207. // pprgProperties property information returned
  208. //
  209. // Returns: HRESULT
  210. // S_OK | The method succeeded
  211. // E_FAIL | Provider specific error
  212. // E_INVALIDARG | pcPropertyInfo or prgPropertyInfo was NULL
  213. // E_OUTOFMEMORY | Out of memory
  214. //
  215. // Modifies:
  216. //
  217. // History: 08-28-96 ShankSh Created.
  218. //
  219. //----------------------------------------------------------------------------
  220. STDMETHODIMP
  221. CDSOObject::GetProperties(
  222. ULONG cPropIDSets,
  223. const DBPROPIDSET rgPropIDSets[],
  224. ULONG * pcPropSets,
  225. DBPROPSET ** pprgPropSets
  226. )
  227. {
  228. //
  229. // Asserts
  230. //
  231. ADsAssert(_pUtilProp);
  232. //
  233. // If the Data Source object is initialized.
  234. //
  235. DWORD dwBitMask = PROPSET_DSO;
  236. if( _fDSOInitialized )
  237. dwBitMask |= PROPSET_INIT;
  238. //
  239. // Validate the GetProperties Arguments
  240. //
  241. HRESULT hr = _pUtilProp->GetPropertiesArgChk(
  242. cPropIDSets,
  243. rgPropIDSets,
  244. pcPropSets,
  245. pprgPropSets,
  246. dwBitMask);
  247. if( FAILED(hr) )
  248. RRETURN( hr );
  249. //
  250. // Just pass this call on to the utility object that manages our properties
  251. //
  252. RRETURN( _pUtilProp->GetProperties(
  253. cPropIDSets,
  254. rgPropIDSets,
  255. pcPropSets,
  256. pprgPropSets,
  257. dwBitMask ) );
  258. }
  259. //+---------------------------------------------------------------------------
  260. //
  261. // Function: CDSOObject::GetPropertyInfo
  262. //
  263. // Synopsis: Returns information about rowset and data source properties supported
  264. // by the provider
  265. //
  266. // Arguments:
  267. // cPropertySets Number of properties being asked about
  268. // rgPropertySets Array of cPropertySets properties about
  269. // which to return information
  270. // pcPropertyInfoSets Number of properties for which information
  271. // is being returned
  272. // prgPropertyInfoSets Buffer containing default values returned
  273. // ppDescBuffer Buffer containing property descriptions
  274. //
  275. // Returns: HRESULT
  276. // S_OK | The method succeeded
  277. // E_FAIL | Provider specific error
  278. // E_INVALIDARG | pcPropertyInfo or prgPropertyInfo was NULL
  279. // E_OUTOFMEMORY | Out of memory
  280. //
  281. // Modifies:
  282. //
  283. // History: 08-28-96 ShankSh Created.
  284. //
  285. //----------------------------------------------------------------------------
  286. STDMETHODIMP
  287. CDSOObject::GetPropertyInfo(
  288. ULONG cPropertyIDSets,
  289. const DBPROPIDSET rgPropertyIDSets[],
  290. ULONG * pcPropertyInfoSets,
  291. DBPROPINFOSET ** pprgPropertyInfoSets,
  292. WCHAR ** ppDescBuffer)
  293. {
  294. //
  295. // Asserts
  296. //
  297. ADsAssert(_pUtilProp);
  298. //
  299. // Just pass this call on to the utility object that manages our properties
  300. //
  301. RRETURN( _pUtilProp->GetPropertyInfo(
  302. cPropertyIDSets,
  303. rgPropertyIDSets,
  304. pcPropertyInfoSets,
  305. pprgPropertyInfoSets,
  306. ppDescBuffer,
  307. _fDSOInitialized) );
  308. }
  309. //+---------------------------------------------------------------------------
  310. //
  311. // Function: CDSOObject::SetProperties
  312. //
  313. // Synopsis: Set properties in the DBPROPFLAGS_DATASOURCE property group
  314. //
  315. // Arguments:
  316. // cPropertySets
  317. // rgPropertySets
  318. //
  319. // Returns: HRESULT
  320. // E_INVALIDARG | cProperties was not equal to 0 and
  321. // rgProperties was NULL
  322. // E_FAIL | Provider specific error
  323. //
  324. // Modifies:
  325. //
  326. // History: 08-28-96 ShankSh Created.
  327. //
  328. //----------------------------------------------------------------------------
  329. STDMETHODIMP
  330. CDSOObject::SetProperties(
  331. ULONG cPropertySets,
  332. DBPROPSET rgPropertySets[]
  333. )
  334. {
  335. //
  336. // Asserts
  337. //
  338. ADsAssert(_pUtilProp);
  339. //
  340. // If the Data Source object is initialized.
  341. //
  342. DWORD dwBitMask = PROPSET_DSO;
  343. if( _fDSOInitialized )
  344. dwBitMask |= PROPSET_INIT;
  345. //
  346. // Just pass this call on to the utility object that manages our properties
  347. //
  348. RRETURN( _pUtilProp->SetProperties(
  349. cPropertySets,
  350. rgPropertySets,
  351. dwBitMask) );
  352. }
  353. //+---------------------------------------------------------------------------
  354. //
  355. // Function: CDSOObject::GetClassID
  356. //
  357. // Synopsis:
  358. //
  359. // Arguments:
  360. //
  361. //
  362. //
  363. // Returns:
  364. //
  365. //
  366. //
  367. //
  368. // Modifies:
  369. //
  370. // History: 08-28-96 ShankSh Created.
  371. //
  372. //----------------------------------------------------------------------------
  373. STDMETHODIMP
  374. CDSOObject::GetClassID(
  375. CLSID * pClassID
  376. )
  377. {
  378. if( pClassID )
  379. {
  380. memcpy(pClassID, &CLSID_ADsDSOObject, sizeof(CLSID));
  381. RRETURN( S_OK );
  382. }
  383. RRETURN( E_FAIL );
  384. }
  385. //+---------------------------------------------------------------------------
  386. //
  387. // Function: CDSOObject::CreateSession
  388. //
  389. // Synopsis: Creates a new DB Session object from the DSO, and returns the
  390. // requested interface on the newly created object.
  391. //
  392. // Arguments:
  393. // pUnkOuter, Controlling IUnknown if being aggregated
  394. // riid, The ID of the interface
  395. // ppDBSession A pointer to memory in which to return the
  396. // interface pointer
  397. //
  398. // Returns: HRESULT
  399. // S_OK The method succeeded.
  400. // E_INVALIDARG ppDBSession was NULL
  401. // DB_E_NOAGGREGATION pUnkOuter was not NULL (this object
  402. // does not support being aggregated)
  403. // E_FAIL Provider-specific error. This
  404. // provider can only create one DBSession
  405. // E_OUTOFMEMORY Out of memory
  406. // E_NOINTERFACE Could not obtain requested interface
  407. // on DBSession object
  408. //
  409. // Modifies:
  410. //
  411. // History: 08-28-96 ShankSh Created.
  412. //
  413. //----------------------------------------------------------------------------
  414. STDMETHODIMP
  415. CDSOObject::CreateSession(
  416. IUnknown * pUnkOuter,
  417. REFIID riid,
  418. IUnknown ** ppDBSession
  419. )
  420. {
  421. CSessionObject* pDBSession = NULL;
  422. HRESULT hr;
  423. BOOL fSuccess;
  424. //
  425. // check in-params and NULL out-params in case of error
  426. //
  427. if( ppDBSession )
  428. *ppDBSession = NULL;
  429. else
  430. RRETURN( E_INVALIDARG );
  431. if( pUnkOuter )//&& !InlineIsEqualGUID(riid, IID_IUnknown) )
  432. RRETURN( DB_E_NOAGGREGATION );
  433. if( !_fDSOInitialized ) {
  434. RRETURN(E_UNEXPECTED);
  435. }
  436. //
  437. // open a DBSession object
  438. //
  439. pDBSession = new CSessionObject(pUnkOuter);
  440. if( !pDBSession )
  441. RRETURN( E_OUTOFMEMORY );
  442. //
  443. // initialize the object
  444. //
  445. if( _pUtilProp->IsIntegratedSecurity() )
  446. {
  447. CCredentials tempCreds;
  448. tempCreds.SetUserName(NULL);
  449. tempCreds.SetPassword(NULL);
  450. tempCreds.SetAuthFlags(_Credentials.GetAuthFlags());
  451. fSuccess = pDBSession->FInit(this, tempCreds);
  452. }
  453. else
  454. {
  455. fSuccess = pDBSession->FInit(this, _Credentials);
  456. }
  457. if (!fSuccess) {
  458. delete pDBSession;
  459. RRETURN( E_OUTOFMEMORY );
  460. }
  461. //
  462. // get requested interface pointer on DBSession
  463. //
  464. hr = pDBSession->QueryInterface( riid, (void **) ppDBSession );
  465. if( FAILED( hr ) ) {
  466. delete pDBSession;
  467. RRETURN( hr );
  468. }
  469. pDBSession->Release();
  470. RRETURN( S_OK );
  471. }
  472. //+-----------------------------------------------------------------------------
  473. //
  474. // Function: CDSOObject::CDSOObject
  475. //
  476. // Synopsis: Constructor
  477. //
  478. // Arguments:
  479. // pUnkOuter Outer Unkown Pointer
  480. //
  481. // Returns:
  482. //
  483. // Modifies:
  484. //
  485. // History: 08-28-96 ShankSh Created.
  486. //
  487. //----------------------------------------------------------------------------
  488. CDSOObject::CDSOObject(
  489. LPUNKNOWN pUnkOuter
  490. )
  491. {
  492. // Initialize simple member vars
  493. _pUnkOuter = pUnkOuter ? pUnkOuter : (IDBInitialize FAR *) this;
  494. _fDSOInitialized = FALSE;
  495. _cSessionsOpen = FALSE;
  496. _pUtilProp = NULL;
  497. _ThreadToken = NULL;
  498. // Set defaults
  499. _Credentials.SetUserName(NULL);
  500. _Credentials.SetPassword(NULL);
  501. _Credentials.SetAuthFlags(0);
  502. ENLIST_TRACKING(CDSOObject);
  503. // make sure DLL isn't unloaded until all data source objects are destroyed
  504. InterlockedIncrement(&glnOledbObjCnt);
  505. }
  506. //+---------------------------------------------------------------------------
  507. //
  508. // Function: CDSOObject::~CDSOObject
  509. //
  510. // Synopsis: Destructor
  511. //
  512. // Arguments:
  513. //
  514. // Returns:
  515. //
  516. // Modifies:
  517. //
  518. // History: 08-28-96 ShankSh Created.
  519. //
  520. //----------------------------------------------------------------------------
  521. CDSOObject::~CDSOObject( )
  522. {
  523. //
  524. // Free properties management object
  525. //
  526. delete _pUtilProp;
  527. if (_ThreadToken)
  528. CloseHandle(_ThreadToken);
  529. InterlockedDecrement(&glnOledbObjCnt);
  530. }
  531. //+---------------------------------------------------------------------------
  532. //
  533. // Function: CDSOObject::FInit
  534. //
  535. // Synopsis: Initialize the data source Object
  536. //
  537. // Arguments:
  538. //
  539. // Returns:
  540. // Did the Initialization Succeed
  541. // TRUE Initialization succeeded
  542. // FALSE Initialization failed
  543. //
  544. // Modifies:
  545. //
  546. // History: 08-28-96 ShankSh Created.
  547. //
  548. //----------------------------------------------------------------------------
  549. BOOL CDSOObject::FInit(
  550. void
  551. )
  552. {
  553. HRESULT hr;
  554. //
  555. // Allocate properties management object
  556. //
  557. _pUtilProp = new CUtilProp();
  558. if( !_pUtilProp )
  559. return FALSE;
  560. hr = _pUtilProp->FInit(&_Credentials);
  561. BAIL_ON_FAILURE( hr );
  562. return TRUE;
  563. error:
  564. return FALSE;
  565. }
  566. //+---------------------------------------------------------------------------
  567. //
  568. // Function: CDSOObject::QueryInterface
  569. //
  570. // Synopsis: Returns a pointer to a specified interface. Callers use
  571. // QueryInterface to determine which interfaces the called object
  572. // supports.
  573. //
  574. // Arguments:
  575. // riid Interface ID of the interface being queried for
  576. // ppv Pointer to interface that was instantiated
  577. //
  578. // Returns:
  579. // S_OK Interface is supported and ppvObject is set.
  580. // E_NOINTERFACE Interface is not supported by the object
  581. // E_INVALIDARG One or more arguments are invalid.
  582. //
  583. // Modifies:
  584. //
  585. // History: 08-28-96 ShankSh Created.
  586. //
  587. //----------------------------------------------------------------------------
  588. STDMETHODIMP
  589. CDSOObject::QueryInterface(REFIID iid, LPVOID FAR* ppv)
  590. {
  591. if( ppv == NULL )
  592. RRETURN( E_INVALIDARG );
  593. if( IsEqualIID(iid, IID_IUnknown) ) {
  594. *ppv = (IDBInitialize FAR *) this;
  595. }
  596. else if( IsEqualIID(iid, IID_IDBInitialize) ) {
  597. *ppv = (IDBInitialize FAR *) this;
  598. }
  599. else if( IsEqualIID(iid, IID_IDBProperties) ) {
  600. *ppv = (IDBProperties FAR *) this;
  601. }
  602. else if( _fDSOInitialized &&
  603. IsEqualIID(iid, IID_IDBCreateSession) ) {
  604. *ppv = (IDBCreateSession FAR *) this;
  605. }
  606. else if( IsEqualIID(iid, IID_IPersist) ) {
  607. *ppv = (IPersist FAR *) this;
  608. }
  609. else {
  610. *ppv = NULL;
  611. return E_NOINTERFACE;
  612. }
  613. AddRef();
  614. return NOERROR;
  615. }