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.

2165 lines
59 KiB

  1. // adsqryDoc.cpp : implementation of the CAdsqryDoc class
  2. //
  3. #include "stdafx.h"
  4. #include "adsqDoc.h"
  5. #include "adsdsrc.h"
  6. #include "oledberr.h"
  7. #include "adsdb.h"
  8. #include "csyntax.h"
  9. #include "newquery.h"
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. #ifdef BUILD_FOR_NT40
  16. typedef DWORD DWORD_PTR;
  17. #endif
  18. /***********************************************************
  19. Function:
  20. Arguments:
  21. Return:
  22. Purpose:
  23. Author(s):
  24. Revision:
  25. Date:
  26. ***********************************************************/
  27. CADsDataSource::CADsDataSource( )
  28. {
  29. m_pSearchPref = NULL;
  30. }
  31. /***********************************************************
  32. Function:
  33. Arguments:
  34. Return:
  35. Purpose:
  36. Author(s):
  37. Revision:
  38. Date:
  39. ***********************************************************/
  40. CADsDataSource::~CADsDataSource( )
  41. {
  42. if( NULL != m_pSearchPref )
  43. {
  44. FreeADsMem( m_pSearchPref );
  45. }
  46. }
  47. /***********************************************************
  48. Function: CADsDataSource::SetQueryParameters
  49. Arguments:
  50. Return:
  51. Purpose:
  52. Author(s):
  53. Revision:
  54. Date:
  55. ***********************************************************/
  56. /*void CADsDataSource::SetQueryParameters( CString& strSource,
  57. CString& strQuery,
  58. CString& strAttributes,
  59. CString& strScope,
  60. CString& strUserName,
  61. CString& strPassword,
  62. BOOL bEncryptPassword,
  63. BOOL bUseSQL )
  64. {
  65. m_strSource = strSource;
  66. m_strQuery = strQuery;
  67. m_strAttributes = strAttributes;
  68. m_strScope = strScope;
  69. m_strUserName = strUserName;
  70. m_strPassword = strPassword;
  71. m_bEncryptPassword = bEncryptPassword;
  72. m_bUseSQL = bUseSQL;
  73. } */
  74. void CADsDataSource::SetQueryParameters( SEARCHPREF* pSearchPref )
  75. {
  76. if( NULL == m_pSearchPref )
  77. {
  78. m_pSearchPref = (SEARCHPREF*) AllocADsMem( sizeof(SEARCHPREF) );
  79. }
  80. *m_pSearchPref = *pSearchPref;
  81. }
  82. /***********************************************************
  83. Function: CADsDataSource::GetColumnsCount
  84. Arguments:
  85. Return:
  86. Purpose:
  87. Author(s):
  88. Revision:
  89. Date:
  90. ***********************************************************/
  91. int CADsDataSource::GetColumnsCount( int nRow )
  92. {
  93. ASSERT( FALSE );
  94. return 0;
  95. }
  96. /***********************************************************
  97. Function: CADsDataSource::GetColumnsCount
  98. Arguments:
  99. Return:
  100. Purpose:
  101. Author(s):
  102. Revision:
  103. Date:
  104. ***********************************************************/
  105. BOOL CADsDataSource::GetValue( int nRow, int nColumn, CString& )
  106. {
  107. return FALSE;
  108. }
  109. /***********************************************************
  110. Function: CADsDataSource::GetColumnsCount
  111. Arguments:
  112. Return:
  113. Purpose:
  114. Author(s):
  115. Revision:
  116. Date:
  117. ***********************************************************/
  118. BOOL CADsDataSource::GetValue( int nRow, CString& strColumn, CString& )
  119. {
  120. return FALSE;
  121. }
  122. /***********************************************************
  123. Function: CADsDataSource::GetColumnsCount
  124. Arguments:
  125. Return:
  126. Purpose:
  127. Author(s):
  128. Revision:
  129. Date:
  130. ***********************************************************/
  131. BOOL CADsDataSource::GetADsPath( int nRow, CString& )
  132. {
  133. ASSERT( FALSE );
  134. return FALSE;
  135. }
  136. /***********************************************************
  137. Function: CADsDataSource::GetColumnsCount
  138. Arguments:
  139. Return:
  140. Purpose:
  141. Author(s):
  142. Revision:
  143. Date:
  144. ***********************************************************/
  145. BOOL CADsDataSource::GetColumnText( int nRow, int nColumn, CString& )
  146. {
  147. ASSERT( FALSE );
  148. return FALSE;
  149. }
  150. /***********************************************************
  151. Function: CADsDataSource::GetColumnsCount
  152. Arguments:
  153. Return:
  154. Purpose:
  155. Author(s):
  156. Revision:
  157. Date:
  158. ***********************************************************/
  159. BOOL CADsDataSource::Refresh( void )
  160. {
  161. return FALSE;
  162. }
  163. /***********************************************************
  164. Function: CADsDataSource::GetColumnsCount
  165. Arguments:
  166. Return:
  167. Purpose:
  168. Author(s):
  169. Revision:
  170. Date:
  171. ***********************************************************/
  172. BOOL CADsDataSource::RunTheQuery( void )
  173. {
  174. ASSERT( FALSE );
  175. return FALSE;
  176. }
  177. /*****************************************************************************
  178. Function: CADsOleDBDataSource::CADsOleDBDataSource
  179. Arguments:
  180. Return:
  181. Purpose:
  182. Author(s):
  183. Revision:
  184. Date:
  185. ***********************************************************/
  186. CADsOleDBDataSource::CADsOleDBDataSource( )
  187. {
  188. CoGetMalloc(MEMCTX_TASK, &m_pIMalloc);
  189. m_pData = NULL;
  190. m_pBindStatus = NULL;
  191. m_hRows = NULL;
  192. m_pIRowset = NULL;
  193. m_pIColsInfo = NULL;
  194. m_pAccessor = NULL;
  195. m_nColumnsCount = 0;
  196. m_prgColInfo = NULL;
  197. m_szColNames = NULL;
  198. }
  199. /*****************************************************************************
  200. Function: CADsOleDBDataSource::~CADsOleDBDataSource
  201. Arguments:
  202. Return:
  203. Purpose:
  204. Author(s):
  205. Revision:
  206. Date:
  207. ***********************************************************/
  208. CADsOleDBDataSource::~CADsOleDBDataSource( )
  209. {
  210. DestroyInternalData( );
  211. m_pIMalloc->Release( );
  212. }
  213. /*****************************************************************************
  214. Function: CADsOleDBDataSource::GetColumnsCount
  215. Arguments:
  216. Return:
  217. Purpose:
  218. Author(s):
  219. Revision:
  220. Date:
  221. ***********************************************************/
  222. int CADsOleDBDataSource::GetColumnsCount( int nRow )
  223. {
  224. if( m_nColumnsCount )
  225. {
  226. return (int)(m_nColumnsCount - m_nAddOne);
  227. }
  228. else
  229. {
  230. return 0;
  231. }
  232. }
  233. /*****************************************************************************
  234. Function: CADsOleDBDataSource::GetColumnText
  235. Arguments:
  236. Return:
  237. Purpose:
  238. Author(s):
  239. Revision:
  240. Date:
  241. ***********************************************************/
  242. BOOL CADsOleDBDataSource::GetColumnText( int nRow, int nColumn, CString& rValue )
  243. {
  244. nColumn += m_nAddOne;
  245. if( nColumn < 0 || nColumn >= (int)m_nColumnsCount )
  246. {
  247. ASSERT( FALSE );
  248. return FALSE;
  249. }
  250. if( FALSE )
  251. {
  252. rValue = _T("ADsPath");
  253. }
  254. else
  255. {
  256. TCHAR szColumnName[ MAX_PATH ];
  257. Convert( szColumnName, m_prgColInfo[ nColumn + 1].pwszName );
  258. rValue = szColumnName;
  259. }
  260. return TRUE;
  261. }
  262. /*****************************************************************************
  263. Function: CADsOleDBDataSource::CreateAccessorHelper
  264. Arguments:
  265. Return:
  266. Purpose:
  267. Author(s):
  268. Revision:
  269. Date:
  270. *****************************************************************************/
  271. BOOL CADsOleDBDataSource::CreateAccessorHelp( void )
  272. {
  273. DBBINDING* prgBindings = NULL;
  274. HRESULT hResult;
  275. ULONG i;
  276. IAccessor* pIAccessor = NULL;
  277. prgBindings = (DBBINDING *) LocalAlloc(
  278. LPTR,
  279. sizeof(DBBINDING) * (m_nColumnsCount)
  280. );
  281. if(NULL == prgBindings)
  282. return E_OUTOFMEMORY;
  283. //
  284. // Set up rest of the attributes
  285. //
  286. for ( i=0; i < m_nColumnsCount ; i++)
  287. {
  288. prgBindings[i].iOrdinal = i+1;
  289. prgBindings[i].obValue = sizeof(Data)*i + offsetof(Data, obValue);
  290. prgBindings[i].obLength = sizeof(Data)*i + offsetof(Data, obLength);
  291. prgBindings[i].obStatus = sizeof(Data)*i + offsetof(Data, status);
  292. prgBindings[i].dwPart = DBPART_VALUE|DBPART_LENGTH|DBPART_STATUS;
  293. //prgBindings[i].dwMemOwner = DBMEMOWNER_PROVIDEROWNED;
  294. prgBindings[i].wType = m_prgColInfo[i+1].wType;
  295. prgBindings[i].dwFlags = 0;
  296. if( prgBindings[i].wType & DBTYPE_BYREF )
  297. {
  298. prgBindings[i].dwMemOwner = DBMEMOWNER_PROVIDEROWNED;
  299. }
  300. else
  301. {
  302. prgBindings[i].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
  303. }
  304. if( m_prgColInfo[i+1].wType == DBTYPE_DATE ||
  305. m_prgColInfo[i+1].wType == DBTYPE_I8 )
  306. {
  307. prgBindings[i].obValue = sizeof(Data)*i + offsetof(Data, obValue2);
  308. }
  309. }
  310. hResult= m_pIRowset->QueryInterface( IID_IAccessor, (void**) &pIAccessor );
  311. ASSERT( SUCCEEDED( hResult ) );
  312. //
  313. // With the bindings create the accessor
  314. //
  315. hResult = pIAccessor->CreateAccessor(
  316. DBACCESSOR_ROWDATA,
  317. m_nColumnsCount,
  318. prgBindings,
  319. 0,
  320. &m_hAccessor,
  321. m_pBindStatus
  322. );
  323. ASSERT( SUCCEEDED( hResult ) );
  324. if( FAILED( hResult ) )
  325. {
  326. AfxMessageBox( _T("IAccessor::CreateAccessor failed") );
  327. }
  328. pIAccessor->Release();
  329. LocalFree(prgBindings);
  330. return( SUCCEEDED( hResult ) );
  331. }
  332. /*****************************************************************************
  333. Function: CADsOleDBDataSource::SetQueryCredentials
  334. Arguments:
  335. Return:
  336. Purpose:
  337. Author(s):
  338. Revision:
  339. Date:
  340. *****************************************************************************/
  341. HRESULT CADsOleDBDataSource::SetQueryCredentials( IDBInitialize* pInit,
  342. ICommandText* pCommand )
  343. {
  344. DBPROPSET aPropSet;
  345. DBPROP arrProp[ 20 ];
  346. HRESULT hResult;
  347. int nIter, nIdx;
  348. ASSERT( !( (NULL != pInit) && (NULL != pCommand) ) );
  349. for ( nIter = 0; nIter < 20; nIter++)
  350. {
  351. VariantInit( &(arrProp[ nIter ].vValue ) );
  352. V_VT( &(arrProp[ nIter ].vValue ) ) = VT_BSTR;
  353. arrProp[ nIter ].dwOptions = DBPROPOPTIONS_REQUIRED;
  354. }
  355. if( NULL != pInit )
  356. {
  357. IDBProperties* pIProp = NULL;
  358. if( !_tcslen(m_pSearchPref->szUserName) )
  359. {
  360. return S_OK;
  361. }
  362. hResult = pInit->QueryInterface( IID_IDBProperties, (void**)&pIProp );
  363. ASSERT( SUCCEEDED( hResult ) );
  364. if( FAILED( hResult ) )
  365. return hResult;
  366. nIter = 0;
  367. if( _tcslen(m_pSearchPref->szUserName) )
  368. {
  369. arrProp[ nIter ].dwPropertyID = DBPROP_AUTH_USERID;
  370. V_BSTR( &(arrProp[ nIter ].vValue) ) = AllocBSTR( m_pSearchPref->szUserName );
  371. nIter++;
  372. arrProp[ nIter ].dwPropertyID = DBPROP_AUTH_PASSWORD;
  373. V_BSTR( &(arrProp[ nIter ].vValue) ) = AllocBSTR( m_pSearchPref->szPassword );
  374. nIter++;
  375. arrProp[ nIter ].dwPropertyID = DBPROP_AUTH_ENCRYPT_PASSWORD;
  376. V_VT( &(arrProp[ nIter ].vValue ) ) = VT_BOOL;
  377. if( m_pSearchPref->bEncryptPassword )
  378. {
  379. V_BOOL( &(arrProp[ nIter ].vValue) ) = VARIANT_TRUE;
  380. }
  381. else
  382. {
  383. V_BOOL( &(arrProp[ nIter ].vValue) ) = VARIANT_FALSE;
  384. }
  385. nIter++;
  386. aPropSet.rgProperties = arrProp;
  387. aPropSet.cProperties = nIter;
  388. aPropSet.guidPropertySet = DBPROPSET_DBINIT;
  389. hResult = pIProp->SetProperties( 1, &aPropSet );
  390. ASSERT( S_OK == hResult );
  391. for ( nIdx = 0; nIdx < nIter ; nIdx++ )
  392. {
  393. VariantClear( &(arrProp[ nIdx ].vValue ) );
  394. }
  395. nIter = 0;
  396. }
  397. pIProp->Release( );
  398. }
  399. if( NULL != pCommand )
  400. {
  401. ICommandProperties* pCommandProp = NULL;
  402. hResult = pCommand->QueryInterface( IID_ICommandProperties,
  403. (void**) &pCommandProp );
  404. ASSERT( SUCCEEDED( hResult ) );
  405. if( FAILED( hResult ) )
  406. return hResult;
  407. nIter = 0;
  408. // Initialize the VARIANTs and the options in rgProps.
  409. //***************************************************************************
  410. if( -1 != m_pSearchPref->nAsynchronous )
  411. {
  412. arrProp[ nIter ].dwPropertyID = ADSIPROP_ASYNCHRONOUS;
  413. V_VT( &(arrProp[ nIter ].vValue ) ) = VT_BOOL;
  414. if( m_pSearchPref->nAsynchronous )
  415. {
  416. V_BOOL( &(arrProp[ nIter ].vValue) ) = VARIANT_TRUE;
  417. }
  418. else
  419. {
  420. V_BOOL( &(arrProp[ nIter ].vValue) ) = VARIANT_FALSE;
  421. }
  422. nIter++;
  423. }
  424. //***************************************************************************
  425. if( -1 != m_pSearchPref->nAttributesOnly )
  426. {
  427. arrProp[ nIter ].dwPropertyID = ADSIPROP_ATTRIBTYPES_ONLY;
  428. V_VT( &(arrProp[ nIter ].vValue ) ) = VT_BOOL;
  429. if( m_pSearchPref->nAttributesOnly )
  430. {
  431. V_BOOL( &(arrProp[ nIter ].vValue) ) = VARIANT_TRUE;
  432. }
  433. else
  434. {
  435. V_BOOL( &(arrProp[ nIter ].vValue) ) = VARIANT_FALSE;
  436. }
  437. nIter++;
  438. }
  439. //***************************************************************************
  440. if( -1 != m_pSearchPref->nTimeOut )
  441. {
  442. arrProp[ nIter ].dwPropertyID = ADSIPROP_TIMEOUT;
  443. V_VT( &(arrProp[ nIter ].vValue ) ) = VT_I4;
  444. V_I4( &(arrProp[ nIter ].vValue ) ) = m_pSearchPref->nTimeOut;
  445. nIter++;
  446. }
  447. //***************************************************************************
  448. if( -1 != m_pSearchPref->nTimeLimit )
  449. {
  450. arrProp[ nIter ].dwPropertyID = ADSIPROP_TIME_LIMIT;
  451. V_VT( &(arrProp[ nIter ].vValue ) ) = VT_I4;
  452. V_I4( &(arrProp[ nIter ].vValue ) ) = m_pSearchPref->nTimeLimit;
  453. nIter++;
  454. }
  455. //***************************************************************************
  456. if( -1 != m_pSearchPref->nSizeLimit )
  457. {
  458. arrProp[ nIter ].dwPropertyID = ADSIPROP_SIZE_LIMIT;
  459. V_VT( &(arrProp[ nIter ].vValue ) ) = VT_I4;
  460. V_I4( &(arrProp[ nIter ].vValue ) ) = m_pSearchPref->nSizeLimit;
  461. nIter++;
  462. }
  463. //***************************************************************************
  464. if( -1 != m_pSearchPref->nPageSize )
  465. {
  466. arrProp[ nIter ].dwPropertyID = ADSIPROP_PAGESIZE;
  467. V_VT( &(arrProp[ nIter ].vValue ) ) = VT_I4;
  468. V_I4( &(arrProp[ nIter ].vValue ) ) = m_pSearchPref->nPageSize;
  469. nIter++;
  470. }
  471. //***************************************************************************
  472. if( _tcslen( m_pSearchPref->szScope ) )
  473. {
  474. arrProp[ nIter ].dwPropertyID = ADSIPROP_SEARCH_SCOPE;
  475. V_VT( &(arrProp[ nIter ].vValue ) ) = VT_I4;
  476. if( !_tcsicmp( m_pSearchPref->szScope, _T("subtree") ) )
  477. {
  478. V_I4( &(arrProp[ nIter ].vValue ) ) = ADS_SCOPE_SUBTREE;
  479. }
  480. else if( !_tcsicmp( m_pSearchPref->szScope, _T("onelevel") ) )
  481. {
  482. V_I4( &(arrProp[ nIter ].vValue ) ) = ADS_SCOPE_ONELEVEL;
  483. }
  484. else
  485. {
  486. V_I4( &(arrProp[ nIter ].vValue ) ) = ADS_SCOPE_BASE;
  487. }
  488. nIter++;
  489. }
  490. //***************************************************************************
  491. if( -1 != m_pSearchPref->nChaseReferrals )
  492. {
  493. arrProp[ nIter ].dwPropertyID = ADSIPROP_CHASE_REFERRALS;
  494. V_VT( &(arrProp[ nIter ].vValue ) ) = VT_I4;
  495. if( m_pSearchPref->nChaseReferrals )
  496. {
  497. V_I4( &(arrProp[ nIter ].vValue) ) = ADS_CHASE_REFERRALS_ALWAYS;
  498. }
  499. else
  500. {
  501. V_I4( &(arrProp[ nIter ].vValue) ) = ADS_CHASE_REFERRALS_NEVER;
  502. }
  503. nIter++;
  504. }
  505. // Create the initialization structure.
  506. if( nIter )
  507. {
  508. aPropSet.rgProperties = arrProp;
  509. aPropSet.cProperties = nIter;
  510. aPropSet.guidPropertySet = DBPROPSET_ADSISEARCH;
  511. hResult = pCommandProp->SetProperties( 1, &aPropSet );
  512. ASSERT( S_OK == hResult );
  513. for ( nIdx = 0; nIdx < nIter ; nIdx++ )
  514. {
  515. VariantClear( &(arrProp[ nIdx ].vValue ) );
  516. }
  517. ASSERT( SUCCEEDED( hResult ) );
  518. }
  519. pCommandProp->Release( );
  520. }
  521. return hResult;
  522. }
  523. /*****************************************************************************
  524. Function: CADsOleDBDataSource::RunTheQuery
  525. Arguments:
  526. Return:
  527. Purpose:
  528. Author(s):
  529. Revision:
  530. Date:
  531. *****************************************************************************/
  532. BOOL CADsOleDBDataSource::RunTheQuery( void )
  533. {
  534. HRESULT hResult;
  535. IDBInitialize * pIDBInit = NULL;
  536. IDBCreateSession * pIDBCS = NULL;
  537. IDBCreateCommand * pIDBCreateCommand= NULL;
  538. ICommandText * pICommandText = NULL;
  539. ICommand * pICommand = NULL;
  540. DBBINDSTATUS * pMyStatus = NULL;
  541. CString strCommandText;
  542. BSTR bstrCommandText;
  543. HCURSOR aCursor, oldCursor;
  544. aCursor = LoadCursor( NULL, IDC_WAIT );
  545. oldCursor = SetCursor( aCursor );
  546. m_nCurrentRow = -1;
  547. m_nFirstRow = -1;
  548. m_nLastRow = -1;
  549. m_bNoMoreData = FALSE;
  550. m_hRows = NULL;
  551. m_nAddOne = 0;
  552. m_strAttributes = m_pSearchPref->szAttributes;
  553. if( !_tcsicmp( m_pSearchPref->szAttributes, _T("*") ) )
  554. {
  555. CString strTemp = _T("ADsPath,");
  556. strTemp += m_pSearchPref->szAttributes;
  557. m_strAttributes = strTemp;
  558. m_nAddOne = 1;
  559. }
  560. if( !m_pSearchPref->bUseSQL )
  561. {
  562. strCommandText = m_pSearchPref->szSource;
  563. if( strCommandText[ 0 ] != _T('<') )
  564. {
  565. CString strTemp;
  566. strTemp = _T("<");
  567. strTemp = strTemp + strCommandText;
  568. strTemp = strTemp + _T(">");
  569. strCommandText = strTemp;
  570. }
  571. strCommandText += _T(';');
  572. strCommandText += m_pSearchPref->szQuery;
  573. strCommandText += _T(';');
  574. strCommandText += m_strAttributes;
  575. /*if( _tcslen( m_pSearchPref->szScope ) )
  576. {
  577. strCommandText += _T(';');
  578. strCommandText += m_pSearchPref->szScope;
  579. }*/
  580. }
  581. else
  582. {
  583. strCommandText = _T("SELECT ");
  584. strCommandText += m_strAttributes;
  585. strCommandText += _T(" FROM '");
  586. strCommandText += m_pSearchPref->szSource;
  587. strCommandText += _T("'");
  588. strCommandText += _T(" WHERE ");
  589. strCommandText += m_pSearchPref->szQuery;
  590. }
  591. bstrCommandText = AllocBSTR( strCommandText.GetBuffer( strCommandText.GetLength( ) + 1 ) );
  592. //
  593. // Instantiate a data source object for LDAP provider
  594. //
  595. while( TRUE )
  596. {
  597. hResult = CoCreateInstance( CLSID_ADsDSOObject,
  598. 0,
  599. CLSCTX_INPROC_SERVER,
  600. IID_IDBInitialize,
  601. (void **)&pIDBInit
  602. );
  603. ASSERT( SUCCEEDED( hResult ) );
  604. if(FAILED(hResult))
  605. {
  606. TRACE(_T("CoCreateInstance failed \n"));
  607. AfxMessageBox( _T("CoCreateInstance failed") );
  608. break;
  609. }
  610. //
  611. // Initialize the Data Source
  612. //
  613. hResult = SetQueryCredentials( pIDBInit, NULL );
  614. ASSERT( SUCCEEDED( hResult ) );
  615. hResult = pIDBInit->Initialize();
  616. ASSERT( SUCCEEDED( hResult ) );
  617. if(FAILED(hResult))
  618. {
  619. TRACE(_T("IDBIntialize::Initialize failed \n"));
  620. AfxMessageBox( _T("IDBIntialize::Initialize failed") );
  621. break;
  622. }
  623. hResult = pIDBInit->QueryInterface(
  624. IID_IDBCreateSession,
  625. (void**) &pIDBCS);
  626. ASSERT( SUCCEEDED( hResult ) );
  627. if(FAILED(hResult))
  628. {
  629. TRACE(_T("QueryInterface for IDBCreateSession failed \n"));
  630. AfxMessageBox( _T("QueryInterface for IDBCreateSession failed") );
  631. break;
  632. }
  633. pIDBInit->Release( );
  634. pIDBInit = NULL;
  635. //
  636. // Create a session returning a pointer to its CreateCommand interface
  637. //
  638. hResult = pIDBCS->CreateSession(
  639. NULL,
  640. IID_IDBCreateCommand,
  641. (LPUNKNOWN*) &pIDBCreateCommand
  642. );
  643. ASSERT( SUCCEEDED( hResult ) );
  644. if(FAILED(hResult))
  645. {
  646. TRACE( _T("IDBCreateSession::CreateSession failed \n") );
  647. AfxMessageBox( _T("IDBCreateSession::CreateSession failed") );
  648. break;
  649. }
  650. pIDBCS->Release( );
  651. pIDBCS = NULL;
  652. //
  653. // Create a command from the session object
  654. //
  655. hResult = pIDBCreateCommand->CreateCommand(
  656. NULL,
  657. IID_ICommandText,
  658. (LPUNKNOWN*) &pICommandText
  659. );
  660. ASSERT( SUCCEEDED( hResult ) );
  661. if(FAILED(hResult))
  662. {
  663. TRACE( _T(" IDBCreateCommand::CreateCommand failed\n") );
  664. AfxMessageBox( _T("IDBCreateCommand::CreateCommand failed") );
  665. break;
  666. }
  667. pIDBCreateCommand->Release( );
  668. pIDBCreateCommand = NULL;
  669. hResult = SetQueryCredentials( NULL, pICommandText );
  670. ASSERT( SUCCEEDED( hResult ) );
  671. if( !m_pSearchPref->bUseSQL )
  672. {
  673. hResult = pICommandText->SetCommandText(
  674. DBGUID_LDAPDialect,
  675. bstrCommandText
  676. );
  677. }
  678. else
  679. {
  680. hResult = pICommandText->SetCommandText(
  681. DBGUID_DBSQL,
  682. bstrCommandText
  683. );
  684. }
  685. ASSERT( SUCCEEDED( hResult ) );
  686. if(FAILED(hResult))
  687. {
  688. TRACE(_T("ICommandText::CommandText failed \n"));
  689. AfxMessageBox( _T("ICommandText::CommandText failed") );
  690. break;
  691. }
  692. hResult = pICommandText->QueryInterface(
  693. IID_ICommand,
  694. (void**) &pICommand);
  695. ASSERT( SUCCEEDED( hResult ) );
  696. if(FAILED(hResult))
  697. {
  698. TRACE(_T("QueryInterface for ICommand failed \n") );
  699. AfxMessageBox( _T("QueryInterface for ICommand failed ") );
  700. break;
  701. }
  702. pICommandText->Release();
  703. pICommandText = NULL;
  704. //
  705. // Do the Query and get back a rowset
  706. //
  707. pICommand->AddRef( );
  708. pICommand->Release( );
  709. hResult = pICommand->Execute(
  710. NULL,
  711. IID_IRowset,
  712. NULL,
  713. NULL,
  714. (LPUNKNOWN *)&m_pIRowset
  715. );
  716. ASSERT( SUCCEEDED( hResult ) );
  717. if(FAILED(hResult))
  718. {
  719. TRACE(_T("ICommand::Execute failed \n"));
  720. AfxMessageBox( _T("ICommand::Execute failed") );
  721. pICommand->Release( );
  722. pICommand = NULL;
  723. break;
  724. }
  725. m_pIRowset->AddRef( );
  726. m_pIRowset->Release( );
  727. pICommand->Release( );
  728. pICommand = NULL;
  729. hResult = m_pIRowset->QueryInterface(
  730. IID_IColumnsInfo,
  731. (void**) &m_pIColsInfo
  732. );
  733. ASSERT( SUCCEEDED( hResult ) );
  734. if(FAILED(hResult))
  735. {
  736. TRACE(_T("QueryInterface for IColumnsInfo failed \n"));
  737. AfxMessageBox( _T("QueryInterface for IColumnsInfo failed") );
  738. break;
  739. }
  740. hResult = m_pIColsInfo->GetColumnInfo(
  741. &m_nColumnsCount,
  742. &m_prgColInfo,
  743. &m_szColNames
  744. );
  745. ASSERT( SUCCEEDED( hResult ) );
  746. if(FAILED(hResult))
  747. {
  748. TRACE( _T("IColumnsInfo::GetColumnInfo failed \n") );
  749. AfxMessageBox( _T("IColumnsInfo::GetColumnInfo failed") );
  750. break;
  751. }
  752. //
  753. // The no. of attributes is one less than the no. of columns because of
  754. // the Bookmark column
  755. //
  756. m_nColumnsCount--;
  757. m_pData = (Data *) LocalAlloc( LPTR, sizeof(Data) * m_nColumnsCount );
  758. m_pBindStatus = (DBBINDSTATUS *) LocalAlloc(
  759. LPTR,
  760. sizeof(DBBINDSTATUS) * m_nColumnsCount
  761. );
  762. hResult = CreateAccessorHelp( );
  763. if(FAILED(hResult))
  764. {
  765. TRACE(_T("CreateAccessorHelper failed \n"));
  766. break;
  767. }
  768. break;
  769. }
  770. SysFreeString( bstrCommandText );
  771. SetCursor( oldCursor );
  772. return SUCCEEDED( hResult );
  773. }
  774. /*****************************************************************************
  775. Function: CADsOleDBDataSource::AdvanceCursor
  776. Arguments:
  777. Return:
  778. Purpose:
  779. Author(s):
  780. Revision:
  781. Date:
  782. *****************************************************************************/
  783. BOOL CADsOleDBDataSource::AdvanceCursor( void )
  784. {
  785. HRESULT hResult;
  786. DBCOUNTITEM cRowsObtained;
  787. HCURSOR aCursor, oldCursor;
  788. aCursor = LoadCursor( NULL, IDC_WAIT );
  789. oldCursor = SetCursor( aCursor );
  790. if( !m_bNoMoreData )
  791. {
  792. cRowsObtained = 0;
  793. if( m_hRows )
  794. {
  795. ULONG refCount[ ROWS ];
  796. DBROWSTATUS rowStat[ ROWS ];
  797. m_pIRowset->ReleaseRows( ROWS,
  798. m_hRows,
  799. NULL,
  800. refCount,
  801. rowStat );
  802. m_pIMalloc->Free( m_hRows );
  803. m_hRows = NULL;
  804. }
  805. TRACE( _T("Ask for %d rows starting from %d\n"), ROWS, m_nLastRow + 1 );
  806. hResult = m_pIRowset->GetNextRows(
  807. NULL,
  808. 0,
  809. ROWS,
  810. //1L,
  811. &cRowsObtained,
  812. &m_hRows
  813. );
  814. TRACE( _T("After asking for %d rows starting from %d\n"), ROWS, m_nLastRow + 1 );
  815. if( SUCCEEDED( hResult ) )
  816. {
  817. m_nFirstRow = m_nLastRow + 1;
  818. m_nLastRow = (int)(m_nFirstRow + cRowsObtained - 1);
  819. }
  820. m_bNoMoreData = (cRowsObtained != ROWS);
  821. }
  822. SetCursor( oldCursor );
  823. return TRUE;
  824. }
  825. /*****************************************************************************
  826. Function: CADsOleDBDataSource::GetADsPath
  827. Arguments:
  828. Return:
  829. Purpose:
  830. Author(s):
  831. Revision:
  832. Date:
  833. ***********************************************************/
  834. BOOL CADsOleDBDataSource::GetADsPath( int nRow, CString& rPath )
  835. {
  836. ASSERT( nRow < m_ADsPath.GetSize( ) );
  837. if( ! (nRow < m_ADsPath.GetSize( ) ) )
  838. {
  839. return FALSE;
  840. }
  841. rPath = m_ADsPath.GetAt( nRow );
  842. return TRUE;
  843. }
  844. /*****************************************************************************
  845. Function: CADsOleDBDataSource::GetValue
  846. Arguments:
  847. Return:
  848. Purpose:
  849. Author(s):
  850. Revision:
  851. Date:
  852. ***********************************************************/
  853. BOOL CADsOleDBDataSource::GetValue( int nRow, int nColumn, CString& rValue )
  854. {
  855. HRESULT hResult;
  856. nColumn += m_nAddOne;
  857. ASSERT( nRow >= 0 );
  858. if( nRow < 0 )
  859. {
  860. return FALSE;
  861. }
  862. ASSERT( nColumn >=0 && nColumn < (int)m_nColumnsCount );
  863. if( nColumn < 0 || nColumn >= (int)m_nColumnsCount )
  864. {
  865. return FALSE;
  866. }
  867. if( !BringRowInBuffer( nRow ) )
  868. return FALSE;
  869. if( m_nCurrentRow != nRow )
  870. {
  871. hResult = m_pIRowset->GetData( m_hRows[nRow - m_nFirstRow],
  872. m_hAccessor,
  873. (void*)m_pData );
  874. m_nCurrentRow = nRow;
  875. ReadADsPath( );
  876. }
  877. if( SUCCEEDED( hResult) )
  878. {
  879. rValue = ExtractData( nColumn );
  880. }
  881. else
  882. {
  883. rValue = _T("Error");
  884. }
  885. return TRUE;
  886. }
  887. /*****************************************************************************
  888. Function: CADsOleDBDataSource::ReadADsPath
  889. Arguments:
  890. Return:
  891. Purpose:
  892. Author(s):
  893. Revision:
  894. Date:
  895. ***********************************************************/
  896. void CADsOleDBDataSource::ReadADsPath( void )
  897. {
  898. CString strADsPath;
  899. strADsPath = ExtractData( 0 );
  900. m_ADsPath.Add( strADsPath );
  901. }
  902. /*****************************************************************************
  903. Function: CADsOleDBDataSource::ExtractData
  904. Arguments:
  905. Return:
  906. Purpose:
  907. Author(s):
  908. Revision:
  909. Date:
  910. ***********************************************************/
  911. CString CADsOleDBDataSource::ExtractData( int nColumn )
  912. {
  913. ULONG i;
  914. TCHAR szValue[ 2048 ] = _T("Error");
  915. HRESULT hResult;
  916. i = nColumn;
  917. if( m_pData[i].status == DBSTATUS_S_ISNULL )
  918. return CString(_T("<No value>") );
  919. if( !( m_prgColInfo[i+1].dwFlags & DBCOLUMNFLAGS_ISNULLABLE &&
  920. m_pData[i].status == DBSTATUS_S_ISNULL))
  921. {
  922. switch(m_prgColInfo[i+1].wType)
  923. {
  924. case DBTYPE_I8:
  925. LARGE_INTEGERToString( szValue, (LARGE_INTEGER*)&m_pData[i].obValue2 );
  926. break;
  927. case DBTYPE_I4:
  928. wsprintf( szValue, _T("%ld"), (DWORD_PTR) m_pData[i].obValue );
  929. break;
  930. case DBTYPE_BOOL:
  931. wsprintf( szValue, _T("%s"),
  932. (VARIANT_TRUE == (VARIANT_BOOL) m_pData[i].obValue) ? _T("TRUE") : _T("FALSE") );
  933. break;
  934. case DBTYPE_DATE:
  935. {
  936. VARIANT varTemp, varString;
  937. HRESULT hResult;
  938. VariantInit( &varString );
  939. VariantInit( &varTemp );
  940. V_VT( &varTemp ) = VT_DATE;
  941. V_DATE( &varTemp ) = (DATE) m_pData[i].obValue2;
  942. hResult= VariantChangeType( &varString, &varTemp, VARIANT_NOVALUEPROP, VT_BSTR );
  943. ASSERT( SUCCEEDED( hResult ) );
  944. if( SUCCEEDED( hResult ) )
  945. {
  946. Convert( szValue, V_BSTR( &varString ) );
  947. VariantClear( &varString );
  948. }
  949. break;
  950. }
  951. case DBTYPE_STR | DBTYPE_BYREF:
  952. if( NULL != (char *)m_pData[i].obValue )
  953. {
  954. wsprintf( szValue, _T("%s"), (char *)m_pData[i].obValue );
  955. }
  956. else
  957. {
  958. _tcscpy( szValue, _T("NULL") );
  959. }
  960. break;
  961. case DBTYPE_BYTES | DBTYPE_BYREF:
  962. {
  963. TCHAR szTemp[ 16 ];
  964. ULONG ulIter;
  965. BYTE* pByte;
  966. _ltot ( m_pData[i].obLength, szTemp, 10 );
  967. _tcscpy ( szValue, _T("[") );
  968. _tcscat ( szValue, szTemp );
  969. _tcscat ( szValue, _T("] ") );
  970. pByte = (BYTE*) (m_pData[i].obValue);
  971. for( ulIter = 0; ulIter < m_pData[i].obLength && _tcslen( szValue ) < 2000; ulIter++ )
  972. {
  973. BYTE bVal;
  974. bVal = pByte[ ulIter ];
  975. _itot( (int)bVal , szTemp, 16 );
  976. _tcscat ( szValue, _T("x") );
  977. _tcscat ( szValue, szTemp );
  978. _tcscat ( szValue, _T(" ") );
  979. }
  980. }
  981. break;
  982. case DBTYPE_WSTR | DBTYPE_BYREF:
  983. if( NULL != (WCHAR *)m_pData[i].obValue )
  984. {
  985. wsprintf( szValue, _T("%S"), (WCHAR *) m_pData[i].obValue );
  986. }
  987. else
  988. {
  989. _tcscpy( szValue, _T("NULL") );
  990. }
  991. break;
  992. case DBTYPE_VARIANT | DBTYPE_BYREF:
  993. {
  994. ULONG dwSLBound;
  995. ULONG dwSUBound, j;
  996. void HUGEP *pArray;
  997. VARIANT *pVariant;
  998. pArray = NULL;
  999. pVariant = (VARIANT*) m_pData[i].obValue;
  1000. if( NULL == pVariant )
  1001. _tcscpy( szValue, _T("ERROR!!! m_pData[i].obValue is NULL") );
  1002. while( TRUE && (NULL != pVariant) )
  1003. {
  1004. ASSERT( V_VT( pVariant ) & VT_ARRAY );
  1005. if( ! (V_VT( pVariant ) & VT_ARRAY ) )
  1006. break;
  1007. hResult = SafeArrayGetLBound( V_ARRAY(pVariant),
  1008. 1,
  1009. (long FAR *) &dwSLBound );
  1010. ASSERT( SUCCEEDED( hResult ) );
  1011. if( FAILED( hResult ) )
  1012. break;
  1013. hResult = SafeArrayGetUBound( V_ARRAY(pVariant),
  1014. 1,
  1015. (long FAR *) &dwSUBound );
  1016. ASSERT( SUCCEEDED( hResult ) );
  1017. if( FAILED( hResult ) )
  1018. break;
  1019. hResult = SafeArrayAccessData( V_ARRAY(pVariant),
  1020. &pArray );
  1021. ASSERT( SUCCEEDED( hResult ) );
  1022. if( FAILED( hResult ) )
  1023. break;
  1024. _tcscpy( szValue, _T("") );
  1025. for ( j = dwSLBound; j <= dwSUBound; j++ )
  1026. {
  1027. TCHAR szTemp[ 1024 ];
  1028. switch( pVariant->vt & ~VT_ARRAY )
  1029. {
  1030. case VT_BSTR:
  1031. Convert( szTemp, ( (BSTR *)pArray )[j] );
  1032. break;
  1033. case VT_I8:
  1034. LARGE_INTEGERToString( szTemp, &( (LARGE_INTEGER *)pArray )[j] );
  1035. break;
  1036. case VT_I4:
  1037. _ltot( ((DWORD *) pArray)[j], szTemp, 10 );
  1038. break;
  1039. case VT_BOOL:
  1040. _tcscpy( szTemp, (((VARIANT_BOOL *) pArray)[j]) == VARIANT_TRUE ?
  1041. _T("TRUE") : _T("FALSE") );
  1042. break;
  1043. case VT_VARIANT:
  1044. {
  1045. VARIANT* pVar;
  1046. pVar = ((VARIANT *)pArray) + j;
  1047. switch( V_VT( pVar ) )
  1048. {
  1049. case VT_BSTR:
  1050. Convert( szTemp, V_BSTR( pVar ) );
  1051. break;
  1052. case VT_I4:
  1053. _ltot( V_I4( pVar ), szTemp, 10 );
  1054. break;
  1055. case VT_BOOL:
  1056. _tcscpy( szTemp, V_BOOL( pVar ) == VARIANT_TRUE ?
  1057. _T("TRUE") : _T("FALSE") );
  1058. break;
  1059. default:
  1060. ASSERT( FALSE ) ;
  1061. _tcscpy( szTemp, _T("Unsupported") );
  1062. break;
  1063. }
  1064. break;
  1065. }
  1066. default:
  1067. _tcscpy( szTemp, _T("Unsupported") );
  1068. }
  1069. if( _tcslen( szValue) + _tcslen( szTemp ) < 2040 )
  1070. {
  1071. if( j != dwSLBound )
  1072. {
  1073. _tcscat( szValue, _T("# ") );
  1074. }
  1075. _tcscat( szValue, szTemp );
  1076. }
  1077. }
  1078. SafeArrayUnaccessData( V_ARRAY(pVariant) );
  1079. break;
  1080. }
  1081. break;
  1082. }
  1083. default:
  1084. wsprintf( szValue, _T("Don't know how to convert") );
  1085. break;
  1086. }
  1087. }
  1088. else
  1089. {
  1090. _tcscpy( szValue, _T("NA") );
  1091. }
  1092. return CString( szValue );
  1093. }
  1094. /*****************************************************************************
  1095. Function: CADsOleDBDataSource::BringRowInBuffer
  1096. Arguments:
  1097. Return:
  1098. Purpose:
  1099. Author(s):
  1100. Revision:
  1101. Date:
  1102. ***********************************************************/
  1103. BOOL CADsOleDBDataSource::BringRowInBuffer( int nRow )
  1104. {
  1105. if( nRow >= m_nFirstRow && nRow <= m_nLastRow )
  1106. return TRUE;
  1107. if( m_nLastRow == -1 )
  1108. AdvanceCursor( );
  1109. while( nRow > m_nLastRow && !m_bNoMoreData )
  1110. AdvanceCursor( );
  1111. if (nRow >= m_nFirstRow && nRow <= m_nLastRow)
  1112. {
  1113. return TRUE;
  1114. }
  1115. return FALSE;
  1116. }
  1117. /*****************************************************************************
  1118. Function: CADsOleDBDataSource::DestroyInternalData
  1119. Arguments:
  1120. Return:
  1121. Purpose:
  1122. Author(s):
  1123. Revision:
  1124. Date:
  1125. ***********************************************************/
  1126. void CADsOleDBDataSource::DestroyInternalData( void )
  1127. {
  1128. if( m_hRows )
  1129. {
  1130. m_pIMalloc->Free( m_hRows );
  1131. }
  1132. if( m_pBindStatus )
  1133. {
  1134. LocalFree( m_pBindStatus );
  1135. }
  1136. if( m_pData )
  1137. {
  1138. LocalFree( m_pData );
  1139. }
  1140. if( m_pIRowset )
  1141. {
  1142. m_pIRowset->Release( );
  1143. }
  1144. if( m_pIColsInfo )
  1145. {
  1146. m_pIColsInfo->Release( );
  1147. }
  1148. if( m_pAccessor )
  1149. {
  1150. m_pAccessor->Release( );
  1151. }
  1152. if( m_prgColInfo )
  1153. {
  1154. m_pIMalloc->Free( m_prgColInfo );
  1155. }
  1156. if( m_szColNames )
  1157. {
  1158. m_pIMalloc->Free( m_szColNames );
  1159. }
  1160. }
  1161. /*****************************************************************************
  1162. Function:
  1163. Arguments:
  1164. Return:
  1165. Purpose:
  1166. Author(s):
  1167. Revision:
  1168. Date:
  1169. *****************************************************************************/
  1170. CADsSearchDataSource::CADsSearchDataSource( )
  1171. {
  1172. m_pSearch = NULL;
  1173. m_nCurrentRow = -1;
  1174. m_hSearch = NULL;
  1175. }
  1176. /*****************************************************************************
  1177. Function:
  1178. Arguments:
  1179. Return:
  1180. Purpose:
  1181. Author(s):
  1182. Revision:
  1183. Date:
  1184. *****************************************************************************/
  1185. CADsSearchDataSource::~CADsSearchDataSource( )
  1186. {
  1187. if( m_pSearch )
  1188. {
  1189. m_pSearch->CloseSearchHandle( m_hSearch );
  1190. m_pSearch->Release( );
  1191. }
  1192. }
  1193. /*****************************************************************************
  1194. Function:
  1195. Arguments:
  1196. Return:
  1197. Purpose:
  1198. Author(s):
  1199. Revision:
  1200. Date:
  1201. *****************************************************************************/
  1202. int CADsSearchDataSource::GetColumnsCount( int nRow )
  1203. {
  1204. BOOL bOK;
  1205. bOK = BringRowInBuffer( nRow );
  1206. if( bOK )
  1207. {
  1208. return (int)m_strColumns.GetSize( );
  1209. }
  1210. else
  1211. {
  1212. return 0;
  1213. }
  1214. }
  1215. /*****************************************************************************
  1216. Function: CADsSearchDataSource::GetValue
  1217. Arguments:
  1218. Return:
  1219. Purpose:
  1220. Author(s):
  1221. Revision:
  1222. Date:
  1223. *****************************************************************************/
  1224. BOOL CADsSearchDataSource::GetValue( int nRow, int nColumn, CString& )
  1225. {
  1226. return FALSE;
  1227. }
  1228. /*****************************************************************************
  1229. Function: CADsSearchDataSource::GetValue
  1230. Arguments:
  1231. Return:
  1232. Purpose:
  1233. Author(s):
  1234. Revision:
  1235. Date:
  1236. *****************************************************************************/
  1237. BOOL CADsSearchDataSource::GetValue( int nRow, CString& strColumn, CString& rValue )
  1238. {
  1239. HRESULT hResult;
  1240. BSTR bstrColumnName;
  1241. ADS_SEARCH_COLUMN aSearchColumn;
  1242. ADS_ATTR_INFO aAttrDef;
  1243. BOOL bOK = TRUE;
  1244. COleDsSyntax* pSyntax;
  1245. rValue = _T("<No value>");
  1246. bOK = BringRowInBuffer( nRow );
  1247. if( bOK )
  1248. {
  1249. bstrColumnName = AllocBSTR( strColumn.GetBuffer( 256 ) );
  1250. hResult = m_pSearch->GetColumn( m_hSearch,
  1251. bstrColumnName,
  1252. &aSearchColumn );
  1253. if( SUCCEEDED( hResult ) )
  1254. {
  1255. aAttrDef.pszAttrName = aSearchColumn.pszAttrName;
  1256. aAttrDef.dwADsType = aSearchColumn.dwADsType;
  1257. aAttrDef.pADsValues = aSearchColumn.pADsValues;
  1258. aAttrDef.dwNumValues = aSearchColumn.dwNumValues;
  1259. pSyntax = NULL;
  1260. pSyntax = GetSyntaxHandler( aAttrDef.dwADsType, rValue );
  1261. if( pSyntax )
  1262. {
  1263. hResult = pSyntax->Native2Value( &aAttrDef, rValue );
  1264. delete pSyntax;
  1265. }
  1266. hResult = m_pSearch->FreeColumn( &aSearchColumn );
  1267. }
  1268. SysFreeString( bstrColumnName );
  1269. }
  1270. return bOK;
  1271. }
  1272. /*****************************************************************************
  1273. Function: CADsSearchDataSource::GetADsPath
  1274. Arguments:
  1275. Return:
  1276. Purpose:
  1277. Author(s):
  1278. Revision:
  1279. Date:
  1280. *****************************************************************************/
  1281. BOOL CADsSearchDataSource::GetADsPath( int nRow, CString& rPath )
  1282. {
  1283. ASSERT( nRow < m_ADsPath.GetSize( ) );
  1284. if( ! (nRow < m_ADsPath.GetSize( ) ) )
  1285. {
  1286. return FALSE;
  1287. }
  1288. rPath = m_ADsPath.GetAt( nRow );
  1289. return TRUE;
  1290. }
  1291. /*****************************************************************************
  1292. Function: CADsSearchDataSource::GetColumnText
  1293. Arguments:
  1294. Return:
  1295. Purpose:
  1296. Author(s):
  1297. Revision:
  1298. Date:
  1299. *****************************************************************************/
  1300. BOOL CADsSearchDataSource::GetColumnText( int nRow, int nColumn, CString& rColumn )
  1301. {
  1302. BOOL bOK = TRUE;
  1303. bOK = BringRowInBuffer( nRow );
  1304. if( bOK )
  1305. {
  1306. rColumn = m_strColumns[ nColumn ];
  1307. }
  1308. return bOK;
  1309. }
  1310. /*****************************************************************************
  1311. Function: CADsSearchDataSource::RunTheQuery
  1312. Arguments:
  1313. Return:
  1314. Purpose:
  1315. Author(s):
  1316. Revision:
  1317. Date:
  1318. *****************************************************************************/
  1319. BOOL CADsSearchDataSource::RunTheQuery( void )
  1320. {
  1321. HRESULT hResult;
  1322. HCURSOR aCursor, oldCursor;
  1323. aCursor = LoadCursor( NULL, IDC_WAIT );
  1324. oldCursor = SetCursor( aCursor );
  1325. while( TRUE )
  1326. {
  1327. hResult = CreateSearchInterface( );
  1328. if( FAILED( hResult ) )
  1329. break;
  1330. hResult = SetSearchPreferences( );
  1331. if( FAILED( hResult ) )
  1332. break;
  1333. hResult = SetAttributesName( );
  1334. break;
  1335. }
  1336. SetCursor( oldCursor );
  1337. m_bNoMoreData = FALSE;
  1338. return (S_OK == hResult);
  1339. }
  1340. /*****************************************************************************
  1341. Function: CADsSearchDataSource::SetAttributesName
  1342. Arguments:
  1343. Return:
  1344. Purpose:
  1345. Author(s):
  1346. Revision:
  1347. Date:
  1348. *****************************************************************************/
  1349. HRESULT CADsSearchDataSource::SetAttributesName( void )
  1350. {
  1351. HRESULT hResult = E_FAIL;
  1352. BSTR bstrSearchFilter;
  1353. DWORD dwNumAttributes = (DWORD)-1;
  1354. BSTR ppszAttributes[ 128 ];
  1355. int nIterator;
  1356. TCHAR szAttribute[ 128 ];
  1357. CString strAttr;
  1358. CString strAttributes;
  1359. bstrSearchFilter = AllocBSTR( m_pSearchPref->szQuery );
  1360. strAttributes = m_pSearchPref->szAttributes;
  1361. // first, we need to figure out how many attributes are requested
  1362. strAttributes.TrimLeft( );
  1363. strAttributes.TrimRight( );
  1364. if( strAttributes.CompareNoCase( _T("*") ) )
  1365. {
  1366. dwNumAttributes = 1;
  1367. _tcscpy( szAttribute, _T("") );
  1368. for( nIterator = 0; nIterator < strAttributes.GetLength( ) ; nIterator++ )
  1369. {
  1370. if( strAttributes[ nIterator ] == _T(',') )
  1371. {
  1372. strAttr = szAttribute;
  1373. strAttr.TrimLeft( );
  1374. strAttr.TrimRight( );
  1375. ppszAttributes[ dwNumAttributes - 1 ] = AllocBSTR( strAttr.GetBuffer( 128 ) );
  1376. dwNumAttributes++;
  1377. _tcscpy( szAttribute, _T("") );
  1378. }
  1379. else
  1380. {
  1381. TCHAR szChars[ 2 ];
  1382. szChars[ 1 ] = _T('\0');
  1383. szChars[ 0 ] = strAttributes[ nIterator ];
  1384. _tcscat( szAttribute, szChars );
  1385. if( nIterator == strAttributes.GetLength( ) - 1 )
  1386. {
  1387. strAttr = szAttribute;
  1388. strAttr.TrimLeft( );
  1389. strAttr.TrimRight( );
  1390. ppszAttributes[ dwNumAttributes - 1 ] = AllocBSTR( strAttr.GetBuffer( 128 ) );
  1391. }
  1392. }
  1393. }
  1394. }
  1395. hResult = m_pSearch->ExecuteSearch(
  1396. bstrSearchFilter,
  1397. ppszAttributes,
  1398. dwNumAttributes,
  1399. &m_hSearch
  1400. );
  1401. if( FAILED( hResult ) )
  1402. {
  1403. TRACE(_T("ExecuteSearch failed with %lx \n"), hResult);
  1404. AfxMessageBox( _T("ExecuteSearch failed") );
  1405. }
  1406. for( nIterator = 0; nIterator < (int)dwNumAttributes ; nIterator++ )
  1407. {
  1408. SysFreeString( ppszAttributes[ nIterator ] );
  1409. }
  1410. SysFreeString( bstrSearchFilter );
  1411. return hResult;
  1412. }
  1413. /*****************************************************************************
  1414. Function:
  1415. Arguments:
  1416. Return:
  1417. Purpose:
  1418. Author(s):
  1419. Revision:
  1420. Date:
  1421. *****************************************************************************/
  1422. /*HRESULT CADsSearchDataSource::SetSearchPreferences( )
  1423. {
  1424. CSearchPreferencesDlg aSearchPref;
  1425. ADS_SEARCHPREF_INFO arrSearchPref[ 20 ];
  1426. int nSearchPrefCount = 0;
  1427. HRESULT hResult;
  1428. if( aSearchPref.DoModal( ) != IDOK )
  1429. {
  1430. return E_FAIL;
  1431. }
  1432. //***************************************************************************
  1433. if( !aSearchPref.m_strAsynchronous.IsEmpty( ) )
  1434. {
  1435. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_ASYNCHRONOUS;
  1436. arrSearchPref[nSearchPrefCount].vValue.dwType= ADSTYPE_BOOLEAN;
  1437. if( !aSearchPref.m_strAsynchronous.CompareNoCase( _T("Yes") ) )
  1438. {
  1439. arrSearchPref[nSearchPrefCount].vValue.Boolean = TRUE;
  1440. }
  1441. else
  1442. {
  1443. arrSearchPref[nSearchPrefCount].vValue.Boolean = FALSE;
  1444. }
  1445. nSearchPrefCount++;
  1446. }
  1447. //***************************************************************************
  1448. if( !aSearchPref.m_strAttributesOnly.IsEmpty( ) )
  1449. {
  1450. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_ATTRIBTYPES_ONLY;
  1451. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_BOOLEAN;
  1452. if( !aSearchPref.m_strAttributesOnly.CompareNoCase( _T("Yes") ) )
  1453. {
  1454. arrSearchPref[nSearchPrefCount].vValue.Boolean = TRUE;
  1455. }
  1456. else
  1457. {
  1458. arrSearchPref[nSearchPrefCount].vValue.Boolean = FALSE;
  1459. }
  1460. nSearchPrefCount++;
  1461. }
  1462. //***************************************************************************
  1463. if( !aSearchPref.m_strDerefAliases.IsEmpty( ) )
  1464. {
  1465. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_DEREF_ALIASES;
  1466. arrSearchPref[nSearchPrefCount].vValue.dwType= ADSTYPE_INTEGER;
  1467. if( !aSearchPref.m_strDerefAliases.CompareNoCase( _T("Yes") ) )
  1468. {
  1469. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_DEREF_ALWAYS;
  1470. }
  1471. else
  1472. {
  1473. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_DEREF_NEVER;
  1474. }
  1475. nSearchPrefCount++;
  1476. }
  1477. //***************************************************************************
  1478. if( !aSearchPref.m_strTimeOut.IsEmpty( ) )
  1479. {
  1480. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_TIMEOUT;
  1481. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1482. arrSearchPref[nSearchPrefCount].vValue.Integer = _ttoi( aSearchPref.m_strTimeOut.GetBuffer( 16 ) );
  1483. nSearchPrefCount++;
  1484. }
  1485. //***************************************************************************
  1486. if( !aSearchPref.m_strTimeLimit.IsEmpty( ) )
  1487. {
  1488. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_TIME_LIMIT;
  1489. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1490. arrSearchPref[nSearchPrefCount].vValue.Integer = _ttoi( aSearchPref.m_strTimeLimit.GetBuffer( 16 ) );
  1491. nSearchPrefCount++;
  1492. }
  1493. //***************************************************************************
  1494. if( !aSearchPref.m_strSizeLimit.IsEmpty( ) )
  1495. {
  1496. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT;
  1497. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1498. arrSearchPref[nSearchPrefCount].vValue.Integer = _ttoi( aSearchPref.m_strSizeLimit.GetBuffer( 16 ) );
  1499. nSearchPrefCount++;
  1500. }
  1501. //***************************************************************************
  1502. if( !aSearchPref.m_strPageSize.IsEmpty( ) )
  1503. {
  1504. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
  1505. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1506. arrSearchPref[nSearchPrefCount].vValue.Integer = _ttoi( aSearchPref.m_strPageSize.GetBuffer( 16 ) );
  1507. nSearchPrefCount++;
  1508. }
  1509. //***************************************************************************
  1510. if( !aSearchPref.m_strScope.IsEmpty( ) )
  1511. {
  1512. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  1513. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1514. if (!aSearchPref.m_strScope.CompareNoCase( _T("Base" ) ) )
  1515. {
  1516. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_SCOPE_BASE;
  1517. }
  1518. if (!aSearchPref.m_strScope.CompareNoCase( _T("OneLevel" ) ) )
  1519. {
  1520. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_SCOPE_ONELEVEL;
  1521. }
  1522. if (!aSearchPref.m_strScope.CompareNoCase( _T("Subtree" ) ) )
  1523. {
  1524. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_SCOPE_SUBTREE;
  1525. }
  1526. nSearchPrefCount++;
  1527. }
  1528. hResult = m_pSearch->SetSearchPreference( arrSearchPref, nSearchPrefCount );
  1529. ASSERT( SUCCEEDED( hResult ) );
  1530. return hResult;
  1531. } */
  1532. /*****************************************************************************
  1533. Function:
  1534. Arguments:
  1535. Return:
  1536. Purpose:
  1537. Author(s):
  1538. Revision:
  1539. Date:
  1540. *****************************************************************************/
  1541. HRESULT CADsSearchDataSource::SetSearchPreferences( )
  1542. {
  1543. ADS_SEARCHPREF_INFO arrSearchPref[ 20 ];
  1544. int nSearchPrefCount = 0;
  1545. HRESULT hResult;
  1546. //***************************************************************************
  1547. if( -1 != m_pSearchPref->nAsynchronous )
  1548. {
  1549. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_ASYNCHRONOUS;
  1550. arrSearchPref[nSearchPrefCount].vValue.dwType= ADSTYPE_BOOLEAN;
  1551. arrSearchPref[nSearchPrefCount].vValue.Boolean = (BOOLEAN) m_pSearchPref->nAsynchronous;
  1552. nSearchPrefCount++;
  1553. }
  1554. //***************************************************************************
  1555. if( -1 != m_pSearchPref->nAttributesOnly )
  1556. {
  1557. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_ATTRIBTYPES_ONLY;
  1558. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_BOOLEAN;
  1559. arrSearchPref[nSearchPrefCount].vValue.Boolean = (BOOLEAN) m_pSearchPref->nAttributesOnly;
  1560. nSearchPrefCount++;
  1561. }
  1562. //***************************************************************************
  1563. if( -1 != m_pSearchPref->nDerefAliases )
  1564. {
  1565. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_DEREF_ALIASES;
  1566. arrSearchPref[nSearchPrefCount].vValue.dwType= ADSTYPE_INTEGER;
  1567. if( m_pSearchPref->nDerefAliases )
  1568. {
  1569. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_DEREF_ALWAYS;
  1570. }
  1571. else
  1572. {
  1573. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_DEREF_NEVER;
  1574. }
  1575. nSearchPrefCount++;
  1576. }
  1577. //***************************************************************************
  1578. if( -1 != m_pSearchPref->nTimeOut )
  1579. {
  1580. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_TIMEOUT;
  1581. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1582. arrSearchPref[nSearchPrefCount].vValue.Integer = m_pSearchPref->nTimeOut;
  1583. nSearchPrefCount++;
  1584. }
  1585. //***************************************************************************
  1586. if( -1 != m_pSearchPref->nTimeLimit )
  1587. {
  1588. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_TIME_LIMIT;
  1589. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1590. arrSearchPref[nSearchPrefCount].vValue.Integer = m_pSearchPref->nTimeLimit;
  1591. nSearchPrefCount++;
  1592. }
  1593. //***************************************************************************
  1594. if( -1 != m_pSearchPref->nSizeLimit )
  1595. {
  1596. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_SIZE_LIMIT;
  1597. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1598. arrSearchPref[nSearchPrefCount].vValue.Integer = m_pSearchPref->nSizeLimit;
  1599. nSearchPrefCount++;
  1600. }
  1601. //***************************************************************************
  1602. if( -1 != m_pSearchPref->nPageSize )
  1603. {
  1604. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_PAGESIZE;
  1605. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1606. arrSearchPref[nSearchPrefCount].vValue.Integer = m_pSearchPref->nPageSize;
  1607. nSearchPrefCount++;
  1608. }
  1609. //***************************************************************************
  1610. if( _tcslen( m_pSearchPref->szScope ) )
  1611. {
  1612. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE;
  1613. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1614. if( !_tcsicmp( m_pSearchPref->szScope, _T("Base" ) ) )
  1615. {
  1616. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_SCOPE_BASE;
  1617. }
  1618. if( !_tcsicmp( m_pSearchPref->szScope, _T("OneLevel" ) ) )
  1619. {
  1620. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_SCOPE_ONELEVEL;
  1621. }
  1622. if( !_tcsicmp( m_pSearchPref->szScope, _T("Subtree" ) ) )
  1623. {
  1624. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_SCOPE_SUBTREE;
  1625. }
  1626. nSearchPrefCount++;
  1627. }
  1628. //***************************************************************************
  1629. if( -1 != m_pSearchPref->nChaseReferrals )
  1630. {
  1631. arrSearchPref[nSearchPrefCount].dwSearchPref = ADS_SEARCHPREF_CHASE_REFERRALS;
  1632. arrSearchPref[nSearchPrefCount].vValue.dwType = ADSTYPE_INTEGER;
  1633. if( m_pSearchPref->nChaseReferrals )
  1634. {
  1635. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_CHASE_REFERRALS_ALWAYS;
  1636. }
  1637. else
  1638. {
  1639. arrSearchPref[nSearchPrefCount].vValue.Integer = ADS_CHASE_REFERRALS_NEVER;
  1640. }
  1641. nSearchPrefCount++;
  1642. }
  1643. hResult = m_pSearch->SetSearchPreference( arrSearchPref, nSearchPrefCount );
  1644. ASSERT( S_OK == hResult );
  1645. return hResult;
  1646. }
  1647. /*****************************************************************************
  1648. Function:
  1649. Arguments:
  1650. Return:
  1651. Purpose:
  1652. Author(s):
  1653. Revision:
  1654. Date:
  1655. *****************************************************************************/
  1656. HRESULT CADsSearchDataSource::CreateSearchInterface( )
  1657. {
  1658. BSTR bstrPath;
  1659. HRESULT hResult = E_FAIL;
  1660. bstrPath = AllocBSTR( m_pSearchPref->szSource );
  1661. if( _tcslen( m_pSearchPref->szUserName ) )
  1662. {
  1663. BSTR bstrOpenAs;
  1664. BSTR bstrPassword;
  1665. LONG lControlCode = 0L;
  1666. bstrOpenAs = AllocBSTR( m_pSearchPref->szUserName );
  1667. bstrPassword = AllocBSTR( m_pSearchPref->szPassword );
  1668. if( m_pSearchPref->bEncryptPassword )
  1669. lControlCode = lControlCode | ADS_SECURE_AUTHENTICATION;
  1670. hResult = ADsOpenObject( bstrPath,
  1671. _wcsicmp( bstrOpenAs, L"NULL" ) ? bstrOpenAs : NULL,
  1672. _wcsicmp( bstrPassword, L"NULL" ) ? bstrPassword : NULL,
  1673. lControlCode, IID_IDirectorySearch, (void**)&m_pSearch );
  1674. SysFreeString( bstrOpenAs );
  1675. SysFreeString( bstrPassword );
  1676. }
  1677. else
  1678. {
  1679. hResult = ADsGetObject( bstrPath, IID_IDirectorySearch, (void**)&m_pSearch );
  1680. }
  1681. ASSERT( SUCCEEDED( hResult ) );
  1682. SysFreeString( bstrPath );
  1683. return hResult;
  1684. }
  1685. /*****************************************************************************
  1686. Function:
  1687. Arguments:
  1688. Return:
  1689. Purpose:
  1690. Author(s):
  1691. Revision:
  1692. Date:
  1693. *****************************************************************************/
  1694. BOOL CADsSearchDataSource::BringRowInBuffer( int nRow )
  1695. {
  1696. HRESULT hResult = E_FAIL;
  1697. if( NULL == m_pSearch )
  1698. {
  1699. m_bNoMoreData = TRUE;
  1700. }
  1701. if( m_bNoMoreData )
  1702. return FALSE;
  1703. if( m_nCurrentRow == nRow )
  1704. return TRUE;
  1705. if( m_nCurrentRow != -1 )
  1706. {
  1707. ASSERT( nRow >= m_nCurrentRow );
  1708. }
  1709. while( m_nCurrentRow != nRow )
  1710. {
  1711. m_bNoMoreData = TRUE;
  1712. TRACE( _T("Asking for row %d\n"), m_nCurrentRow + 1);
  1713. hResult = m_pSearch->GetNextRow( m_hSearch );
  1714. if( hResult != S_OK )
  1715. break;
  1716. m_bNoMoreData = FALSE;
  1717. if( hResult == S_ADS_NOMORE_ROWS )
  1718. {
  1719. m_bNoMoreData = TRUE;
  1720. }
  1721. m_nCurrentRow++;
  1722. }
  1723. if( hResult == S_OK )
  1724. {
  1725. ReadColumnNames( nRow );
  1726. }
  1727. return ( hResult == S_OK );
  1728. }
  1729. /*****************************************************************************
  1730. Function:
  1731. Arguments:
  1732. Return:
  1733. Purpose:
  1734. Author(s):
  1735. Revision:
  1736. Date:
  1737. *****************************************************************************/
  1738. BOOL CADsSearchDataSource::ReadColumnNames( int nRow )
  1739. {
  1740. HRESULT hResult = E_FAIL;
  1741. WCHAR* pszColumnName;
  1742. TCHAR szColumn[ 256 ];
  1743. ASSERT( nRow == m_nCurrentRow );
  1744. if( nRow != m_nCurrentRow )
  1745. {
  1746. return FALSE;
  1747. }
  1748. m_strColumns.RemoveAll( );
  1749. ReadADsPath( );
  1750. while( TRUE )
  1751. {
  1752. hResult = m_pSearch->GetNextColumnName( m_hSearch, &pszColumnName );
  1753. //if( SUCCEEDED( hResult ) )
  1754. if( S_OK == hResult )
  1755. {
  1756. Convert( szColumn, pszColumnName );
  1757. m_strColumns.Add( szColumn );
  1758. FreeADsStr( pszColumnName );
  1759. }
  1760. //if( FAILED( hResult ) )
  1761. else
  1762. {
  1763. break;
  1764. }
  1765. }
  1766. return TRUE;
  1767. }
  1768. /*****************************************************************************
  1769. Function:
  1770. Arguments:
  1771. Return:
  1772. Purpose:
  1773. Author(s):
  1774. Revision:
  1775. Date:
  1776. *****************************************************************************/
  1777. void CADsSearchDataSource::ReadADsPath( void )
  1778. {
  1779. HRESULT hResult;
  1780. BSTR bstrColumnName;
  1781. ADS_SEARCH_COLUMN aSearchColumn;
  1782. ADS_ATTR_INFO aAttrDef;
  1783. BOOL bOK = TRUE;
  1784. COleDsSyntax* pSyntax;
  1785. CString rValue = _T("");
  1786. bstrColumnName = AllocBSTR( _T("ADsPath") );
  1787. hResult = m_pSearch->GetColumn( m_hSearch,
  1788. bstrColumnName,
  1789. &aSearchColumn );
  1790. SysFreeString( bstrColumnName );
  1791. if( SUCCEEDED( hResult ) )
  1792. {
  1793. aAttrDef.pszAttrName = aSearchColumn.pszAttrName;
  1794. aAttrDef.dwADsType = aSearchColumn.dwADsType;
  1795. aAttrDef.pADsValues = aSearchColumn.pADsValues;
  1796. aAttrDef.dwNumValues = aSearchColumn.dwNumValues;
  1797. pSyntax = new COleDsBSTR;
  1798. hResult = pSyntax->Native2Value( &aAttrDef, rValue );
  1799. delete pSyntax;
  1800. hResult = m_pSearch->FreeColumn( &aSearchColumn );
  1801. }
  1802. m_ADsPath.Add( rValue );
  1803. }
  1804.