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.

974 lines
31 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-2000.
  5. //
  6. // File: monarch.cxx
  7. //
  8. // Contents: Public interfaces to Index Server
  9. //
  10. // History: 24 Jan 1997 Alanw Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "pch.cxx"
  14. #pragma hdrstop
  15. #include <pvarset.hxx>
  16. #include <strsort.hxx>
  17. #include <ciplist.hxx>
  18. #include <doquery.hxx>
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: AddToPropertyList, private
  22. //
  23. // Synopsis: Adds an array of properties to a property list
  24. //
  25. // Arguments: [PropertyList] -- destination for the props
  26. // [cProperties] -- # of properties to add
  27. // [pProperties] -- source of props
  28. // [lcid] -- Locale (used for uppercasing)
  29. //
  30. // History: 21 Jul 1997 dlee Created
  31. //
  32. //----------------------------------------------------------------------------
  33. void AddToPropertyList( CLocalGlobalPropertyList & PropertyList,
  34. ULONG cProperties,
  35. CIPROPERTYDEF * pProperties,
  36. LCID lcid )
  37. {
  38. if ( ( 0 != cProperties ) && ( 0 == pProperties ) )
  39. THROW( CException( E_INVALIDARG ) );
  40. XGrowable<WCHAR> xTemp;
  41. for ( unsigned i = 0; i < cProperties; i++ )
  42. {
  43. //
  44. // Uppercase the friendly name. Done at this level of code to
  45. // optimize other property lookup paths.
  46. //
  47. int cc = wcslen( pProperties[i].wcsFriendlyName ) + 1;
  48. xTemp.SetSize( cc + cc/2 );
  49. int ccOut = LCMapString( lcid,
  50. LCMAP_UPPERCASE,
  51. pProperties[i].wcsFriendlyName,
  52. cc,
  53. xTemp.Get(),
  54. xTemp.Count() );
  55. Win4Assert( 0 != ccOut );
  56. Win4Assert( 0 == xTemp[ccOut-1] );
  57. if ( 0 == ccOut )
  58. THROW( CException() );
  59. XPtr<CPropEntry> xEntry;
  60. //
  61. // Did the string change?
  62. //
  63. if ( ccOut == cc &&
  64. RtlEqualMemory( pProperties[i].wcsFriendlyName, xTemp.Get(), cc*sizeof(WCHAR) ) )
  65. {
  66. xEntry.Set( new CPropEntry( pProperties[i].wcsFriendlyName,
  67. 0,
  68. (DBTYPE) pProperties[i].dbType,
  69. pProperties[i].dbCol ) );
  70. }
  71. else
  72. {
  73. XPtrST<WCHAR> xFName( new WCHAR[ccOut] );
  74. RtlCopyMemory( xFName.GetPointer(), xTemp.Get(), ccOut * sizeof(WCHAR) );
  75. xEntry.Set( new CPropEntry( xFName,
  76. (DBTYPE) pProperties[i].dbType,
  77. pProperties[i].dbCol ) );
  78. }
  79. //
  80. // Add new property to list.
  81. //
  82. PropertyList.AddEntry( xEntry.GetPointer(), 0 );
  83. xEntry.Acquire();
  84. }
  85. } //AddToPropertyList
  86. //+---------------------------------------------------------------------------
  87. //
  88. // Function: CITextToSelectTree, public
  89. //
  90. // Synopsis: Converts a Tripoli query string into a DBCOMMANDTREE
  91. //
  92. // Arguments: [pwszRestriction] - input query string
  93. // [ppTree] - output command tree
  94. // [cProperties] - number of extension properties
  95. // [pProperties] - pointer to extension property array
  96. //
  97. // History: 29 Oct 1996 Alanw Created
  98. //
  99. //----------------------------------------------------------------------------
  100. SCODE CITextToSelectTree(
  101. WCHAR const * pwszRestriction,
  102. DBCOMMANDTREE * * ppTree,
  103. ULONG cProperties,
  104. CIPROPERTYDEF * pProperties,
  105. LCID LocaleID )
  106. {
  107. return CITextToSelectTreeEx( pwszRestriction,
  108. ISQLANG_V1,
  109. ppTree,
  110. cProperties,
  111. pProperties,
  112. LocaleID );
  113. } //CITextToSelectTree
  114. //+---------------------------------------------------------------------------
  115. //
  116. // Function: CITextToFullTree
  117. //
  118. // Synopsis: Forms a DBCOMMANDTREE from the given restriction, output
  119. // columns and sort columns.
  120. //
  121. // Arguments: [pwszRestriction] - Input query string in "Triplish"
  122. // [pwszColumns] - List of comma separated output columns.
  123. // [pwszSortColumns] - sort specification, may be NULL
  124. // [pwszGrouping] - grouping specification, may be NULL
  125. // [ppTree] - [out] The DBCOMMANDTREE representing the
  126. // query.
  127. // [cProperties] - [in] Number of properties in pProperties
  128. // [pProperties] - [in] List of custom properties
  129. // [LocaleID] - [in] The locale for query parsing
  130. //
  131. // Returns: S_OK if successful; Error code otherwise
  132. //
  133. // History: 3-03-97 srikants Created
  134. //
  135. //----------------------------------------------------------------------------
  136. SCODE CITextToFullTree( WCHAR const * pwszRestriction,
  137. WCHAR const * pwszColumns,
  138. WCHAR const * pwszSortColumns,
  139. WCHAR const * pwszGrouping,
  140. DBCOMMANDTREE * * ppTree,
  141. ULONG cProperties,
  142. CIPROPERTYDEF * pProperties,
  143. LCID LocaleID )
  144. {
  145. return CITextToFullTreeEx( pwszRestriction,
  146. ISQLANG_V1,
  147. pwszColumns,
  148. pwszSortColumns,
  149. pwszGrouping,
  150. ppTree,
  151. cProperties,
  152. pProperties,
  153. LocaleID );
  154. } //CITextToFullTree
  155. //+---------------------------------------------------------------------------
  156. //
  157. // Function: CITextToSelectTreeEx, public
  158. //
  159. // Synopsis: Converts a Tripoli query string into a DBCOMMANDTREE
  160. //
  161. // Arguments: [pwszRestriction] - input query string
  162. // [ulDialect] - dialect of triplish
  163. // [ppTree] - output command tree
  164. // [cProperties] - number of extension properties
  165. // [pProperties] - pointer to extension property array
  166. //
  167. // History: 29 Oct 1996 Alanw Created
  168. //
  169. //----------------------------------------------------------------------------
  170. SCODE CITextToSelectTreeEx(
  171. WCHAR const * pwszRestriction,
  172. ULONG ulDialect,
  173. DBCOMMANDTREE * * ppTree,
  174. ULONG cProperties,
  175. CIPROPERTYDEF * pProperties,
  176. LCID LocaleID )
  177. {
  178. if ( 0 == pwszRestriction || 0 == *pwszRestriction || 0 == ppTree )
  179. return E_INVALIDARG;
  180. if ( ISQLANG_V1 != ulDialect &&
  181. ISQLANG_V2 != ulDialect )
  182. return E_INVALIDARG;
  183. SCODE sc = S_OK;
  184. CTranslateSystemExceptions translate;
  185. TRY
  186. {
  187. LCID lcid = LocaleID;
  188. if (lcid == -1)
  189. lcid = GetSystemDefaultLCID();
  190. XInterface<CLocalGlobalPropertyList> xPropertyList(new CLocalGlobalPropertyList(lcid));
  191. AddToPropertyList( xPropertyList.GetReference(),
  192. cProperties,
  193. pProperties,
  194. LocaleID );
  195. //
  196. // Setup the variables needed to execute this query; including:
  197. //
  198. // CiRestriction
  199. // CiMaxRecordsInResultSet
  200. // CiSort
  201. //
  202. // ixssoDebugOut(( DEB_TRACE, "ExecuteQuery:\n" ));
  203. // ixssoDebugOut(( DEB_TRACE, "\tCiRestriction = '%ws'\n", pwszRestriction ));
  204. *ppTree = GetStringDbRestriction( pwszRestriction,
  205. ulDialect,
  206. xPropertyList.GetPointer(),
  207. lcid )->CastToStruct();
  208. }
  209. CATCH ( CException, e )
  210. {
  211. sc = GetScodeError( e );
  212. }
  213. END_CATCH;
  214. return sc;
  215. } //CITextToSelectTreeEx
  216. //+---------------------------------------------------------------------------
  217. //
  218. // Function: CITextToFullTreeEx
  219. //
  220. // Synopsis: Forms a DBCOMMANDTREE from the given restriction, output
  221. // columns and sort columns.
  222. //
  223. // Arguments: [pwszRestriction] - Input query string in "Triplish"
  224. // [ulDialect] - Dialect of Triplish
  225. // [pwszColumns] - List of comma separated output columns.
  226. // [pwszSortColumns] - sort specification, may be NULL
  227. // [pwszGrouping] - grouping specification, may be NULL
  228. // [ppTree] - [out] The DBCOMMANDTREE representing the
  229. // query.
  230. // [cProperties] - [in] Number of properties in pProperties
  231. // [pProperties] - [in] List of custom properties
  232. // [LocaleID] - [in] The locale for query parsing
  233. //
  234. // Returns: S_OK if successful; Error code otherwise
  235. //
  236. // History: 3-03-97 srikants Created
  237. //
  238. //----------------------------------------------------------------------------
  239. SCODE CITextToFullTreeEx( WCHAR const * pwszRestriction,
  240. ULONG ulDialect,
  241. WCHAR const * pwszColumns,
  242. WCHAR const * pwszSortColumns,
  243. WCHAR const * pwszGrouping,
  244. DBCOMMANDTREE * * ppTree,
  245. ULONG cProperties,
  246. CIPROPERTYDEF * pProperties,
  247. LCID LocaleID )
  248. {
  249. if ( 0 == ppTree ||
  250. 0 == pwszRestriction ||
  251. 0 == *pwszRestriction ||
  252. 0 == pwszColumns ||
  253. 0 == *pwszColumns )
  254. return E_INVALIDARG;
  255. if ( ISQLANG_V1 != ulDialect &&
  256. ISQLANG_V2 != ulDialect )
  257. return E_INVALIDARG;
  258. SCODE sc = S_OK;
  259. CTranslateSystemExceptions translate;
  260. TRY
  261. {
  262. LCID lcid = LocaleID;
  263. if (lcid == -1)
  264. lcid = GetSystemDefaultLCID();
  265. XInterface<CLocalGlobalPropertyList> xPropertyList(new CLocalGlobalPropertyList(lcid));
  266. AddToPropertyList( xPropertyList.GetReference(),
  267. cProperties,
  268. pProperties,
  269. LocaleID );
  270. CTextToTree textToTree( pwszRestriction,
  271. ulDialect,
  272. pwszColumns,
  273. xPropertyList.GetPointer(),
  274. lcid,
  275. pwszSortColumns,
  276. pwszGrouping );
  277. *ppTree = textToTree.FormFullTree();
  278. }
  279. CATCH ( CException, e )
  280. {
  281. sc = GetScodeError( e );
  282. }
  283. END_CATCH;
  284. return sc;
  285. } //CITextToFullTreeEx
  286. //+---------------------------------------------------------------------------
  287. //
  288. // Function: CIBuildQueryNode
  289. //
  290. // Synopsis: Build a simple restriction node.
  291. //
  292. // Arguments: [wcsProperty] - Target property
  293. // [dwOperator] - Enumerated operator
  294. // [pvarPropertyValue] - property value
  295. // [ppTree] - [out] The DBCOMMANDTREE representing the
  296. // simple restriction.
  297. // [cProperties] - # of props in the pProperties array
  298. // [pProperties] - Array of properties
  299. // [LocaleId] - Locale to use.
  300. //
  301. // Returns: S_OK if successful; Error code otherwise
  302. //
  303. // History: July 22 1997 KrishnaN Created
  304. //
  305. //----------------------------------------------------------------------------
  306. SCODE CIBuildQueryNode(WCHAR const *wcsProperty,
  307. DBCOMMANDOP dbOperator,
  308. PROPVARIANT const *pvarPropertyValue,
  309. DBCOMMANDTREE ** ppTree,
  310. ULONG cProperties,
  311. CIPROPERTYDEF const * pProperties, // Can be 0.
  312. LCID LocaleID)
  313. {
  314. if (0 == pvarPropertyValue || 0 == ppTree ||
  315. (cProperties > 0 && 0 == pProperties))
  316. return E_INVALIDARG;
  317. XInterface<CLocalGlobalPropertyList> xPropertyList;
  318. SCODE sc = S_OK;
  319. *ppTree = 0;
  320. CTranslateSystemExceptions translate;
  321. TRY
  322. {
  323. xPropertyList.Set( new CLocalGlobalPropertyList( LocaleID ) );
  324. //
  325. // No need to add to prop list if this is dbop_content.
  326. // CITextToSelectTree does that.
  327. //
  328. if (pProperties && dbOperator != DBOP_content)
  329. {
  330. AddToPropertyList( xPropertyList.GetReference(),
  331. cProperties,
  332. (CIPROPERTYDEF *)pProperties,
  333. LocaleID );
  334. }
  335. DBID *pdbid = 0;
  336. CDbColId *pcdbCol = 0;
  337. DBTYPE ptype;
  338. // dbop_content prop info is taken care in citexttoselecttree call
  339. if (dbOperator != DBOP_content)
  340. {
  341. if( FAILED(xPropertyList->GetPropInfoFromName( wcsProperty,
  342. &pdbid,
  343. &ptype,
  344. 0 )) )
  345. THROW( CParserException( QPARSE_E_NO_SUCH_PROPERTY ) );
  346. }
  347. pcdbCol = (CDbColId *)pdbid;
  348. switch (dbOperator)
  349. {
  350. //
  351. // The caller passes a chunk of text. Pass it
  352. // to the parser and have it build a restriction
  353. // for us.
  354. //
  355. case DBOP_content:
  356. {
  357. if (pvarPropertyValue->vt != VT_LPWSTR &&
  358. pvarPropertyValue->vt != (DBTYPE_WSTR|DBTYPE_BYREF))
  359. THROW( CException( E_INVALIDARG ) );
  360. sc = CITextToSelectTree(pvarPropertyValue->pwszVal,
  361. ppTree,
  362. cProperties,
  363. (CIPROPERTYDEF *)pProperties,
  364. LocaleID );
  365. break;
  366. }
  367. //
  368. // The caller passes a chunk of text which should be
  369. // interpreted as free text. Build a natlang restriction.
  370. //
  371. case DBOP_content_freetext:
  372. {
  373. if (pvarPropertyValue->vt != VT_LPWSTR &&
  374. pvarPropertyValue->vt != (DBTYPE_WSTR|DBTYPE_BYREF))
  375. THROW( CException( E_INVALIDARG ) );
  376. XPtr<CDbNatLangRestriction> xNatLangRst( new CDbNatLangRestriction( pvarPropertyValue->pwszVal,
  377. *pcdbCol,
  378. LocaleID ) );
  379. if ( xNatLangRst.IsNull() || !xNatLangRst->IsValid() )
  380. THROW( CException( E_OUTOFMEMORY ) );
  381. *ppTree = xNatLangRst->CastToStruct();
  382. xNatLangRst.Acquire();
  383. break;
  384. }
  385. //
  386. // Regular expressions and property value queries
  387. //
  388. case DBOP_like:
  389. case DBOP_equal:
  390. case DBOP_not_equal:
  391. case DBOP_less:
  392. case DBOP_less_equal:
  393. case DBOP_greater:
  394. case DBOP_greater_equal:
  395. case DBOP_allbits:
  396. case DBOP_anybits:
  397. case DBOP_equal_all:
  398. case DBOP_not_equal_all:
  399. case DBOP_greater_all:
  400. case DBOP_greater_equal_all:
  401. case DBOP_less_all:
  402. case DBOP_less_equal_all:
  403. case DBOP_allbits_all:
  404. case DBOP_anybits_all:
  405. case DBOP_equal_any:
  406. case DBOP_not_equal_any:
  407. case DBOP_greater_any:
  408. case DBOP_greater_equal_any:
  409. case DBOP_less_any:
  410. case DBOP_less_equal_any:
  411. case DBOP_allbits_any:
  412. case DBOP_anybits_any:
  413. {
  414. XPtr<CDbPropertyRestriction> xPrpRst( new CDbPropertyRestriction
  415. (dbOperator,
  416. *(pcdbCol->CastToStruct()),
  417. *(CStorageVariant const *)(void *)pvarPropertyValue) );
  418. if ( xPrpRst.IsNull() || !xPrpRst->IsValid() )
  419. THROW( CException( E_OUTOFMEMORY ) );
  420. *ppTree = xPrpRst->CastToStruct();
  421. xPrpRst.Acquire();
  422. break;
  423. }
  424. default:
  425. sc = E_INVALIDARG;
  426. break;
  427. }
  428. }
  429. CATCH(CException, e)
  430. {
  431. sc = GetScodeError( e );
  432. Win4Assert(0 == *ppTree);
  433. }
  434. END_CATCH
  435. return sc;
  436. } //CIBuildQueryNode
  437. //+---------------------------------------------------------------------------
  438. //
  439. // Function: CIBuildQueryTree
  440. //
  441. // Synopsis: Build a restriction tree from an existing tree (could be empty)
  442. // and a newly added node/tree.
  443. //
  444. // Arguments: [pExistingTree] - Ptr to existing command tree
  445. // [dwBoolOp] - Enumerated boolean operator
  446. // [cSiblings] - Number of trees to combine at the same level.
  447. // [ppSibsToCombine]- Array of sibling tree to combine.
  448. // [ppTree] - [out] The DBCOMMANDTREE representing the
  449. // combined restriction.
  450. //
  451. // Returns: S_OK if successful; Error code otherwise
  452. //
  453. // History: July 22 1997 KrishnaN Created
  454. //
  455. //----------------------------------------------------------------------------
  456. SCODE CIBuildQueryTree(DBCOMMANDTREE const *pExistingTree,
  457. DBCOMMANDOP dbBoolOp,
  458. ULONG cSiblings,
  459. DBCOMMANDTREE const * const *ppSibsToCombine,
  460. DBCOMMANDTREE ** ppTree)
  461. {
  462. if (0 == cSiblings || 0 == ppTree ||
  463. 0 == ppSibsToCombine || 0 == *ppSibsToCombine)
  464. return E_INVALIDARG;
  465. // AND and OR should have at least two operands
  466. if ((dbBoolOp == DBOP_and || dbBoolOp == DBOP_or) &&
  467. 0 == pExistingTree && cSiblings < 2)
  468. return E_INVALIDARG;
  469. // NOT should have only one operand
  470. if (dbBoolOp == DBOP_not && (pExistingTree || cSiblings > 1))
  471. return E_INVALIDARG;
  472. *ppTree = 0;
  473. SCODE sc = S_OK;
  474. CTranslateSystemExceptions translate;
  475. TRY
  476. {
  477. switch(dbBoolOp)
  478. {
  479. case DBOP_and:
  480. case DBOP_or:
  481. {
  482. CDbBooleanNodeRestriction *pAndOrCombiner = new CDbBooleanNodeRestriction( dbBoolOp );
  483. if (0 == pAndOrCombiner)
  484. THROW( CException( E_OUTOFMEMORY ) );
  485. if (pExistingTree)
  486. pAndOrCombiner->AppendChild((CDbRestriction *)CDbCmdTreeNode::CastFromStruct(pExistingTree));
  487. for (ULONG i = 0; i < cSiblings; i++)
  488. pAndOrCombiner->AppendChild((CDbRestriction *)CDbCmdTreeNode::CastFromStruct(ppSibsToCombine[i]));
  489. *ppTree = pAndOrCombiner->CastToStruct();
  490. break;
  491. }
  492. case DBOP_not:
  493. {
  494. CDbNotRestriction *pNotCombiner = new CDbNotRestriction((CDbRestriction *)
  495. CDbCmdTreeNode::CastFromStruct(ppSibsToCombine[0]));
  496. if (0 == pNotCombiner)
  497. THROW( CException( E_OUTOFMEMORY ) );
  498. *ppTree = pNotCombiner->CastToStruct();
  499. break;
  500. }
  501. default:
  502. sc = E_INVALIDARG;
  503. break;
  504. }
  505. }
  506. CATCH(CException, e)
  507. {
  508. sc = GetScodeError( e );
  509. Win4Assert(0 == *ppTree);
  510. }
  511. END_CATCH
  512. return sc;
  513. } //CIBuildQueryTree
  514. //+---------------------------------------------------------------------------
  515. //
  516. // Function: CIRestrictionToFullTree
  517. //
  518. // Synopsis: Forms a DBCOMMANDTREE from the given restriction, output
  519. // columns and sort columns.
  520. //
  521. // Arguments: [pTree] - Input query tree
  522. // [pwszColumns] - List of comma separated output columns.
  523. // [pwszSortColumns] - sort specification, may be NULL
  524. // [pwszGrouping] - grouping specification, may be NULL
  525. // [ppTree] - [out] The DBCOMMANDTREE representing the
  526. // query.
  527. // [cProperties] - [in] Number of properties in pProperties
  528. // [pProperties] - [in] List of custom properties
  529. // [LocaleID] - [in] The locale for query parsing
  530. //
  531. // Returns: S_OK if successful; Error code otherwise
  532. //
  533. // History: 3-03-97 srikants Created
  534. //
  535. //----------------------------------------------------------------------------
  536. SCODE CIRestrictionToFullTree( DBCOMMANDTREE const *pTree,
  537. WCHAR const * pwszColumns,
  538. WCHAR const * pwszSortColumns,
  539. WCHAR const * pwszGrouping,
  540. DBCOMMANDTREE * * ppTree,
  541. ULONG cProperties,
  542. CIPROPERTYDEF * pProperties,
  543. LCID LocaleID )
  544. {
  545. if ( 0 == ppTree ||
  546. 0 == pTree ||
  547. 0 == pwszColumns ||
  548. 0 == *pwszColumns )
  549. return E_INVALIDARG;
  550. SCODE sc = S_OK;
  551. CTranslateSystemExceptions translate;
  552. TRY
  553. {
  554. LCID lcid = LocaleID;
  555. if (lcid == -1)
  556. lcid = GetSystemDefaultLCID();
  557. XInterface<CLocalGlobalPropertyList> xPropertyList(new CLocalGlobalPropertyList(LocaleID));
  558. AddToPropertyList( xPropertyList.GetReference(),
  559. cProperties,
  560. pProperties,
  561. LocaleID );
  562. CTextToTree RestrictionToTree( pTree,
  563. pwszColumns,
  564. xPropertyList.GetPointer(),
  565. lcid,
  566. pwszSortColumns,
  567. pwszGrouping );
  568. *ppTree = RestrictionToTree.FormFullTree();
  569. }
  570. CATCH ( CException, e )
  571. {
  572. sc = GetScodeError( e );
  573. }
  574. END_CATCH;
  575. return sc;
  576. } //CIRestrictionToFullTree
  577. //+---------------------------------------------------------------------------
  578. //
  579. // Function: CIMakeICommand
  580. //
  581. // Synopsis: Creates an ICommand
  582. //
  583. // Arguments: [ppCommand] -- where the ICommand is returned
  584. // [cScope] -- # of items in below arrays
  585. // [aDepths] -- array of depths
  586. // [awcsScope] -- array of scopes
  587. // [awcsCat] -- array of catalogs
  588. // [awcsMachine] -- array of machines
  589. //
  590. // Returns: S_OK if successful; Error code otherwise
  591. //
  592. // History: 6-11-97 dlee Fixed and added header
  593. //
  594. //----------------------------------------------------------------------------
  595. SCODE CIMakeICommand( ICommand ** ppCommand,
  596. ULONG cScope,
  597. DWORD const * aDepths,
  598. WCHAR const * const * awcsScope,
  599. WCHAR const * const * awcsCat,
  600. WCHAR const * const * awcsMachine )
  601. {
  602. if ( 0 == ppCommand ||
  603. 0 == aDepths ||
  604. 0 == awcsScope ||
  605. 0 == awcsCat ||
  606. 0 == awcsMachine ||
  607. 0 == cScope )
  608. return E_INVALIDARG;
  609. *ppCommand = 0;
  610. SCODE sc = S_OK;
  611. CTranslateSystemExceptions translate;
  612. TRY
  613. {
  614. // First get an ICommand object as an IUnknown
  615. XInterface<IUnknown> xUnk;
  616. sc = MakeICommand( xUnk.GetIUPointer(), 0, 0, 0 );
  617. if ( FAILED( sc ) )
  618. THROW( CException( sc ) );
  619. // QI to ICommand
  620. XInterface<ICommand> xCommand;
  621. sc = xUnk->QueryInterface( IID_ICommand,
  622. xCommand.GetQIPointer() );
  623. if ( FAILED( sc ) )
  624. THROW( CException( sc ) );
  625. // SetScopeProperties throws
  626. SetScopeProperties( xCommand.GetPointer(),
  627. cScope,
  628. awcsScope,
  629. aDepths,
  630. awcsCat,
  631. awcsMachine );
  632. *ppCommand = xCommand.Acquire();
  633. }
  634. CATCH ( CException, e )
  635. {
  636. sc = GetScodeError( e );
  637. }
  638. END_CATCH;
  639. return sc;
  640. } //CIMakeICommand
  641. //+---------------------------------------------------------------------------
  642. //
  643. // Function: CICreateCommand
  644. //
  645. // Synopsis: Creates an ICommand
  646. //
  647. // Arguments: [ppResult] -- where the resulting interface is returned
  648. // [pUnkOuter] -- outer unknown
  649. // [riid] -- iid of interface to return. Must be
  650. // IID_IUnknown unless pUnkOuter == 0
  651. // [pwcsCatalog] -- catalog
  652. // [pwcsMachine] -- machine
  653. //
  654. // Returns: S_OK if successful; Error code otherwise
  655. //
  656. // History: 6-11-97 dlee Fixed and added header
  657. //
  658. //----------------------------------------------------------------------------
  659. SCODE CICreateCommand( IUnknown ** ppResult,
  660. IUnknown * pUnkOuter,
  661. REFIID riid,
  662. WCHAR const * pwcsCatalog,
  663. WCHAR const * pwcsMachine )
  664. {
  665. if ( 0 != pUnkOuter && IID_IUnknown != riid )
  666. return CLASS_E_NOAGGREGATION;
  667. if ( 0 == ppResult ||
  668. 0 == pwcsCatalog ||
  669. 0 == pwcsMachine )
  670. return E_INVALIDARG;
  671. // try to AV
  672. *ppResult = 0;
  673. SCODE sc = S_OK;
  674. CTranslateSystemExceptions translate;
  675. TRY
  676. {
  677. //
  678. // First get an ICommand object as an IUnknown
  679. //
  680. XInterface<IUnknown> xUnk;
  681. sc = MakeICommand( xUnk.GetIUPointer(),
  682. 0,
  683. 0,
  684. pUnkOuter );
  685. if ( FAILED( sc ) )
  686. THROW( CException( sc ) );
  687. //
  688. // QI to the interface requested
  689. //
  690. if ( IID_IUnknown != riid )
  691. {
  692. IUnknown *pUnk;
  693. sc = xUnk->QueryInterface( riid,
  694. (void **) & pUnk );
  695. if ( FAILED( sc ) )
  696. THROW( CException( sc ) );
  697. xUnk.Free();
  698. xUnk.Set( pUnk );
  699. }
  700. //
  701. // Set the scope, catalogs, and machines
  702. //
  703. {
  704. // SetScopeProperties throws
  705. DWORD dwFlags = QUERY_DEEP;
  706. WCHAR const * pwcScope = L"\\";
  707. //
  708. // cheezy hack cast, since I can't QI for the ICommand yet
  709. // if the outer unknown is specified. Assume MakeICommand
  710. // returns an ICommand under the IUnknown.
  711. //
  712. SetScopeProperties( (ICommand *) xUnk.GetPointer(),
  713. 1,
  714. &pwcScope,
  715. &dwFlags,
  716. &pwcsCatalog,
  717. &pwcsMachine );
  718. }
  719. *ppResult = xUnk.Acquire();
  720. }
  721. CATCH ( CException, e )
  722. {
  723. //
  724. // This is Index Server's function, not OLE-DB's, so don't mask
  725. // errors as E_FAIL with GetOleError
  726. //
  727. sc = GetScodeError( e );
  728. }
  729. END_CATCH;
  730. return sc;
  731. } //CICreateCommand
  732. //+---------------------------------------------------------------------------
  733. //
  734. // Class: CIPropertyList
  735. //
  736. // Synopsis: allow access to the default property list used by CITextTo*Tree
  737. //
  738. // History: 08-Aug-97 alanw Created
  739. //
  740. //----------------------------------------------------------------------------
  741. class CIPropertyList : public ICiPropertyList
  742. {
  743. public:
  744. CIPropertyList() : _cRef( 1 )
  745. {
  746. _xproplist.Set( new CLocalGlobalPropertyList() );
  747. }
  748. ~CIPropertyList()
  749. {
  750. }
  751. virtual ULONG STDMETHODCALLTYPE AddRef( )
  752. {
  753. return InterlockedIncrement(&_cRef);
  754. }
  755. virtual ULONG STDMETHODCALLTYPE Release( )
  756. {
  757. ULONG uTmp = InterlockedDecrement(&_cRef);
  758. if (uTmp == 0)
  759. {
  760. delete this;
  761. return 0;
  762. }
  763. return uTmp;
  764. }
  765. virtual BOOL GetPropInfo( WCHAR const * wcsPropName,
  766. DBID ** ppPropid,
  767. DBTYPE * pPropType,
  768. unsigned int * puWidth )
  769. {
  770. return (S_OK == _xproplist->GetPropInfoFromName(
  771. wcsPropName,
  772. ppPropid,
  773. pPropType,
  774. puWidth ));
  775. }
  776. virtual BOOL GetPropInfo( DBID const & prop,
  777. WCHAR const ** pwcsName,
  778. DBTYPE * pPropType,
  779. unsigned int * puWidth )
  780. {
  781. return (S_OK == _xproplist->GetPropInfoFromId(
  782. &prop,
  783. (WCHAR **)pwcsName,
  784. pPropType,
  785. puWidth ));
  786. }
  787. virtual BOOL EnumPropInfo( ULONG const & iEntry,
  788. WCHAR const ** pwcsName,
  789. DBID ** ppProp,
  790. DBTYPE * pPropType,
  791. unsigned int * puWidth )
  792. {
  793. return FALSE; // Not implemented because no one needs it.
  794. }
  795. private:
  796. XInterface<CLocalGlobalPropertyList> _xproplist;
  797. LONG _cRef;
  798. };
  799. //+---------------------------------------------------------------------------
  800. //
  801. // Function: CIGetGlobalPropertyList, public
  802. //
  803. // Synopsis: Gets a reference to the property list used by CITextToSelectTree
  804. //
  805. // Arguments: [ppPropList] -- where the ICiPropertyList is returned
  806. //
  807. // Returns: S_OK if successful; Error code otherwise
  808. //
  809. // History: 08-Aug-97 alanw Created
  810. //
  811. //----------------------------------------------------------------------------
  812. SCODE CIGetGlobalPropertyList( ICiPropertyList ** ppPropList )
  813. {
  814. if ( 0 == ppPropList )
  815. return E_INVALIDARG;
  816. *ppPropList = 0;
  817. SCODE sc = S_OK;
  818. CTranslateSystemExceptions translate;
  819. TRY
  820. {
  821. XPtr<CIPropertyList> xProplist( new CIPropertyList() );
  822. *ppPropList = xProplist.Acquire();
  823. }
  824. CATCH ( CException, e )
  825. {
  826. sc = GetScodeError( e );
  827. }
  828. END_CATCH;
  829. return sc;
  830. } //CIGetGlobalPropertyList