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.

1315 lines
58 KiB

  1. // Binder.cpp : Implementation of CBinder
  2. #include "oleds.hxx"
  3. #if (!defined(BUILD_FOR_NT40))
  4. #include "atl.h"
  5. #include "binder.hxx"
  6. #include "row.hxx"
  7. //property description constants
  8. const PWSTR DESC_DBPROP_INIT_LCID = L"Location ID";
  9. const PWSTR DESC_DBPROP_INIT_MODE = L"Mode";
  10. const PWSTR DESC_DBPROP_INIT_BINDFLAGS = L"Bind Flags";
  11. const PWSTR DESC_DBPROP_INIT_LOCKOWNER = L"Lock Owner";
  12. const PWSTR DESC_DBPROP_USERID = L"User ID";
  13. const PWSTR DESC_DBPROP_PASSWORD = L"Password";
  14. const PWSTR DESC_DBPROP_ENCRYPT_PASSWORD = L"Encrypt Password";
  15. #define DEFAULT_DBPROP_INIT_MODE DB_MODE_READ
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CBinder
  18. //ISupportErrorInfo methods
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: CBinder::InterfaceSupportsErrorInfo
  22. //
  23. // Synopsis: Given an interface ID, tells if that interface supports
  24. // the interface ISupportErrorInfo
  25. //
  26. // Arguments:
  27. // REFIID riid
  28. //
  29. // Returns:
  30. // S_OK yes, the interface supports ISupportErrorInfo
  31. // S_FALSE no, the interface doesn't support it.
  32. //----------------------------------------------------------------------------
  33. STDMETHODIMP CBinder::InterfaceSupportsErrorInfo(REFIID riid)
  34. {
  35. static const IID* arr[] =
  36. {
  37. &IID_IBindResource, &IID_IDBBinderProperties
  38. };
  39. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  40. {
  41. if (InlineIsEqualGUID(*arr[i],riid))
  42. RRETURN(S_OK);
  43. }
  44. RRETURN(S_FALSE);
  45. }
  46. //IBindResource methods
  47. //+---------------------------------------------------------------------------
  48. //
  49. // Function: CBinder::Bind
  50. //
  51. // Synopsis: Binds to a row or rowset object given a URL.
  52. //
  53. // For more info see OLE DB 2.5 spec.
  54. //----------------------------------------------------------------------------
  55. STDMETHODIMP CBinder::Bind(
  56. IUnknown * punkOuter,
  57. LPCOLESTR pwszURL,
  58. DBBINDURLFLAG dwBindFlags,
  59. REFGUID rguid,
  60. REFIID riid,
  61. IAuthenticate * pAuthenticate,
  62. DBIMPLICITSESSION * pImplSession,
  63. DWORD * pdwBindStatus,
  64. IUnknown ** ppUnk
  65. )
  66. {
  67. HRESULT hr = S_OK;
  68. TRYBLOCK
  69. //if caller passed a null value for dwBindFlags,
  70. //get them from initialization properties.
  71. if (dwBindFlags == 0)
  72. dwBindFlags = BindFlagsFromDbProps();
  73. //Forward the Bind call to CSessionObject for actual binding
  74. ADsAssert(m_pSession);
  75. hr = m_pSession->Bind(punkOuter, pwszURL, dwBindFlags, rguid, riid,
  76. pAuthenticate, pImplSession, pdwBindStatus, ppUnk);
  77. if (FAILED(hr))
  78. RRETURN(hr);
  79. CATCHBLOCKRETURN
  80. RRETURN(hr);
  81. }
  82. //IDBBinderProperties : IDBProperties
  83. //(most of this code has been copied form exoledb and reorganized).
  84. //IDBProperties
  85. //+---------------------------------------------------------------------------
  86. //
  87. // Function: CBinder::GetProperties
  88. //
  89. // Synopsis: Gets the requested Binder properties
  90. //
  91. // For more info see OLE DB 2.1 spec.
  92. //----------------------------------------------------------------------------
  93. STDMETHODIMP CBinder::GetProperties(
  94. ULONG cPropertySets,
  95. const DBPROPIDSET rgPropertySets[ ],
  96. ULONG *pcPropertySets,
  97. DBPROPSET **prgPropertySets)
  98. {
  99. BOOL fPropInError, fSpecialSets, fCopy = FALSE;
  100. HRESULT hr = S_OK;
  101. LONG ipropset =0, iprop =0;
  102. ULONG cprop = 0, cpropError =0, ipropT;
  103. DBPROPSET *rgPropertySetsOutput = NULL, *ppropset = NULL;
  104. DBPROP *pprop;
  105. auto_leave cs_auto_leave(m_autocs);
  106. TRYBLOCK
  107. //Let property manager object check and init the arguments
  108. hr = m_dbProperties.CheckAndInitPropArgs(cPropertySets,
  109. rgPropertySets,
  110. pcPropertySets,
  111. (void **)prgPropertySets,
  112. &fPropInError,
  113. &fSpecialSets);
  114. //if all the requested sets are special,
  115. //we just return error because this method
  116. //doesn't support special sets. Otherwise,
  117. //we attempt to return information about other
  118. //non-special sets.
  119. if(fSpecialSets && SUCCEEDED(hr))
  120. RRETURN(DB_E_ERRORSOCCURRED);
  121. else if(!fSpecialSets && FAILED(hr))
  122. RRETURN(hr);
  123. cs_auto_leave.EnterCriticalSection();
  124. //if cPropertySets is zero, return INIT property set.
  125. if(cPropertySets == 0)
  126. {
  127. cPropertySets = 1;
  128. fCopy = TRUE;
  129. }
  130. //or if DBPROPSET_PROPERTIESINERROR is requested,
  131. //check for invalid status values
  132. else if(fPropInError)
  133. {
  134. ppropset = m_dbProperties.GetPropertySet(DBPROPSET_DBINIT);
  135. for(iprop = 0, cpropError = 0;
  136. (ULONG)iprop < ppropset->cProperties;
  137. iprop++)
  138. if( ppropset->rgProperties[iprop].dwStatus != DBPROPSTATUS_OK )
  139. cpropError++;
  140. }
  141. //Allocate memory for returning property sets.
  142. rgPropertySetsOutput =
  143. (DBPROPSET *)CoTaskMemAlloc(cPropertySets *sizeof(DBPROPSET));
  144. if (!rgPropertySetsOutput)
  145. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  146. //If properties in error were requested, look for all properties
  147. //with invalid status values and return the info.
  148. if(fPropInError)
  149. {
  150. if(cpropError)
  151. {
  152. rgPropertySetsOutput[0].rgProperties
  153. =(DBPROP *)CoTaskMemAlloc(cpropError *sizeof(DBPROP));
  154. if(rgPropertySetsOutput[0].rgProperties == NULL)
  155. {
  156. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  157. }
  158. rgPropertySetsOutput[0].guidPropertySet = DBPROPSET_DBINIT;
  159. for(ipropT =0, iprop =0;
  160. ipropT <ppropset->cProperties;
  161. ipropT++)
  162. if( ppropset->rgProperties[ipropT].dwStatus
  163. != DBPROPSTATUS_OK )
  164. {
  165. memcpy(&(rgPropertySetsOutput[0].rgProperties[iprop]),
  166. &(ppropset->rgProperties[ipropT]),
  167. sizeof(DBPROP));
  168. VariantInit(
  169. &(rgPropertySetsOutput[0].rgProperties[iprop].vValue));
  170. hr = VariantCopy(
  171. &(rgPropertySetsOutput[0].rgProperties[iprop].vValue),
  172. &(ppropset->rgProperties[ipropT].vValue));
  173. BAIL_ON_FAILURE(hr);
  174. iprop++;
  175. }
  176. }
  177. else
  178. rgPropertySetsOutput[0].rgProperties = NULL;
  179. rgPropertySetsOutput[0].cProperties = cpropError;
  180. cpropError =0;
  181. }
  182. //if fCopy is set, copy the init property set to the return array
  183. else if(fCopy)
  184. {
  185. for (ipropset=0; (ULONG)ipropset<cPropertySets; ++ipropset)
  186. {
  187. hr = m_dbProperties.CopyPropertySet(
  188. ipropset, &rgPropertySetsOutput[ipropset]);
  189. BAIL_ON_FAILURE(hr);
  190. }
  191. }
  192. //caller requested for some regular property sets
  193. //return the info.
  194. else
  195. {
  196. //copy passed in information from rgPropertySets
  197. //to output array.
  198. memcpy(rgPropertySetsOutput,
  199. rgPropertySets,
  200. cPropertySets *sizeof(DBPROPSET));
  201. //cycle thru each property set, get properties
  202. //allocate necessary memory and assign values.
  203. for(ipropset = 0, cprop = 0, cpropError =0;
  204. (ULONG)ipropset<cPropertySets;
  205. ipropset++)
  206. {
  207. ppropset = m_dbProperties.GetPropertySet(
  208. rgPropertySets[ipropset].guidPropertySet);
  209. if(rgPropertySets[ipropset].cPropertyIDs)
  210. {
  211. iprop =0;
  212. cprop += rgPropertySets[ipropset].cPropertyIDs;
  213. //Allocate memory for all the propertyIDs in this set.
  214. rgPropertySetsOutput[ipropset].rgProperties =
  215. (DBPROP *) CoTaskMemAlloc(
  216. rgPropertySets[ipropset].cPropertyIDs *sizeof(DBPROP));
  217. if(rgPropertySetsOutput[ipropset].rgProperties == NULL)
  218. {
  219. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  220. }
  221. //zero memory
  222. memset( rgPropertySetsOutput[ipropset].rgProperties,
  223. 0x00,
  224. rgPropertySets[ipropset].cPropertyIDs *sizeof(DBPROP));
  225. //DBPROPSET_DATASOURCEINFO is not valid on this object.
  226. if( ppropset == NULL ||
  227. (rgPropertySets[ipropset].guidPropertySet ==
  228. DBPROPSET_DATASOURCEINFO)
  229. )
  230. {
  231. cpropError += rgPropertySets[ipropset].cPropertyIDs;
  232. for(;
  233. (ULONG)iprop<rgPropertySets[ipropset].cPropertyIDs;
  234. iprop++
  235. )
  236. {
  237. rgPropertySetsOutput[ipropset].
  238. rgProperties[iprop].dwPropertyID
  239. = rgPropertySets[ipropset].rgPropertyIDs[iprop];
  240. rgPropertySetsOutput[ipropset].
  241. rgProperties[iprop].dwStatus =
  242. DBPROPSTATUS_NOTSUPPORTED;
  243. }
  244. continue; //continue with next property set.
  245. }
  246. //we have a valid property set. Cycle thru each
  247. //property and assign values in output array.
  248. for(;
  249. (ULONG)iprop < rgPropertySets[ipropset].cPropertyIDs;
  250. iprop++
  251. )
  252. {
  253. pprop = (DBPROP *)m_dbProperties.GetProperty(
  254. rgPropertySets[ipropset].guidPropertySet,
  255. rgPropertySets[ipropset].rgPropertyIDs[iprop]);
  256. if(pprop)
  257. {
  258. rgPropertySetsOutput[ipropset].rgProperties[iprop]
  259. = *pprop;
  260. VariantInit(
  261. &(rgPropertySetsOutput[ipropset].
  262. rgProperties[iprop].vValue));
  263. hr = VariantCopy(
  264. &(rgPropertySetsOutput[ipropset].
  265. rgProperties[iprop].vValue),
  266. &(pprop->vValue));
  267. BAIL_ON_FAILURE(hr);
  268. }
  269. //If unable to get property, set dwStatus
  270. else
  271. {
  272. cpropError++;
  273. rgPropertySetsOutput[ipropset].
  274. rgProperties[iprop].dwPropertyID =
  275. rgPropertySets[ipropset].rgPropertyIDs[iprop];
  276. rgPropertySetsOutput[ipropset].
  277. rgProperties[iprop].dwStatus =
  278. DBPROPSTATUS_NOTSUPPORTED;
  279. }
  280. }
  281. }
  282. else //no propertyIDs requested for this set
  283. {
  284. rgPropertySetsOutput[ipropset].rgProperties = NULL;
  285. //DBPROPSET_DATASOURCEINFO is invalid for this object.
  286. //Return error if it is the one requested.
  287. if(ppropset == NULL ||
  288. (rgPropertySets[ipropset].guidPropertySet ==
  289. DBPROPSET_DATASOURCEINFO)
  290. )
  291. {
  292. cprop++;
  293. cpropError++;
  294. }
  295. else //otherwise, copy all propertyIDs
  296. {
  297. hr = m_dbProperties.CopyPropertySet(
  298. rgPropertySets[ipropset].guidPropertySet,
  299. &rgPropertySetsOutput[ipropset]);
  300. BAIL_ON_FAILURE(hr);
  301. }
  302. }
  303. } //for (ipropset = 0....
  304. }
  305. CATCHBLOCKBAIL(hr)
  306. ADsAssert(pcPropertySets && prgPropertySets);
  307. *pcPropertySets = cPropertySets;
  308. *prgPropertySets = rgPropertySetsOutput;
  309. hr = cpropError ?
  310. ((cpropError < cprop) ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED)
  311. : S_OK;
  312. RRETURN(hr);
  313. error:
  314. while(ipropset >= 0)
  315. {
  316. while(--iprop >= 0)
  317. VariantClear(
  318. &(rgPropertySetsOutput[ipropset].rgProperties[iprop].vValue));
  319. if( rgPropertySetsOutput
  320. && rgPropertySetsOutput[ipropset].cProperties
  321. && rgPropertySetsOutput[ipropset].rgProperties)
  322. CoTaskMemFree(rgPropertySetsOutput[ipropset].rgProperties);
  323. ipropset--;
  324. }
  325. if(rgPropertySetsOutput)
  326. CoTaskMemFree(rgPropertySetsOutput);
  327. RRETURN(hr);
  328. }
  329. //+---------------------------------------------------------------------------
  330. //
  331. // Function: CBinder::GetPropertyInfo
  332. //
  333. // Synopsis: Gets information about requested properties
  334. //
  335. // For more info see OLE DB 2.1 spec.
  336. //----------------------------------------------------------------------------
  337. STDMETHODIMP CBinder::GetPropertyInfo(
  338. ULONG cPropertySets,
  339. const DBPROPIDSET rgPropertySets[ ],
  340. ULONG *pcPropertyInfoSets,
  341. DBPROPINFOSET **prgPropertyInfoSets,
  342. OLECHAR **ppDescBuffer)
  343. {
  344. HRESULT hr;
  345. BOOL fPropInError, fSpecialSets, fCopy =FALSE;
  346. ULONG ipropset = 0, iprop, cProperty, cprop = 0, cpropError=0;
  347. ULONG_PTR cchDescBuffer, ichDescBuffer;
  348. DBPROPINFOSET *rgPropertyInfoSetsOutput = NULL, *ppropinfoset;
  349. const DBPROPINFO UNALIGNED *pdbpropinfoSrc;
  350. PDBPROPINFO pdbpropinfo;
  351. auto_leave cs_auto_leave(m_autocs);
  352. TRYBLOCK
  353. if(ppDescBuffer)
  354. {
  355. *ppDescBuffer = NULL;
  356. cchDescBuffer = 0;
  357. ichDescBuffer = 0;
  358. }
  359. //Let the property manager object check and init arguments
  360. hr = m_dbProperties.CheckAndInitPropArgs(cPropertySets,
  361. rgPropertySets,
  362. pcPropertyInfoSets,
  363. (void **)prgPropertyInfoSets,
  364. &fPropInError,
  365. &fSpecialSets);
  366. if(FAILED(hr))
  367. RRETURN(hr);
  368. else if(fPropInError)
  369. RRETURN(E_INVALIDARG);
  370. cs_auto_leave.EnterCriticalSection();
  371. //if cPropertySets is zero, return INIT property set info
  372. if(cPropertySets == 0)
  373. {
  374. cPropertySets = 1;
  375. fCopy = TRUE;
  376. }
  377. rgPropertyInfoSetsOutput = (DBPROPINFOSET *)
  378. CoTaskMemAlloc(cPropertySets*sizeof(DBPROPINFOSET));
  379. if (!rgPropertyInfoSetsOutput)
  380. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  381. if(fCopy)
  382. {
  383. for (ipropset=0; ipropset <cPropertySets; ++ipropset)
  384. {
  385. hr = m_dbProperties.CopyPropertyInfoSet(
  386. ipropset,
  387. &rgPropertyInfoSetsOutput[ipropset],
  388. ppDescBuffer,
  389. &cchDescBuffer,
  390. &ichDescBuffer);
  391. if (FAILED(hr))
  392. break;
  393. }
  394. BAIL_ON_FAILURE(hr);
  395. }
  396. else
  397. {
  398. //copy passed in property set info to output array.
  399. memcpy( rgPropertyInfoSetsOutput,
  400. rgPropertySets,
  401. cPropertySets *sizeof(DBPROPSET));
  402. //Cycle thru each requested property set
  403. for(ipropset=0, cprop =0; ipropset<cPropertySets; ipropset++)
  404. {
  405. iprop =0;
  406. //Handle each special set
  407. if( rgPropertySets[ipropset].guidPropertySet ==
  408. DBPROPSET_DBINITALL)
  409. {
  410. cprop++;
  411. hr = m_dbProperties.CopyPropertyInfoSet(DBPROPSET_DBINIT,
  412. &rgPropertyInfoSetsOutput[ipropset],
  413. ppDescBuffer,
  414. &cchDescBuffer,
  415. &ichDescBuffer);
  416. BAIL_ON_FAILURE(hr);
  417. }
  418. else if(fSpecialSets)
  419. {
  420. if(rgPropertySets[ipropset].guidPropertySet ==
  421. DBPROPSET_DATASOURCEALL)
  422. rgPropertyInfoSetsOutput[ipropset].guidPropertySet =
  423. DBPROPSET_DATASOURCE;
  424. else if (rgPropertyInfoSetsOutput[ipropset].guidPropertySet ==
  425. DBPROPSET_SESSIONALL)
  426. rgPropertyInfoSetsOutput[ipropset].guidPropertySet =
  427. DBPROPSET_SESSION;
  428. else if(rgPropertyInfoSetsOutput[ipropset].guidPropertySet ==
  429. DBPROPSET_ROWSETALL)
  430. rgPropertyInfoSetsOutput[ipropset].guidPropertySet =
  431. DBPROPSET_ROWSET;
  432. else
  433. rgPropertyInfoSetsOutput[ipropset].guidPropertySet =
  434. DBPROPSET_DATASOURCEINFO;
  435. rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos = NULL;
  436. rgPropertyInfoSetsOutput[ipropset].cPropertyInfos = 0;
  437. cprop++;
  438. cpropError++;
  439. }
  440. else //Now the regular property sets
  441. {
  442. ppropinfoset =
  443. m_dbProperties.GetPropertyInfoSet(
  444. rgPropertySets[ipropset].guidPropertySet);
  445. cProperty = rgPropertySets[ipropset].cPropertyIDs;
  446. if(cProperty)
  447. {
  448. cprop += cProperty;
  449. //allocate memory for each property info
  450. rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos
  451. = (DBPROPINFO *)
  452. CoTaskMemAlloc(cProperty *sizeof(DBPROPINFO));
  453. if( rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos
  454. == NULL)
  455. {
  456. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  457. }
  458. //zero memory
  459. memset(rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos,
  460. 0x00,
  461. cProperty*sizeof(DBPROPINFO));
  462. //if the requested property info set is empty,
  463. //store error information into the output array.
  464. if(ppropinfoset == 0)
  465. {
  466. cpropError += cProperty;
  467. for(iprop =0; iprop <cProperty; iprop++)
  468. {
  469. rgPropertyInfoSetsOutput[ipropset].
  470. rgPropertyInfos[iprop].dwPropertyID =
  471. rgPropertySets[ipropset].rgPropertyIDs[iprop];
  472. rgPropertyInfoSetsOutput[ipropset].
  473. rgPropertyInfos[iprop].dwFlags =
  474. DBPROPFLAGS_NOTSUPPORTED;
  475. }
  476. }
  477. //otherwise, try to get property info for each property.
  478. else
  479. {
  480. pdbpropinfo =
  481. rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos;
  482. for(; iprop <cProperty; iprop++, pdbpropinfo++)
  483. {
  484. pdbpropinfoSrc = m_dbProperties.GetPropertyInfo(
  485. rgPropertySets[ipropset].guidPropertySet,
  486. rgPropertySets[ipropset].rgPropertyIDs[iprop]);
  487. if(pdbpropinfoSrc)
  488. *pdbpropinfo = *pdbpropinfoSrc;
  489. else
  490. {
  491. //unable to get property info
  492. //for this property. Store error info.
  493. pdbpropinfo->dwPropertyID =
  494. rgPropertySets[ipropset].
  495. rgPropertyIDs[iprop];
  496. pdbpropinfo->dwFlags =
  497. DBPROPFLAGS_NOTSUPPORTED;
  498. cpropError++;
  499. }
  500. }
  501. //Now copy property descriptions
  502. //for all properties in this set
  503. hr = m_dbProperties.CopyPropertyDescriptions(
  504. &rgPropertyInfoSetsOutput[ipropset],
  505. ppDescBuffer,
  506. &cchDescBuffer,
  507. &ichDescBuffer);
  508. BAIL_ON_FAILURE(hr);
  509. }
  510. }
  511. else //no properties stored in this set.
  512. {
  513. cprop++;
  514. //if the returned set itself is NULL, nothing
  515. //to copy.
  516. if(ppropinfoset == NULL)
  517. {
  518. cpropError++;
  519. rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos =
  520. NULL;
  521. }
  522. //otherwise, just copy whatever info we have
  523. //in the set.
  524. else
  525. {
  526. hr = m_dbProperties.CopyPropertyInfoSet(
  527. rgPropertySets[ipropset].guidPropertySet,
  528. &rgPropertyInfoSetsOutput[ipropset],
  529. ppDescBuffer,
  530. &cchDescBuffer,
  531. &ichDescBuffer);
  532. BAIL_ON_FAILURE(hr);
  533. }
  534. }
  535. }
  536. } //for (ipropset = 0 ....
  537. } //if (fcopy) ... else ...
  538. CATCHBLOCKBAIL(hr)
  539. *pcPropertyInfoSets = cPropertySets;
  540. *prgPropertyInfoSets = rgPropertyInfoSetsOutput;
  541. // So far we have put relative offsets into pointers to property
  542. // descriptions. They have to be rebased on the beginning of the
  543. // desription strings buffer.
  544. if(ppDescBuffer && *ppDescBuffer)
  545. {
  546. for(ipropset=0; ipropset < cPropertySets; ipropset++)
  547. for(iprop =0;
  548. iprop <rgPropertyInfoSetsOutput[ipropset].cPropertyInfos;
  549. iprop++)
  550. {
  551. // Only do this if we really support the property:
  552. //
  553. if ( rgPropertyInfoSetsOutput[ipropset].
  554. rgPropertyInfos[iprop].dwFlags !=
  555. DBPROPFLAGS_NOTSUPPORTED )
  556. {
  557. rgPropertyInfoSetsOutput[ipropset].
  558. rgPropertyInfos[iprop].pwszDescription =
  559. (WCHAR *)(*ppDescBuffer) +
  560. (ULONG_PTR)(rgPropertyInfoSetsOutput[ipropset].
  561. rgPropertyInfos[iprop].pwszDescription);
  562. }
  563. else {
  564. ADsAssert ( rgPropertyInfoSetsOutput[ipropset].
  565. rgPropertyInfos[iprop].pwszDescription
  566. == NULL );
  567. }
  568. }
  569. }
  570. else
  571. {
  572. // Assert that we're not passing back any strings:
  573. //
  574. for(ipropset=0; ipropset < cPropertySets; ipropset++)
  575. {
  576. for(iprop =0;
  577. iprop < rgPropertyInfoSetsOutput[ipropset].cPropertyInfos;
  578. iprop++)
  579. {
  580. ADsAssert ( rgPropertyInfoSetsOutput[ipropset].
  581. rgPropertyInfos[iprop].pwszDescription == NULL );
  582. }
  583. }
  584. }
  585. hr = cpropError ?
  586. ((cpropError <cprop) ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED)
  587. : S_OK;
  588. RRETURN(hr);
  589. error:
  590. ULONG i;
  591. for ( i = 0; i < ipropset; i++ )
  592. {
  593. if( rgPropertyInfoSetsOutput
  594. && rgPropertyInfoSetsOutput[i].cPropertyInfos
  595. && rgPropertyInfoSetsOutput[i].rgPropertyInfos)
  596. CoTaskMemFree(rgPropertyInfoSetsOutput[i].rgPropertyInfos);
  597. }
  598. if(rgPropertyInfoSetsOutput)
  599. CoTaskMemFree(rgPropertyInfoSetsOutput);
  600. if(ppDescBuffer && *ppDescBuffer)
  601. {
  602. CoTaskMemFree(*ppDescBuffer);
  603. *ppDescBuffer = NULL;
  604. }
  605. RRETURN(hr);
  606. }
  607. //+---------------------------------------------------------------------------
  608. //
  609. // Function: CBinder::GetProperties
  610. //
  611. // Synopsis: Sets Binder properties
  612. //
  613. // For more info see OLE DB 2.1 spec.
  614. //----------------------------------------------------------------------------
  615. STDMETHODIMP CBinder::SetProperties(
  616. ULONG cPropertySets,
  617. DBPROPSET rgPropertySets[ ])
  618. {
  619. ULONG ipropset, cprop, cpropError;
  620. DBPROPSTATUS dbpropstat;
  621. DBPROP *ppropNew, *ppropEnd, *ppropStored;
  622. BOOL fEqualOnly, fRestore;
  623. HRESULT hr;
  624. DBPROPSET *ppropset;
  625. auto_leave cs_auto_leave(m_autocs);
  626. TRYBLOCK
  627. //Let the property manager object verify the args.
  628. hr = m_dbProperties.VerifySetPropertiesArgs(cPropertySets,
  629. rgPropertySets);
  630. if (FAILED(hr))
  631. RRETURN(hr);
  632. cs_auto_leave.EnterCriticalSection();
  633. //Cycle thru each property set.
  634. for(ipropset =0, cprop =0,
  635. cpropError =0; ipropset < cPropertySets;
  636. ipropset++)
  637. {
  638. dbpropstat = DBPROPSTATUS_OK;
  639. fEqualOnly = FALSE;
  640. cprop += rgPropertySets[ipropset].cProperties;
  641. //Get the property set.
  642. ppropset = m_dbProperties.GetPropertySet(
  643. rgPropertySets[ipropset].guidPropertySet);
  644. //Error if this is NOT init property set,
  645. if(rgPropertySets[ipropset].guidPropertySet != DBPROPSET_DBINIT)
  646. {
  647. dbpropstat = DBPROPSTATUS_NOTSUPPORTED;
  648. }
  649. //ppropnew is beginning of property struct in memory
  650. //and ppropEnd is the end.
  651. ppropNew = rgPropertySets[ipropset].rgProperties;
  652. ppropEnd = ppropNew +rgPropertySets[ipropset].cProperties;
  653. if(fEqualOnly || dbpropstat == DBPROPSTATUS_OK)
  654. {
  655. //Cycle thru each property
  656. for(; ppropNew !=ppropEnd; ppropNew++)
  657. {
  658. ppropStored = (DBPROP *)m_dbProperties.GetProperty(
  659. rgPropertySets[ipropset].guidPropertySet,
  660. ppropNew->dwPropertyID);
  661. //if property is already there....
  662. if(ppropStored)
  663. {
  664. ppropNew->dwStatus = DBPROPSTATUS_OK;
  665. //Set error status if validation fails or
  666. //if type doesn't match
  667. //or if bad option or fEqualOnly is set
  668. //but new and existing values aren't the same.
  669. if (ppropNew->dwPropertyID == DBPROP_INIT_MODE && (V_VT(&(ppropNew->vValue)) == VT_I4) &&
  670. V_I4(&ppropNew->vValue) != DB_MODE_READ)
  671. ppropNew->dwStatus = DBPROPSTATUS_BADVALUE;
  672. else if(V_VT(&(ppropNew->vValue)) !=
  673. (m_dbProperties.GetPropertyInfo(
  674. rgPropertySets[ipropset].guidPropertySet,
  675. ppropNew->dwPropertyID))->vtType)
  676. {
  677. if(V_VT(&(ppropNew->vValue)) != VT_EMPTY)
  678. ppropNew->dwStatus = DBPROPSTATUS_BADVALUE;
  679. else if(fEqualOnly)
  680. ppropNew->dwStatus = DBPROPSTATUS_NOTSETTABLE;
  681. }
  682. else if(!GoodPropOption(ppropNew->dwOptions))
  683. ppropNew->dwStatus = DBPROPSTATUS_BADOPTION;
  684. else if(fEqualOnly && !VariantsEqual(
  685. &(ppropNew->vValue),
  686. &(ppropStored->vValue)))
  687. ppropNew->dwStatus = DBPROPSTATUS_NOTSETTABLE;
  688. //fEqualOnly was not set
  689. if(!fEqualOnly && ppropNew->dwStatus ==
  690. DBPROPSTATUS_OK)
  691. {
  692. // If VT_EMPTY we need to reset the default.
  693. if(V_VT(&(ppropNew->vValue)) == VT_EMPTY)
  694. {
  695. // Reset our initialization properties
  696. // to the default:
  697. if(ppropNew->dwPropertyID == DBPROP_INIT_LCID)
  698. {
  699. V_VT(&(ppropNew->vValue)) = VT_I4;
  700. V_I4(&(ppropNew->vValue)) =
  701. GetUserDefaultLCID();
  702. }
  703. else if ( ppropNew->dwPropertyID ==
  704. DBPROP_INIT_MODE)
  705. {
  706. V_VT(&(ppropNew->vValue)) = VT_I4;
  707. V_I4(&(ppropNew->vValue)) = DEFAULT_DBPROP_INIT_MODE;
  708. }
  709. else if ( ppropNew->dwPropertyID ==
  710. DBPROP_INIT_BINDFLAGS)
  711. {
  712. V_VT(&(ppropNew->vValue)) = VT_I4;
  713. V_I4(&(ppropNew->vValue)) = 0;
  714. }
  715. else if ( ppropNew->dwPropertyID ==
  716. DBPROP_INIT_LOCKOWNER)
  717. {
  718. V_VT(&(ppropNew->vValue)) = VT_BSTR;
  719. V_BSTR(&(ppropNew->vValue)) = NULL;
  720. }
  721. else if ( ppropNew->dwPropertyID ==
  722. DBPROP_AUTH_USERID)
  723. {
  724. V_VT(&(ppropNew->vValue)) = VT_BSTR;
  725. V_BSTR(&(ppropNew->vValue)) = NULL;
  726. }
  727. else if ( ppropNew->dwPropertyID ==
  728. DBPROP_AUTH_PASSWORD)
  729. {
  730. V_VT(&(ppropNew->vValue)) = VT_BSTR;
  731. V_BSTR(&(ppropNew->vValue)) = NULL;
  732. }
  733. else if ( ppropNew->dwPropertyID ==
  734. DBPROP_AUTH_ENCRYPT_PASSWORD)
  735. {
  736. V_VT(&(ppropNew->vValue)) = VT_BOOL;
  737. V_BOOL(&(ppropNew->vValue)) = VARIANT_FALSE;
  738. }
  739. fRestore = TRUE;
  740. }
  741. else
  742. fRestore = FALSE;
  743. //copy new value into the property variant.
  744. if(FAILED(VariantCopy(
  745. &(ppropStored->vValue),
  746. &(ppropNew->vValue))))
  747. ppropNew->dwStatus = DBPROPSTATUS_NOTSET;
  748. else if( ppropNew->dwPropertyID == DBPROP_AUTH_USERID ) {
  749. if(S_OK != m_pSession->SetUserName(V_BSTR(&(ppropNew->vValue))))
  750. ppropNew->dwStatus = DBPROPSTATUS_NOTSET;
  751. }
  752. else if( ppropNew->dwPropertyID == DBPROP_AUTH_PASSWORD ) {
  753. if(S_OK != m_pSession->SetPassword(V_BSTR(&(ppropNew->vValue))))
  754. ppropNew->dwStatus = DBPROPSTATUS_NOTSET;
  755. }
  756. else if( ppropNew->dwPropertyID == DBPROP_AUTH_ENCRYPT_PASSWORD ) {
  757. if(V_BOOL(&(ppropNew->vValue)) == VARIANT_TRUE)
  758. m_pSession->SetAuthFlag(ADS_SECURE_AUTHENTICATION);
  759. }
  760. if(fRestore)
  761. VariantInit(&(ppropNew->vValue));
  762. }
  763. }
  764. else
  765. ppropNew->dwStatus = DBPROPSTATUS_NOTSUPPORTED;
  766. if(ppropNew->dwStatus != DBPROPSTATUS_OK)
  767. cpropError++;
  768. }
  769. }
  770. else
  771. {
  772. cpropError += rgPropertySets[ipropset].cProperties;
  773. for(; ppropNew !=ppropEnd; ppropNew++)
  774. ppropNew->dwStatus = dbpropstat;
  775. }
  776. } //for (ipropset = 0 ...
  777. CATCHBLOCKRETURN
  778. hr = cpropError ?
  779. ((cpropError <cprop) ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED)
  780. : S_OK;
  781. RRETURN(hr);
  782. }
  783. //IDBBinderProperties
  784. //+---------------------------------------------------------------------------
  785. //
  786. // Function: CBinder::Reset
  787. //
  788. // Synopsis: Resets binder properties to default values.
  789. //
  790. // For more info see OLE DB 2.5 spec.
  791. //----------------------------------------------------------------------------
  792. STDMETHODIMP CBinder::Reset( void)
  793. {
  794. HRESULT hr = NOERROR;
  795. DBPROP * pprop;
  796. auto_leave cs_auto_leave(m_autocs);
  797. TRYBLOCK
  798. cs_auto_leave.EnterCriticalSection();
  799. pprop = (DBPROP *) m_dbProperties.GetProperty (
  800. DBPROPSET_DBINIT,
  801. DBPROP_INIT_LCID );
  802. ADsAssert ( pprop );
  803. VariantClear ( &pprop->vValue );
  804. V_VT(&pprop->vValue) = VT_I4;
  805. V_I4(&pprop->vValue) = GetUserDefaultLCID();
  806. pprop = (DBPROP *) m_dbProperties.GetProperty (
  807. DBPROPSET_DBINIT,
  808. DBPROP_INIT_MODE );
  809. ADsAssert ( pprop );
  810. VariantClear ( &pprop->vValue );
  811. V_VT(&pprop->vValue) = VT_I4;
  812. V_I4(&pprop->vValue) = DEFAULT_DBPROP_INIT_MODE;
  813. pprop = (DBPROP *) m_dbProperties.GetProperty (
  814. DBPROPSET_DBINIT,
  815. DBPROP_INIT_BINDFLAGS );
  816. ADsAssert ( pprop );
  817. VariantClear ( &pprop->vValue );
  818. V_VT(&pprop->vValue) = VT_I4;
  819. V_I4(&pprop->vValue) = 0;
  820. pprop = (DBPROP *) m_dbProperties.GetProperty (
  821. DBPROPSET_DBINIT,
  822. DBPROP_INIT_LOCKOWNER );
  823. ADsAssert ( pprop );
  824. VariantClear ( &pprop->vValue );
  825. V_VT(&pprop->vValue) = VT_BSTR;
  826. V_BSTR(&pprop->vValue) = NULL;
  827. pprop = (DBPROP *) m_dbProperties.GetProperty (
  828. DBPROPSET_DBINIT,
  829. DBPROP_AUTH_USERID );
  830. ADsAssert ( pprop );
  831. VariantClear ( &pprop->vValue );
  832. V_VT(&pprop->vValue) = VT_BSTR;
  833. V_BSTR(&pprop->vValue) = NULL;
  834. m_pSession->SetUserName(NULL);
  835. pprop = (DBPROP *) m_dbProperties.GetProperty (
  836. DBPROPSET_DBINIT,
  837. DBPROP_AUTH_PASSWORD );
  838. ADsAssert ( pprop );
  839. VariantClear ( &pprop->vValue );
  840. V_VT(&pprop->vValue) = VT_BSTR;
  841. V_BSTR(&pprop->vValue) = NULL;
  842. m_pSession->SetPassword(NULL);
  843. pprop = (DBPROP *) m_dbProperties.GetProperty (
  844. DBPROPSET_DBINIT,
  845. DBPROP_AUTH_ENCRYPT_PASSWORD );
  846. ADsAssert ( pprop );
  847. VariantClear ( &pprop->vValue );
  848. V_VT(&pprop->vValue) = VT_BOOL;
  849. V_BOOL(&pprop->vValue) = VARIANT_FALSE;
  850. m_pSession->SetAuthFlag(0);
  851. CATCHBLOCKRETURN
  852. RRETURN(hr);
  853. }
  854. //Helper functions
  855. //+---------------------------------------------------------------------------
  856. //
  857. // Function: CBinder::InitializeProperties
  858. //
  859. // Synopsis: Initializes binder init property group to default values.
  860. //
  861. //----------------------------------------------------------------------------
  862. HRESULT CBinder::InitializeProperties()
  863. {
  864. HRESULT hr;
  865. DBPROP prop;
  866. DBPROPINFO * ppropinfo;
  867. // Initialize the DBPROP structure:
  868. //
  869. ZeroMemory ( &prop, sizeof (prop) );
  870. prop.dwOptions = DBPROPOPTIONS_OPTIONAL;
  871. prop.dwStatus = DBPROPSTATUS_OK;
  872. // Add the LCID:
  873. //
  874. prop.dwPropertyID = DBPROP_INIT_LCID;
  875. V_VT(&prop.vValue) = VT_I4;
  876. V_I4(&prop.vValue) = GetUserDefaultLCID ();
  877. hr = m_dbProperties.SetProperty (
  878. DBPROPSET_DBINIT,
  879. prop,
  880. TRUE,
  881. DESC_DBPROP_INIT_LCID
  882. );
  883. BAIL_ON_FAILURE(hr);
  884. // Make it writable:
  885. ppropinfo = (DBPROPINFO *)m_dbProperties.GetPropertyInfo(
  886. DBPROPSET_DBINIT,
  887. DBPROP_INIT_LCID);
  888. ADsAssert ( ppropinfo );
  889. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  890. // Add the DB_MODE:
  891. //
  892. prop.dwPropertyID = DBPROP_INIT_MODE;
  893. V_VT(&prop.vValue) = VT_I4;
  894. V_I4(&prop.vValue) = DEFAULT_DBPROP_INIT_MODE;
  895. hr = m_dbProperties.SetProperty (
  896. DBPROPSET_DBINIT,
  897. prop,
  898. TRUE,
  899. DESC_DBPROP_INIT_MODE
  900. );
  901. BAIL_ON_FAILURE(hr);
  902. // Make it writable:
  903. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  904. DBPROPSET_DBINIT,
  905. DBPROP_INIT_MODE );
  906. ADsAssert ( ppropinfo );
  907. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  908. // Add the BindFlags property:
  909. //
  910. prop.dwPropertyID = DBPROP_INIT_BINDFLAGS;
  911. V_VT(&prop.vValue) = VT_I4;
  912. V_I4(&prop.vValue) = 0;
  913. hr = m_dbProperties.SetProperty (
  914. DBPROPSET_DBINIT,
  915. prop,
  916. TRUE,
  917. DESC_DBPROP_INIT_BINDFLAGS
  918. );
  919. BAIL_ON_FAILURE(hr);
  920. // Make it writable:
  921. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  922. DBPROPSET_DBINIT,
  923. DBPROP_INIT_BINDFLAGS );
  924. ADsAssert ( ppropinfo );
  925. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  926. // Add the LOCKOWNER property:
  927. //
  928. prop.dwPropertyID = DBPROP_INIT_LOCKOWNER;
  929. V_VT(&prop.vValue) = VT_BSTR;
  930. V_BSTR(&prop.vValue) = NULL;
  931. hr = m_dbProperties.SetProperty (
  932. DBPROPSET_DBINIT,
  933. prop,
  934. TRUE,
  935. DESC_DBPROP_INIT_LOCKOWNER
  936. );
  937. BAIL_ON_FAILURE(hr);
  938. // Make it writable:
  939. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  940. DBPROPSET_DBINIT,
  941. DBPROP_INIT_LOCKOWNER );
  942. ADsAssert ( ppropinfo );
  943. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  944. // Add the USERID property:
  945. //
  946. prop.dwPropertyID = DBPROP_AUTH_USERID;
  947. V_VT(&prop.vValue) = VT_BSTR;
  948. V_BSTR(&prop.vValue) = NULL;
  949. hr = m_dbProperties.SetProperty (
  950. DBPROPSET_DBINIT,
  951. prop,
  952. TRUE,
  953. DESC_DBPROP_USERID
  954. );
  955. BAIL_ON_FAILURE(hr);
  956. // Make it writable:
  957. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  958. DBPROPSET_DBINIT,
  959. DBPROP_AUTH_USERID );
  960. ADsAssert ( ppropinfo );
  961. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  962. // Add the PASSWORD property:
  963. //
  964. prop.dwPropertyID = DBPROP_AUTH_PASSWORD;
  965. V_VT(&prop.vValue) = VT_BSTR;
  966. V_BSTR(&prop.vValue) = NULL;
  967. hr = m_dbProperties.SetProperty (
  968. DBPROPSET_DBINIT,
  969. prop,
  970. TRUE,
  971. DESC_DBPROP_PASSWORD
  972. );
  973. BAIL_ON_FAILURE(hr);
  974. // Make it writable:
  975. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  976. DBPROPSET_DBINIT,
  977. DBPROP_AUTH_PASSWORD );
  978. ADsAssert ( ppropinfo );
  979. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  980. // Add the ENCRYPT_PASSWORD property:
  981. //
  982. prop.dwPropertyID = DBPROP_AUTH_ENCRYPT_PASSWORD;
  983. V_VT(&prop.vValue) = VT_BOOL;
  984. V_BOOL(&prop.vValue) = VARIANT_FALSE;
  985. hr = m_dbProperties.SetProperty (
  986. DBPROPSET_DBINIT,
  987. prop,
  988. TRUE,
  989. DESC_DBPROP_ENCRYPT_PASSWORD
  990. );
  991. BAIL_ON_FAILURE(hr);
  992. // Make it writable:
  993. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  994. DBPROPSET_DBINIT,
  995. DBPROP_AUTH_ENCRYPT_PASSWORD );
  996. ADsAssert ( ppropinfo );
  997. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  998. error:
  999. RRETURN ( hr );
  1000. }
  1001. //+---------------------------------------------------------------------------
  1002. //
  1003. // Function: CBinder::BindFlagsFromDbProps
  1004. //
  1005. // Synopsis: extracts bind flags from initialization properties.
  1006. //
  1007. //----------------------------------------------------------------------------
  1008. DWORD CBinder::BindFlagsFromDbProps ( )
  1009. {
  1010. const DBPROP * ppropMode;
  1011. const DBPROP * ppropBindFlags;
  1012. ppropMode = m_dbProperties.GetProperty (
  1013. DBPROPSET_DBINIT,
  1014. DBPROP_INIT_MODE );
  1015. ADsAssert ( ppropMode );
  1016. ppropBindFlags = m_dbProperties.GetProperty (
  1017. DBPROPSET_DBINIT,
  1018. DBPROP_INIT_BINDFLAGS );
  1019. ADsAssert ( ppropBindFlags );
  1020. const VARIANT * pvarMode = &ppropMode->vValue;
  1021. const VARIANT * pvarBindFlags = &ppropBindFlags->vValue;
  1022. DWORD dwResult = 0;
  1023. if ( V_VT(pvarMode) == VT_I4 ) {
  1024. DWORD dwModeMask =
  1025. DB_MODE_READ |
  1026. DB_MODE_WRITE |
  1027. DB_MODE_READWRITE |
  1028. DB_MODE_SHARE_DENY_READ |
  1029. DB_MODE_SHARE_DENY_WRITE |
  1030. DB_MODE_SHARE_EXCLUSIVE |
  1031. DB_MODE_SHARE_DENY_NONE;
  1032. dwResult |= V_I4(pvarMode) & dwModeMask;
  1033. }
  1034. if ( V_VT(pvarBindFlags) == VT_I4 ) {
  1035. DWORD dwBindFlagProp = V_I4(pvarBindFlags);
  1036. DWORD dwBindFlags = 0;
  1037. if ( dwBindFlagProp & DB_BINDFLAGS_DELAYFETCHCOLUMNS ) {
  1038. dwBindFlags |= DBBINDURLFLAG_DELAYFETCHCOLUMNS;
  1039. }
  1040. if ( dwBindFlagProp & DB_BINDFLAGS_DELAYFETCHSTREAM ) {
  1041. dwBindFlags |= DBBINDURLFLAG_DELAYFETCHSTREAM;
  1042. }
  1043. if ( dwBindFlagProp & DB_BINDFLAGS_RECURSIVE ) {
  1044. dwBindFlags |= DBBINDURLFLAG_RECURSIVE;
  1045. }
  1046. if ( dwBindFlagProp & DB_BINDFLAGS_OUTPUT ) {
  1047. dwBindFlags |= DBBINDURLFLAG_OUTPUT;
  1048. }
  1049. dwResult |= V_I4(pvarBindFlags) | dwBindFlags;
  1050. }
  1051. RRETURN (dwResult);
  1052. }
  1053. //+---------------------------------------------------------------------------
  1054. //
  1055. // Function: CBinder::CreateDataSource
  1056. //
  1057. // Synopsis: Creates an implicit DataSource object for this binder object.
  1058. //
  1059. //----------------------------------------------------------------------------
  1060. HRESULT CBinder::CreateDataSource()
  1061. {
  1062. //Call this function only at creation time.
  1063. ADsAssert(m_pDataSource == NULL && m_pDBInitialize.get() == NULL);
  1064. HRESULT hr = S_OK;
  1065. //Create a DataSource object. Note: starts with refcount = 1.
  1066. m_pDataSource = new CDSOObject( NULL );
  1067. if (m_pDataSource == NULL)
  1068. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1069. //Initialize the object
  1070. if (!m_pDataSource->FInit())
  1071. {
  1072. delete m_pDataSource;
  1073. m_pDataSource = NULL;
  1074. BAIL_ON_FAILURE(hr = E_FAIL);
  1075. }
  1076. //Get IDBInitialize interface and store it in (auto)member variable.
  1077. //This will also make sure the DataSource object stays alive during
  1078. //the lifetime of binder object.
  1079. hr = m_pDataSource->QueryInterface(__uuidof(IDBInitialize),
  1080. (void**)&m_pDBInitialize);
  1081. BAIL_ON_FAILURE(hr);
  1082. //We already stored datasource object reference in auto_rel object,
  1083. //Now release once, since datasource object is created with refcount = 1.
  1084. m_pDataSource->Release();
  1085. error:
  1086. RRETURN ( hr );
  1087. }
  1088. //+---------------------------------------------------------------------------
  1089. //
  1090. // Function: CBinder::CreateSession
  1091. //
  1092. // Synopsis: Creates an implicit Session object for this binder object.
  1093. //
  1094. //----------------------------------------------------------------------------
  1095. HRESULT CBinder::CreateSession()
  1096. {
  1097. //Call this function only at creation time.
  1098. ADsAssert(m_pSession == NULL && m_pOpenRowset.get() == NULL);
  1099. HRESULT hr = S_OK;
  1100. CCredentials creds;
  1101. //create a session object. Note: starts with refcount = 1
  1102. m_pSession = new CSessionObject( NULL );
  1103. if (m_pSession == NULL)
  1104. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1105. //Initialize session object passing null credentials.
  1106. //Note: This increments refcount on DataSource object.
  1107. if (!m_pSession->FInit(m_pDataSource, creds))
  1108. BAIL_ON_FAILURE(hr = E_FAIL);
  1109. hr = m_pSession->QueryInterface(__uuidof(IOpenRowset),
  1110. (void **)&m_pOpenRowset);
  1111. BAIL_ON_FAILURE(hr);
  1112. //We already stored session reference in auto_rel object.
  1113. //Now release once, since session object is created
  1114. //with refcount = 1
  1115. m_pSession->Release();
  1116. RRETURN ( S_OK );
  1117. error:
  1118. //if we're here, the Session object is no good.
  1119. if (m_pSession)
  1120. {
  1121. delete m_pSession;
  1122. m_pSession = NULL;
  1123. }
  1124. RRETURN ( hr );
  1125. }
  1126. #endif