Leaked source code of windows server 2003
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.

1317 lines
59 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. if (ipropset >= 0)
  325. iprop = rgPropertySetsOutput[ipropset].cProperties;
  326. }
  327. if(rgPropertySetsOutput)
  328. CoTaskMemFree(rgPropertySetsOutput);
  329. RRETURN(hr);
  330. }
  331. //+---------------------------------------------------------------------------
  332. //
  333. // Function: CBinder::GetPropertyInfo
  334. //
  335. // Synopsis: Gets information about requested properties
  336. //
  337. // For more info see OLE DB 2.1 spec.
  338. //----------------------------------------------------------------------------
  339. STDMETHODIMP CBinder::GetPropertyInfo(
  340. ULONG cPropertySets,
  341. const DBPROPIDSET rgPropertySets[ ],
  342. ULONG *pcPropertyInfoSets,
  343. DBPROPINFOSET **prgPropertyInfoSets,
  344. OLECHAR **ppDescBuffer)
  345. {
  346. HRESULT hr;
  347. BOOL fPropInError, fSpecialSets, fCopy =FALSE;
  348. ULONG ipropset = 0, iprop, cProperty, cprop = 0, cpropError=0;
  349. ULONG_PTR cchDescBuffer, ichDescBuffer;
  350. DBPROPINFOSET *rgPropertyInfoSetsOutput = NULL, *ppropinfoset;
  351. const DBPROPINFO UNALIGNED *pdbpropinfoSrc;
  352. PDBPROPINFO pdbpropinfo;
  353. auto_leave cs_auto_leave(m_autocs);
  354. TRYBLOCK
  355. if(ppDescBuffer)
  356. {
  357. *ppDescBuffer = NULL;
  358. cchDescBuffer = 0;
  359. ichDescBuffer = 0;
  360. }
  361. //Let the property manager object check and init arguments
  362. hr = m_dbProperties.CheckAndInitPropArgs(cPropertySets,
  363. rgPropertySets,
  364. pcPropertyInfoSets,
  365. (void **)prgPropertyInfoSets,
  366. &fPropInError,
  367. &fSpecialSets);
  368. if(FAILED(hr))
  369. RRETURN(hr);
  370. else if(fPropInError)
  371. RRETURN(E_INVALIDARG);
  372. cs_auto_leave.EnterCriticalSection();
  373. //if cPropertySets is zero, return INIT property set info
  374. if(cPropertySets == 0)
  375. {
  376. cPropertySets = 1;
  377. fCopy = TRUE;
  378. }
  379. rgPropertyInfoSetsOutput = (DBPROPINFOSET *)
  380. CoTaskMemAlloc(cPropertySets*sizeof(DBPROPINFOSET));
  381. if (!rgPropertyInfoSetsOutput)
  382. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  383. if(fCopy)
  384. {
  385. for (ipropset=0; ipropset <cPropertySets; ++ipropset)
  386. {
  387. hr = m_dbProperties.CopyPropertyInfoSet(
  388. ipropset,
  389. &rgPropertyInfoSetsOutput[ipropset],
  390. ppDescBuffer,
  391. &cchDescBuffer,
  392. &ichDescBuffer);
  393. if (FAILED(hr))
  394. break;
  395. }
  396. BAIL_ON_FAILURE(hr);
  397. }
  398. else
  399. {
  400. //copy passed in property set info to output array.
  401. memcpy( rgPropertyInfoSetsOutput,
  402. rgPropertySets,
  403. cPropertySets *sizeof(DBPROPSET));
  404. //Cycle thru each requested property set
  405. for(ipropset=0, cprop =0; ipropset<cPropertySets; ipropset++)
  406. {
  407. iprop =0;
  408. //Handle each special set
  409. if( rgPropertySets[ipropset].guidPropertySet ==
  410. DBPROPSET_DBINITALL)
  411. {
  412. cprop++;
  413. hr = m_dbProperties.CopyPropertyInfoSet(DBPROPSET_DBINIT,
  414. &rgPropertyInfoSetsOutput[ipropset],
  415. ppDescBuffer,
  416. &cchDescBuffer,
  417. &ichDescBuffer);
  418. BAIL_ON_FAILURE(hr);
  419. }
  420. else if(fSpecialSets)
  421. {
  422. if(rgPropertySets[ipropset].guidPropertySet ==
  423. DBPROPSET_DATASOURCEALL)
  424. rgPropertyInfoSetsOutput[ipropset].guidPropertySet =
  425. DBPROPSET_DATASOURCE;
  426. else if (rgPropertyInfoSetsOutput[ipropset].guidPropertySet ==
  427. DBPROPSET_SESSIONALL)
  428. rgPropertyInfoSetsOutput[ipropset].guidPropertySet =
  429. DBPROPSET_SESSION;
  430. else if(rgPropertyInfoSetsOutput[ipropset].guidPropertySet ==
  431. DBPROPSET_ROWSETALL)
  432. rgPropertyInfoSetsOutput[ipropset].guidPropertySet =
  433. DBPROPSET_ROWSET;
  434. else
  435. rgPropertyInfoSetsOutput[ipropset].guidPropertySet =
  436. DBPROPSET_DATASOURCEINFO;
  437. rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos = NULL;
  438. rgPropertyInfoSetsOutput[ipropset].cPropertyInfos = 0;
  439. cprop++;
  440. cpropError++;
  441. }
  442. else //Now the regular property sets
  443. {
  444. ppropinfoset =
  445. m_dbProperties.GetPropertyInfoSet(
  446. rgPropertySets[ipropset].guidPropertySet);
  447. cProperty = rgPropertySets[ipropset].cPropertyIDs;
  448. if(cProperty)
  449. {
  450. cprop += cProperty;
  451. //allocate memory for each property info
  452. rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos
  453. = (DBPROPINFO *)
  454. CoTaskMemAlloc(cProperty *sizeof(DBPROPINFO));
  455. if( rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos
  456. == NULL)
  457. {
  458. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  459. }
  460. //zero memory
  461. memset(rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos,
  462. 0x00,
  463. cProperty*sizeof(DBPROPINFO));
  464. //if the requested property info set is empty,
  465. //store error information into the output array.
  466. if(ppropinfoset == 0)
  467. {
  468. cpropError += cProperty;
  469. for(iprop =0; iprop <cProperty; iprop++)
  470. {
  471. rgPropertyInfoSetsOutput[ipropset].
  472. rgPropertyInfos[iprop].dwPropertyID =
  473. rgPropertySets[ipropset].rgPropertyIDs[iprop];
  474. rgPropertyInfoSetsOutput[ipropset].
  475. rgPropertyInfos[iprop].dwFlags =
  476. DBPROPFLAGS_NOTSUPPORTED;
  477. }
  478. }
  479. //otherwise, try to get property info for each property.
  480. else
  481. {
  482. pdbpropinfo =
  483. rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos;
  484. for(; iprop <cProperty; iprop++, pdbpropinfo++)
  485. {
  486. pdbpropinfoSrc = m_dbProperties.GetPropertyInfo(
  487. rgPropertySets[ipropset].guidPropertySet,
  488. rgPropertySets[ipropset].rgPropertyIDs[iprop]);
  489. if(pdbpropinfoSrc)
  490. *pdbpropinfo = *pdbpropinfoSrc;
  491. else
  492. {
  493. //unable to get property info
  494. //for this property. Store error info.
  495. pdbpropinfo->dwPropertyID =
  496. rgPropertySets[ipropset].
  497. rgPropertyIDs[iprop];
  498. pdbpropinfo->dwFlags =
  499. DBPROPFLAGS_NOTSUPPORTED;
  500. cpropError++;
  501. }
  502. }
  503. //Now copy property descriptions
  504. //for all properties in this set
  505. hr = m_dbProperties.CopyPropertyDescriptions(
  506. &rgPropertyInfoSetsOutput[ipropset],
  507. ppDescBuffer,
  508. &cchDescBuffer,
  509. &ichDescBuffer);
  510. BAIL_ON_FAILURE(hr);
  511. }
  512. }
  513. else //no properties stored in this set.
  514. {
  515. cprop++;
  516. //if the returned set itself is NULL, nothing
  517. //to copy.
  518. if(ppropinfoset == NULL)
  519. {
  520. cpropError++;
  521. rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos =
  522. NULL;
  523. }
  524. //otherwise, just copy whatever info we have
  525. //in the set.
  526. else
  527. {
  528. hr = m_dbProperties.CopyPropertyInfoSet(
  529. rgPropertySets[ipropset].guidPropertySet,
  530. &rgPropertyInfoSetsOutput[ipropset],
  531. ppDescBuffer,
  532. &cchDescBuffer,
  533. &ichDescBuffer);
  534. BAIL_ON_FAILURE(hr);
  535. }
  536. }
  537. }
  538. } //for (ipropset = 0 ....
  539. } //if (fcopy) ... else ...
  540. CATCHBLOCKBAIL(hr)
  541. *pcPropertyInfoSets = cPropertySets;
  542. *prgPropertyInfoSets = rgPropertyInfoSetsOutput;
  543. // So far we have put relative offsets into pointers to property
  544. // descriptions. They have to be rebased on the beginning of the
  545. // desription strings buffer.
  546. if(ppDescBuffer && *ppDescBuffer)
  547. {
  548. for(ipropset=0; ipropset < cPropertySets; ipropset++)
  549. for(iprop =0;
  550. iprop <rgPropertyInfoSetsOutput[ipropset].cPropertyInfos;
  551. iprop++)
  552. {
  553. // Only do this if we really support the property:
  554. //
  555. if ( rgPropertyInfoSetsOutput[ipropset].
  556. rgPropertyInfos[iprop].dwFlags !=
  557. DBPROPFLAGS_NOTSUPPORTED )
  558. {
  559. rgPropertyInfoSetsOutput[ipropset].
  560. rgPropertyInfos[iprop].pwszDescription =
  561. (WCHAR *)(*ppDescBuffer) +
  562. (ULONG_PTR)(rgPropertyInfoSetsOutput[ipropset].
  563. rgPropertyInfos[iprop].pwszDescription);
  564. }
  565. else {
  566. ADsAssert ( rgPropertyInfoSetsOutput[ipropset].
  567. rgPropertyInfos[iprop].pwszDescription
  568. == NULL );
  569. }
  570. }
  571. }
  572. else
  573. {
  574. // Assert that we're not passing back any strings:
  575. //
  576. for(ipropset=0; ipropset < cPropertySets; ipropset++)
  577. {
  578. for(iprop =0;
  579. iprop < rgPropertyInfoSetsOutput[ipropset].cPropertyInfos;
  580. iprop++)
  581. {
  582. ADsAssert ( rgPropertyInfoSetsOutput[ipropset].
  583. rgPropertyInfos[iprop].pwszDescription == NULL );
  584. }
  585. }
  586. }
  587. hr = cpropError ?
  588. ((cpropError <cprop) ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED)
  589. : S_OK;
  590. RRETURN(hr);
  591. error:
  592. ULONG i;
  593. for ( i = 0; i < ipropset; i++ )
  594. {
  595. if( rgPropertyInfoSetsOutput
  596. && rgPropertyInfoSetsOutput[i].cPropertyInfos
  597. && rgPropertyInfoSetsOutput[i].rgPropertyInfos)
  598. CoTaskMemFree(rgPropertyInfoSetsOutput[i].rgPropertyInfos);
  599. }
  600. if(rgPropertyInfoSetsOutput)
  601. CoTaskMemFree(rgPropertyInfoSetsOutput);
  602. if(ppDescBuffer && *ppDescBuffer)
  603. {
  604. CoTaskMemFree(*ppDescBuffer);
  605. *ppDescBuffer = NULL;
  606. }
  607. RRETURN(hr);
  608. }
  609. //+---------------------------------------------------------------------------
  610. //
  611. // Function: CBinder::GetProperties
  612. //
  613. // Synopsis: Sets Binder properties
  614. //
  615. // For more info see OLE DB 2.1 spec.
  616. //----------------------------------------------------------------------------
  617. STDMETHODIMP CBinder::SetProperties(
  618. ULONG cPropertySets,
  619. DBPROPSET rgPropertySets[ ])
  620. {
  621. ULONG ipropset, cprop, cpropError;
  622. DBPROPSTATUS dbpropstat;
  623. DBPROP *ppropNew, *ppropEnd, *ppropStored;
  624. BOOL fEqualOnly, fRestore;
  625. HRESULT hr;
  626. DBPROPSET *ppropset;
  627. auto_leave cs_auto_leave(m_autocs);
  628. TRYBLOCK
  629. //Let the property manager object verify the args.
  630. hr = m_dbProperties.VerifySetPropertiesArgs(cPropertySets,
  631. rgPropertySets);
  632. if (FAILED(hr))
  633. RRETURN(hr);
  634. cs_auto_leave.EnterCriticalSection();
  635. //Cycle thru each property set.
  636. for(ipropset =0, cprop =0,
  637. cpropError =0; ipropset < cPropertySets;
  638. ipropset++)
  639. {
  640. dbpropstat = DBPROPSTATUS_OK;
  641. fEqualOnly = FALSE;
  642. cprop += rgPropertySets[ipropset].cProperties;
  643. //Get the property set.
  644. ppropset = m_dbProperties.GetPropertySet(
  645. rgPropertySets[ipropset].guidPropertySet);
  646. //Error if this is NOT init property set,
  647. if(rgPropertySets[ipropset].guidPropertySet != DBPROPSET_DBINIT)
  648. {
  649. dbpropstat = DBPROPSTATUS_NOTSUPPORTED;
  650. }
  651. //ppropnew is beginning of property struct in memory
  652. //and ppropEnd is the end.
  653. ppropNew = rgPropertySets[ipropset].rgProperties;
  654. ppropEnd = ppropNew +rgPropertySets[ipropset].cProperties;
  655. if(fEqualOnly || dbpropstat == DBPROPSTATUS_OK)
  656. {
  657. //Cycle thru each property
  658. for(; ppropNew !=ppropEnd; ppropNew++)
  659. {
  660. ppropStored = (DBPROP *)m_dbProperties.GetProperty(
  661. rgPropertySets[ipropset].guidPropertySet,
  662. ppropNew->dwPropertyID);
  663. //if property is already there....
  664. if(ppropStored)
  665. {
  666. ppropNew->dwStatus = DBPROPSTATUS_OK;
  667. //Set error status if validation fails or
  668. //if type doesn't match
  669. //or if bad option or fEqualOnly is set
  670. //but new and existing values aren't the same.
  671. if (ppropNew->dwPropertyID == DBPROP_INIT_MODE && (V_VT(&(ppropNew->vValue)) == VT_I4) &&
  672. V_I4(&ppropNew->vValue) != DB_MODE_READ)
  673. ppropNew->dwStatus = DBPROPSTATUS_BADVALUE;
  674. else if(V_VT(&(ppropNew->vValue)) !=
  675. (m_dbProperties.GetPropertyInfo(
  676. rgPropertySets[ipropset].guidPropertySet,
  677. ppropNew->dwPropertyID))->vtType)
  678. {
  679. if(V_VT(&(ppropNew->vValue)) != VT_EMPTY)
  680. ppropNew->dwStatus = DBPROPSTATUS_BADVALUE;
  681. else if(fEqualOnly)
  682. ppropNew->dwStatus = DBPROPSTATUS_NOTSETTABLE;
  683. }
  684. else if(!GoodPropOption(ppropNew->dwOptions))
  685. ppropNew->dwStatus = DBPROPSTATUS_BADOPTION;
  686. else if(fEqualOnly && !VariantsEqual(
  687. &(ppropNew->vValue),
  688. &(ppropStored->vValue)))
  689. ppropNew->dwStatus = DBPROPSTATUS_NOTSETTABLE;
  690. //fEqualOnly was not set
  691. if(!fEqualOnly && ppropNew->dwStatus ==
  692. DBPROPSTATUS_OK)
  693. {
  694. // If VT_EMPTY we need to reset the default.
  695. if(V_VT(&(ppropNew->vValue)) == VT_EMPTY)
  696. {
  697. // Reset our initialization properties
  698. // to the default:
  699. if(ppropNew->dwPropertyID == DBPROP_INIT_LCID)
  700. {
  701. V_VT(&(ppropNew->vValue)) = VT_I4;
  702. V_I4(&(ppropNew->vValue)) =
  703. GetUserDefaultLCID();
  704. }
  705. else if ( ppropNew->dwPropertyID ==
  706. DBPROP_INIT_MODE)
  707. {
  708. V_VT(&(ppropNew->vValue)) = VT_I4;
  709. V_I4(&(ppropNew->vValue)) = DEFAULT_DBPROP_INIT_MODE;
  710. }
  711. else if ( ppropNew->dwPropertyID ==
  712. DBPROP_INIT_BINDFLAGS)
  713. {
  714. V_VT(&(ppropNew->vValue)) = VT_I4;
  715. V_I4(&(ppropNew->vValue)) = 0;
  716. }
  717. else if ( ppropNew->dwPropertyID ==
  718. DBPROP_INIT_LOCKOWNER)
  719. {
  720. V_VT(&(ppropNew->vValue)) = VT_BSTR;
  721. V_BSTR(&(ppropNew->vValue)) = NULL;
  722. }
  723. else if ( ppropNew->dwPropertyID ==
  724. DBPROP_AUTH_USERID)
  725. {
  726. V_VT(&(ppropNew->vValue)) = VT_BSTR;
  727. V_BSTR(&(ppropNew->vValue)) = NULL;
  728. }
  729. else if ( ppropNew->dwPropertyID ==
  730. DBPROP_AUTH_PASSWORD)
  731. {
  732. V_VT(&(ppropNew->vValue)) = VT_BSTR;
  733. V_BSTR(&(ppropNew->vValue)) = NULL;
  734. }
  735. else if ( ppropNew->dwPropertyID ==
  736. DBPROP_AUTH_ENCRYPT_PASSWORD)
  737. {
  738. V_VT(&(ppropNew->vValue)) = VT_BOOL;
  739. V_BOOL(&(ppropNew->vValue)) = VARIANT_FALSE;
  740. }
  741. fRestore = TRUE;
  742. }
  743. else
  744. fRestore = FALSE;
  745. //copy new value into the property variant.
  746. if(FAILED(VariantCopy(
  747. &(ppropStored->vValue),
  748. &(ppropNew->vValue))))
  749. ppropNew->dwStatus = DBPROPSTATUS_NOTSET;
  750. else if( ppropNew->dwPropertyID == DBPROP_AUTH_USERID ) {
  751. if(S_OK != m_pSession->SetUserName(V_BSTR(&(ppropNew->vValue))))
  752. ppropNew->dwStatus = DBPROPSTATUS_NOTSET;
  753. }
  754. else if( ppropNew->dwPropertyID == DBPROP_AUTH_PASSWORD ) {
  755. if(S_OK != m_pSession->SetPassword(V_BSTR(&(ppropNew->vValue))))
  756. ppropNew->dwStatus = DBPROPSTATUS_NOTSET;
  757. }
  758. else if( ppropNew->dwPropertyID == DBPROP_AUTH_ENCRYPT_PASSWORD ) {
  759. if(V_BOOL(&(ppropNew->vValue)) == VARIANT_TRUE)
  760. m_pSession->SetAuthFlag(ADS_SECURE_AUTHENTICATION);
  761. }
  762. if(fRestore)
  763. VariantInit(&(ppropNew->vValue));
  764. }
  765. }
  766. else
  767. ppropNew->dwStatus = DBPROPSTATUS_NOTSUPPORTED;
  768. if(ppropNew->dwStatus != DBPROPSTATUS_OK)
  769. cpropError++;
  770. }
  771. }
  772. else
  773. {
  774. cpropError += rgPropertySets[ipropset].cProperties;
  775. for(; ppropNew !=ppropEnd; ppropNew++)
  776. ppropNew->dwStatus = dbpropstat;
  777. }
  778. } //for (ipropset = 0 ...
  779. CATCHBLOCKRETURN
  780. hr = cpropError ?
  781. ((cpropError <cprop) ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED)
  782. : S_OK;
  783. RRETURN(hr);
  784. }
  785. //IDBBinderProperties
  786. //+---------------------------------------------------------------------------
  787. //
  788. // Function: CBinder::Reset
  789. //
  790. // Synopsis: Resets binder properties to default values.
  791. //
  792. // For more info see OLE DB 2.5 spec.
  793. //----------------------------------------------------------------------------
  794. STDMETHODIMP CBinder::Reset( void)
  795. {
  796. HRESULT hr = NOERROR;
  797. DBPROP * pprop;
  798. auto_leave cs_auto_leave(m_autocs);
  799. TRYBLOCK
  800. cs_auto_leave.EnterCriticalSection();
  801. pprop = (DBPROP *) m_dbProperties.GetProperty (
  802. DBPROPSET_DBINIT,
  803. DBPROP_INIT_LCID );
  804. ADsAssert ( pprop );
  805. VariantClear ( &pprop->vValue );
  806. V_VT(&pprop->vValue) = VT_I4;
  807. V_I4(&pprop->vValue) = GetUserDefaultLCID();
  808. pprop = (DBPROP *) m_dbProperties.GetProperty (
  809. DBPROPSET_DBINIT,
  810. DBPROP_INIT_MODE );
  811. ADsAssert ( pprop );
  812. VariantClear ( &pprop->vValue );
  813. V_VT(&pprop->vValue) = VT_I4;
  814. V_I4(&pprop->vValue) = DEFAULT_DBPROP_INIT_MODE;
  815. pprop = (DBPROP *) m_dbProperties.GetProperty (
  816. DBPROPSET_DBINIT,
  817. DBPROP_INIT_BINDFLAGS );
  818. ADsAssert ( pprop );
  819. VariantClear ( &pprop->vValue );
  820. V_VT(&pprop->vValue) = VT_I4;
  821. V_I4(&pprop->vValue) = 0;
  822. pprop = (DBPROP *) m_dbProperties.GetProperty (
  823. DBPROPSET_DBINIT,
  824. DBPROP_INIT_LOCKOWNER );
  825. ADsAssert ( pprop );
  826. VariantClear ( &pprop->vValue );
  827. V_VT(&pprop->vValue) = VT_BSTR;
  828. V_BSTR(&pprop->vValue) = NULL;
  829. pprop = (DBPROP *) m_dbProperties.GetProperty (
  830. DBPROPSET_DBINIT,
  831. DBPROP_AUTH_USERID );
  832. ADsAssert ( pprop );
  833. VariantClear ( &pprop->vValue );
  834. V_VT(&pprop->vValue) = VT_BSTR;
  835. V_BSTR(&pprop->vValue) = NULL;
  836. m_pSession->SetUserName(NULL);
  837. pprop = (DBPROP *) m_dbProperties.GetProperty (
  838. DBPROPSET_DBINIT,
  839. DBPROP_AUTH_PASSWORD );
  840. ADsAssert ( pprop );
  841. VariantClear ( &pprop->vValue );
  842. V_VT(&pprop->vValue) = VT_BSTR;
  843. V_BSTR(&pprop->vValue) = NULL;
  844. m_pSession->SetPassword(NULL);
  845. pprop = (DBPROP *) m_dbProperties.GetProperty (
  846. DBPROPSET_DBINIT,
  847. DBPROP_AUTH_ENCRYPT_PASSWORD );
  848. ADsAssert ( pprop );
  849. VariantClear ( &pprop->vValue );
  850. V_VT(&pprop->vValue) = VT_BOOL;
  851. V_BOOL(&pprop->vValue) = VARIANT_FALSE;
  852. m_pSession->SetAuthFlag(0);
  853. CATCHBLOCKRETURN
  854. RRETURN(hr);
  855. }
  856. //Helper functions
  857. //+---------------------------------------------------------------------------
  858. //
  859. // Function: CBinder::InitializeProperties
  860. //
  861. // Synopsis: Initializes binder init property group to default values.
  862. //
  863. //----------------------------------------------------------------------------
  864. HRESULT CBinder::InitializeProperties()
  865. {
  866. HRESULT hr;
  867. DBPROP prop;
  868. DBPROPINFO * ppropinfo;
  869. // Initialize the DBPROP structure:
  870. //
  871. ZeroMemory ( &prop, sizeof (prop) );
  872. prop.dwOptions = DBPROPOPTIONS_OPTIONAL;
  873. prop.dwStatus = DBPROPSTATUS_OK;
  874. // Add the LCID:
  875. //
  876. prop.dwPropertyID = DBPROP_INIT_LCID;
  877. V_VT(&prop.vValue) = VT_I4;
  878. V_I4(&prop.vValue) = GetUserDefaultLCID ();
  879. hr = m_dbProperties.SetProperty (
  880. DBPROPSET_DBINIT,
  881. prop,
  882. TRUE,
  883. DESC_DBPROP_INIT_LCID
  884. );
  885. BAIL_ON_FAILURE(hr);
  886. // Make it writable:
  887. ppropinfo = (DBPROPINFO *)m_dbProperties.GetPropertyInfo(
  888. DBPROPSET_DBINIT,
  889. DBPROP_INIT_LCID);
  890. ADsAssert ( ppropinfo );
  891. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  892. // Add the DB_MODE:
  893. //
  894. prop.dwPropertyID = DBPROP_INIT_MODE;
  895. V_VT(&prop.vValue) = VT_I4;
  896. V_I4(&prop.vValue) = DEFAULT_DBPROP_INIT_MODE;
  897. hr = m_dbProperties.SetProperty (
  898. DBPROPSET_DBINIT,
  899. prop,
  900. TRUE,
  901. DESC_DBPROP_INIT_MODE
  902. );
  903. BAIL_ON_FAILURE(hr);
  904. // Make it writable:
  905. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  906. DBPROPSET_DBINIT,
  907. DBPROP_INIT_MODE );
  908. ADsAssert ( ppropinfo );
  909. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  910. // Add the BindFlags property:
  911. //
  912. prop.dwPropertyID = DBPROP_INIT_BINDFLAGS;
  913. V_VT(&prop.vValue) = VT_I4;
  914. V_I4(&prop.vValue) = 0;
  915. hr = m_dbProperties.SetProperty (
  916. DBPROPSET_DBINIT,
  917. prop,
  918. TRUE,
  919. DESC_DBPROP_INIT_BINDFLAGS
  920. );
  921. BAIL_ON_FAILURE(hr);
  922. // Make it writable:
  923. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  924. DBPROPSET_DBINIT,
  925. DBPROP_INIT_BINDFLAGS );
  926. ADsAssert ( ppropinfo );
  927. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  928. // Add the LOCKOWNER property:
  929. //
  930. prop.dwPropertyID = DBPROP_INIT_LOCKOWNER;
  931. V_VT(&prop.vValue) = VT_BSTR;
  932. V_BSTR(&prop.vValue) = NULL;
  933. hr = m_dbProperties.SetProperty (
  934. DBPROPSET_DBINIT,
  935. prop,
  936. TRUE,
  937. DESC_DBPROP_INIT_LOCKOWNER
  938. );
  939. BAIL_ON_FAILURE(hr);
  940. // Make it writable:
  941. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  942. DBPROPSET_DBINIT,
  943. DBPROP_INIT_LOCKOWNER );
  944. ADsAssert ( ppropinfo );
  945. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  946. // Add the USERID property:
  947. //
  948. prop.dwPropertyID = DBPROP_AUTH_USERID;
  949. V_VT(&prop.vValue) = VT_BSTR;
  950. V_BSTR(&prop.vValue) = NULL;
  951. hr = m_dbProperties.SetProperty (
  952. DBPROPSET_DBINIT,
  953. prop,
  954. TRUE,
  955. DESC_DBPROP_USERID
  956. );
  957. BAIL_ON_FAILURE(hr);
  958. // Make it writable:
  959. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  960. DBPROPSET_DBINIT,
  961. DBPROP_AUTH_USERID );
  962. ADsAssert ( ppropinfo );
  963. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  964. // Add the PASSWORD property:
  965. //
  966. prop.dwPropertyID = DBPROP_AUTH_PASSWORD;
  967. V_VT(&prop.vValue) = VT_BSTR;
  968. V_BSTR(&prop.vValue) = NULL;
  969. hr = m_dbProperties.SetProperty (
  970. DBPROPSET_DBINIT,
  971. prop,
  972. TRUE,
  973. DESC_DBPROP_PASSWORD
  974. );
  975. BAIL_ON_FAILURE(hr);
  976. // Make it writable:
  977. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  978. DBPROPSET_DBINIT,
  979. DBPROP_AUTH_PASSWORD );
  980. ADsAssert ( ppropinfo );
  981. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  982. // Add the ENCRYPT_PASSWORD property:
  983. //
  984. prop.dwPropertyID = DBPROP_AUTH_ENCRYPT_PASSWORD;
  985. V_VT(&prop.vValue) = VT_BOOL;
  986. V_BOOL(&prop.vValue) = VARIANT_FALSE;
  987. hr = m_dbProperties.SetProperty (
  988. DBPROPSET_DBINIT,
  989. prop,
  990. TRUE,
  991. DESC_DBPROP_ENCRYPT_PASSWORD
  992. );
  993. BAIL_ON_FAILURE(hr);
  994. // Make it writable:
  995. ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo (
  996. DBPROPSET_DBINIT,
  997. DBPROP_AUTH_ENCRYPT_PASSWORD );
  998. ADsAssert ( ppropinfo );
  999. ppropinfo->dwFlags |= DBPROPFLAGS_WRITE;
  1000. error:
  1001. RRETURN ( hr );
  1002. }
  1003. //+---------------------------------------------------------------------------
  1004. //
  1005. // Function: CBinder::BindFlagsFromDbProps
  1006. //
  1007. // Synopsis: extracts bind flags from initialization properties.
  1008. //
  1009. //----------------------------------------------------------------------------
  1010. DWORD CBinder::BindFlagsFromDbProps ( )
  1011. {
  1012. const DBPROP * ppropMode;
  1013. const DBPROP * ppropBindFlags;
  1014. ppropMode = m_dbProperties.GetProperty (
  1015. DBPROPSET_DBINIT,
  1016. DBPROP_INIT_MODE );
  1017. ADsAssert ( ppropMode );
  1018. ppropBindFlags = m_dbProperties.GetProperty (
  1019. DBPROPSET_DBINIT,
  1020. DBPROP_INIT_BINDFLAGS );
  1021. ADsAssert ( ppropBindFlags );
  1022. const VARIANT * pvarMode = &ppropMode->vValue;
  1023. const VARIANT * pvarBindFlags = &ppropBindFlags->vValue;
  1024. DWORD dwResult = 0;
  1025. if ( V_VT(pvarMode) == VT_I4 ) {
  1026. DWORD dwModeMask =
  1027. DB_MODE_READ |
  1028. DB_MODE_WRITE |
  1029. DB_MODE_READWRITE |
  1030. DB_MODE_SHARE_DENY_READ |
  1031. DB_MODE_SHARE_DENY_WRITE |
  1032. DB_MODE_SHARE_EXCLUSIVE |
  1033. DB_MODE_SHARE_DENY_NONE;
  1034. dwResult |= V_I4(pvarMode) & dwModeMask;
  1035. }
  1036. if ( V_VT(pvarBindFlags) == VT_I4 ) {
  1037. DWORD dwBindFlagProp = V_I4(pvarBindFlags);
  1038. DWORD dwBindFlags = 0;
  1039. if ( dwBindFlagProp & DB_BINDFLAGS_DELAYFETCHCOLUMNS ) {
  1040. dwBindFlags |= DBBINDURLFLAG_DELAYFETCHCOLUMNS;
  1041. }
  1042. if ( dwBindFlagProp & DB_BINDFLAGS_DELAYFETCHSTREAM ) {
  1043. dwBindFlags |= DBBINDURLFLAG_DELAYFETCHSTREAM;
  1044. }
  1045. if ( dwBindFlagProp & DB_BINDFLAGS_RECURSIVE ) {
  1046. dwBindFlags |= DBBINDURLFLAG_RECURSIVE;
  1047. }
  1048. if ( dwBindFlagProp & DB_BINDFLAGS_OUTPUT ) {
  1049. dwBindFlags |= DBBINDURLFLAG_OUTPUT;
  1050. }
  1051. dwResult |= V_I4(pvarBindFlags) | dwBindFlags;
  1052. }
  1053. RRETURN (dwResult);
  1054. }
  1055. //+---------------------------------------------------------------------------
  1056. //
  1057. // Function: CBinder::CreateDataSource
  1058. //
  1059. // Synopsis: Creates an implicit DataSource object for this binder object.
  1060. //
  1061. //----------------------------------------------------------------------------
  1062. HRESULT CBinder::CreateDataSource()
  1063. {
  1064. //Call this function only at creation time.
  1065. ADsAssert(m_pDataSource == NULL && m_pDBInitialize.get() == NULL);
  1066. HRESULT hr = S_OK;
  1067. //Create a DataSource object. Note: starts with refcount = 1.
  1068. m_pDataSource = new CDSOObject( NULL );
  1069. if (m_pDataSource == NULL)
  1070. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1071. //Initialize the object
  1072. if (!m_pDataSource->FInit())
  1073. {
  1074. delete m_pDataSource;
  1075. m_pDataSource = NULL;
  1076. BAIL_ON_FAILURE(hr = E_FAIL);
  1077. }
  1078. //Get IDBInitialize interface and store it in (auto)member variable.
  1079. //This will also make sure the DataSource object stays alive during
  1080. //the lifetime of binder object.
  1081. hr = m_pDataSource->QueryInterface(__uuidof(IDBInitialize),
  1082. (void**)&m_pDBInitialize);
  1083. BAIL_ON_FAILURE(hr);
  1084. //We already stored datasource object reference in auto_rel object,
  1085. //Now release once, since datasource object is created with refcount = 1.
  1086. m_pDataSource->Release();
  1087. error:
  1088. RRETURN ( hr );
  1089. }
  1090. //+---------------------------------------------------------------------------
  1091. //
  1092. // Function: CBinder::CreateSession
  1093. //
  1094. // Synopsis: Creates an implicit Session object for this binder object.
  1095. //
  1096. //----------------------------------------------------------------------------
  1097. HRESULT CBinder::CreateSession()
  1098. {
  1099. //Call this function only at creation time.
  1100. ADsAssert(m_pSession == NULL && m_pOpenRowset.get() == NULL);
  1101. HRESULT hr = S_OK;
  1102. CCredentials creds;
  1103. //create a session object. Note: starts with refcount = 1
  1104. m_pSession = new CSessionObject( NULL );
  1105. if (m_pSession == NULL)
  1106. BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
  1107. //Initialize session object passing null credentials.
  1108. //Note: This increments refcount on DataSource object.
  1109. if (!m_pSession->FInit(m_pDataSource, creds))
  1110. BAIL_ON_FAILURE(hr = E_FAIL);
  1111. hr = m_pSession->QueryInterface(__uuidof(IOpenRowset),
  1112. (void **)&m_pOpenRowset);
  1113. BAIL_ON_FAILURE(hr);
  1114. //We already stored session reference in auto_rel object.
  1115. //Now release once, since session object is created
  1116. //with refcount = 1
  1117. m_pSession->Release();
  1118. RRETURN ( S_OK );
  1119. error:
  1120. //if we're here, the Session object is no good.
  1121. if (m_pSession)
  1122. {
  1123. delete m_pSession;
  1124. m_pSession = NULL;
  1125. }
  1126. RRETURN ( hr );
  1127. }
  1128. #endif