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.

545 lines
16 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: cmdcreat.cxx
  7. //
  8. // Contents: IQuery for file-based queries
  9. //
  10. // Classes: CSimpleCommandCreator
  11. //
  12. // History: 20 Aug 1998 AlanW Created - split from stdqspec.cxx
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. extern long gulcInstances;
  18. #include <lgplist.hxx>
  19. #include <ciregkey.hxx>
  20. #include "svcquery.hxx"
  21. #include <svccatpx.hxx>
  22. #include "stdqspec.hxx"
  23. #include "cmdcreat.hxx"
  24. SCODE ProxyErrorToCIError( CException & e );
  25. IDBProperties * CreateDbProperties( WCHAR const * pwcCatalog,
  26. WCHAR const * pwcMachine,
  27. WCHAR const * pwcScopes = 0,
  28. CiMetaData eType = CiAdminOp );
  29. //+-------------------------------------------------------------------------
  30. //
  31. // Method: CSimpleCommandCreator::CSimpleCommandCreator, public
  32. //
  33. // Synopsis: Constructor
  34. //
  35. // History: 13-May-1997 KrishnaN Created
  36. //
  37. //--------------------------------------------------------------------------
  38. CSimpleCommandCreator::CSimpleCommandCreator()
  39. : _cRefs( 1 ),
  40. xDefaultCatalogValue( 0 )
  41. {
  42. InterlockedIncrement( &gulcInstances );
  43. }
  44. //+-------------------------------------------------------------------------
  45. //
  46. // Method: CSimpleCommandCreator::~CSimpleCommandCreator
  47. //
  48. // Synopsis: Desstructor
  49. //
  50. // History: 13-May-1997 KrishnaN Created
  51. //
  52. //--------------------------------------------------------------------------
  53. CSimpleCommandCreator::~CSimpleCommandCreator()
  54. {
  55. InterlockedDecrement( &gulcInstances );
  56. }
  57. //+-------------------------------------------------------------------------
  58. //
  59. // Method: CSimpleCommandCreator::QueryInterface, public
  60. //
  61. // Synopsis: Rebind to other interface
  62. //
  63. // Arguments: [riid] -- IID of new interface
  64. // [ppvObject] -- New interface * returned here
  65. //
  66. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  67. //
  68. // History: 13-May-1997 KrishnaN Created
  69. // 26-Aug-1997 KrishnaN Added IColumnMapperCreator.
  70. //
  71. //--------------------------------------------------------------------------
  72. SCODE STDMETHODCALLTYPE CSimpleCommandCreator::QueryInterface(
  73. REFIID riid,
  74. void ** ppvObject )
  75. {
  76. SCODE sc = 0;
  77. if ( 0 == ppvObject )
  78. return E_INVALIDARG;
  79. *ppvObject = 0;
  80. if ( IID_IClassFactory == riid )
  81. *ppvObject = (IClassFactory *)this;
  82. else if ( IID_ITypeLib == riid )
  83. sc = E_NOTIMPL;
  84. else if ( IID_ISimpleCommandCreator == riid )
  85. *ppvObject = (IUnknown *)(ISimpleCommandCreator *)this;
  86. else if ( IID_IColumnMapperCreator == riid )
  87. *ppvObject = (IUnknown *)(IColumnMapperCreator *)this;
  88. else if ( IID_IUnknown == riid )
  89. *ppvObject = (IUnknown *)(IClassFactory *)this;
  90. else
  91. sc = E_NOINTERFACE;
  92. if ( SUCCEEDED( sc ) )
  93. AddRef();
  94. return sc;
  95. } //QueryInterface
  96. //+-------------------------------------------------------------------------
  97. //
  98. // Method: CSimpleCommandCreator::AddRef, public
  99. //
  100. // Synopsis: Increments refcount
  101. //
  102. // History: 13-May-1997 KrishnaN Created
  103. //
  104. //--------------------------------------------------------------------------
  105. ULONG STDMETHODCALLTYPE CSimpleCommandCreator::AddRef()
  106. {
  107. return InterlockedIncrement( &_cRefs );
  108. }
  109. //+-------------------------------------------------------------------------
  110. //
  111. // Method: CSimpleCommandCreator::Release, public
  112. //
  113. // Synopsis: Decrement refcount. Delete if necessary.
  114. //
  115. // History: 13-May-1997 KrishnaN Created
  116. //
  117. //--------------------------------------------------------------------------
  118. ULONG STDMETHODCALLTYPE CSimpleCommandCreator::Release()
  119. {
  120. unsigned long uTmp = InterlockedDecrement( &_cRefs );
  121. if ( 0 == uTmp )
  122. delete this;
  123. return(uTmp);
  124. }
  125. //+-------------------------------------------------------------------------
  126. //
  127. // Method: CSimpleCommandCreator::CreateInstance, public
  128. //
  129. // Synopsis: Creates new CSimpleCommandCreator object
  130. //
  131. // Arguments: [pOuterUnk] -- 'Outer' IUnknown
  132. // [riid] -- Interface to bind
  133. // [ppvObject] -- Interface returned here
  134. //
  135. // History: 13-May-1997 KrishnaN Created
  136. //
  137. //--------------------------------------------------------------------------
  138. SCODE STDMETHODCALLTYPE CSimpleCommandCreator::CreateInstance( IUnknown * pOuterUnk,
  139. REFIID riid,
  140. void * * ppvObject )
  141. {
  142. return QueryInterface( riid, ppvObject );
  143. }
  144. //+-------------------------------------------------------------------------
  145. //
  146. // Method: CSimpleCommandCreator::LockServer, public
  147. //
  148. // Synopsis: Force class factory to remain loaded
  149. //
  150. // Arguments: [fLock] -- TRUE if locking, FALSE if unlocking
  151. //
  152. // Returns: S_OK
  153. //
  154. // History: 13-May-1997 KrishnaN Created
  155. //
  156. //--------------------------------------------------------------------------
  157. SCODE STDMETHODCALLTYPE CSimpleCommandCreator::LockServer(BOOL fLock)
  158. {
  159. if(fLock)
  160. InterlockedIncrement( &gulcInstances );
  161. else
  162. InterlockedDecrement( &gulcInstances );
  163. return(S_OK);
  164. }
  165. //+-------------------------------------------------------------------------
  166. //
  167. // Method: CSimpleCommandCreator::CreateICommand, public
  168. //
  169. // Synopsis: Creates a ICommand.
  170. //
  171. // Arguments: [ppUnknown] -- Returns the IUnknown for the command
  172. // [pOuterUnk] -- (optional) outer unknown pointer
  173. //
  174. // History: 13-May-1997 KrishnaN Created
  175. // 29-May-1997 EmilyB Added aggregation support, so now
  176. // returns IUnknown ptr and caller
  177. // must now call QI to get ICommand ptr
  178. //
  179. //--------------------------------------------------------------------------
  180. SCODE STDMETHODCALLTYPE CSimpleCommandCreator::CreateICommand( IUnknown ** ppUnknown,
  181. IUnknown * pOuterUnk )
  182. {
  183. if ( 0 == ppUnknown )
  184. return E_INVALIDARG;
  185. SCODE sc = S_OK;
  186. *ppUnknown = 0;
  187. CQuerySpec * pQuery = 0;
  188. TRANSLATE_EXCEPTIONS;
  189. TRY
  190. {
  191. pQuery = new CQuerySpec( 0, ppUnknown );
  192. }
  193. CATCH(CException, e)
  194. {
  195. Win4Assert(0 == pQuery);
  196. sc = e.GetErrorCode();
  197. }
  198. END_CATCH
  199. UNTRANSLATE_EXCEPTIONS;
  200. return sc;
  201. }
  202. //+---------------------------------------------------------------------------
  203. //
  204. // Member: CSimpleCommandCreator::VerifyCatalog, public
  205. //
  206. // Synopsis: Validate catalog location
  207. //
  208. // Arguments: [pwszMachine] -- Machine on which catalog exists
  209. // [pwszCatalogName] -- Catalog Name
  210. //
  211. // Returns: S_OK if catalog is accessible, various errors otherwise.
  212. //
  213. // History: 22-Jul-97 KyleP Created
  214. //
  215. //----------------------------------------------------------------------------
  216. SCODE STDMETHODCALLTYPE CSimpleCommandCreator::VerifyCatalog(
  217. WCHAR const * pwszMachine,
  218. WCHAR const * pwszCatalogName )
  219. {
  220. // Verify that we have legal parameters
  221. if ( 0 == pwszMachine ||
  222. 0 == pwszCatalogName )
  223. return E_INVALIDARG;
  224. SCODE status = S_OK;
  225. TRANSLATE_EXCEPTIONS;
  226. TRY
  227. {
  228. // Just try to connect to the catalog. We don't actually need to
  229. // do anything!
  230. XInterface<IDBProperties> xDbProps( CreateDbProperties( pwszCatalogName,
  231. pwszMachine ) );
  232. CSvcCatProxy cat( pwszMachine, xDbProps.GetPointer() );
  233. }
  234. CATCH( CException, e )
  235. {
  236. status = ProxyErrorToCIError( e );
  237. }
  238. END_CATCH
  239. UNTRANSLATE_EXCEPTIONS;
  240. return status;
  241. }
  242. //+---------------------------------------------------------------------------
  243. //
  244. // Member: CSimpleCommandCreator::GetDefaultCatalog, public
  245. //
  246. // Synopsis: Determine 'default' catalog for system
  247. //
  248. // Arguments: [pwszCatalogName] -- Catalog Name
  249. // [cwcIn] -- Size in characters of [pwszCatalogName]
  250. // [pcwcOut] -- Size of catalog name
  251. //
  252. // Returns: Contents of IsapiDefaultCatalogDirectory registry value.
  253. //
  254. // History: 22-Jul-97 KyleP Created
  255. //
  256. //----------------------------------------------------------------------------
  257. CStaticMutexSem g_mtxCommandCreator;
  258. SCODE STDMETHODCALLTYPE CSimpleCommandCreator::GetDefaultCatalog(
  259. WCHAR * pwszCatalogName,
  260. ULONG cwcIn,
  261. ULONG * pcwcOut )
  262. {
  263. SCODE sc = S_OK;
  264. TRANSLATE_EXCEPTIONS;
  265. TRY
  266. {
  267. *pcwcOut = 0;
  268. if ( xDefaultCatalogValue.IsNull() )
  269. {
  270. CLock lock(g_mtxCommandCreator);
  271. if ( xDefaultCatalogValue.IsNull() )
  272. xDefaultCatalogValue.Set( new CRegAutoStringValue(
  273. wcsRegAdminTree,
  274. wcsISDefaultCatalogDirectory,
  275. L"system" ) );
  276. }
  277. *pcwcOut = xDefaultCatalogValue->Get( pwszCatalogName, cwcIn );
  278. }
  279. CATCH(CException, e)
  280. {
  281. sc = e.GetErrorCode();
  282. }
  283. END_CATCH
  284. UNTRANSLATE_EXCEPTIONS;
  285. return sc;
  286. }
  287. // IColumnMapperCreator methods
  288. //+-------------------------------------------------------------------------
  289. //
  290. // Method: CSimpleCommandCreator::GetColumnMapper, public
  291. //
  292. // Synopsis: Retrieves a column mapper object.
  293. //
  294. // Arguments: [wcsMachineName] -- Machine on which the catalog exists
  295. // [wcsCatalogName] -- Catalog for which col. mapper is requested
  296. // [ppColumnMapper] -- Stores the outgoing column mapper ptr
  297. //
  298. // History: 26-Aug-1997 KrishnaN Created
  299. //
  300. //--------------------------------------------------------------------------
  301. const short StaticPropList = 0;
  302. const short DynamicPropList = 1;
  303. SCODE STDMETHODCALLTYPE CSimpleCommandCreator::GetColumnMapper
  304. ( WCHAR const *wcsMachineName,
  305. WCHAR const *wcsCatalogName,
  306. IColumnMapper **ppColumnMapper )
  307. {
  308. if (0 == ppColumnMapper || 0 == wcsCatalogName)
  309. return E_INVALIDARG;
  310. //
  311. // We currently only understand "." or NULL for machine name. Both
  312. // map to the local machine.
  313. // We currently only understand constant SYSTEM_DEFAULT_CAT for catalog
  314. // name. Any catalog name other than this will cause the dynamic list
  315. // to be returned.
  316. //
  317. // Optimize a bit, avoid wcscmp more than once for the same name
  318. short sCatUsed = DynamicPropList;
  319. if ( 0 == wcscmp(wcsCatalogName, SYSTEM_DEFAULT_CAT) )
  320. sCatUsed = StaticPropList;
  321. if (wcsMachineName && 0 != wcscmp(wcsMachineName, LOCAL_MACHINE))
  322. return E_INVALIDARG;
  323. SCODE sc = S_OK;
  324. *ppColumnMapper = 0;
  325. TRANSLATE_EXCEPTIONS;
  326. TRY
  327. {
  328. if (DynamicPropList == sCatUsed)
  329. {
  330. // return the file based property list
  331. *ppColumnMapper = GetGlobalPropListFile();
  332. }
  333. else
  334. {
  335. // return the static default property list
  336. Win4Assert(StaticPropList == sCatUsed);
  337. *ppColumnMapper = GetGlobalStaticPropertyList();
  338. }
  339. }
  340. CATCH(CException, e)
  341. {
  342. sc = e.GetErrorCode();
  343. }
  344. END_CATCH
  345. UNTRANSLATE_EXCEPTIONS;
  346. return sc;
  347. }
  348. //+---------------------------------------------------------------------------
  349. //
  350. // Function: MakeICommand
  351. //
  352. // Synopsis: Instantiates an ICommand
  353. //
  354. // Arguments: [ppUnknown] -- Returns the IUnknown for the command
  355. // [wcsCat] -- catalog name
  356. // [wcsMachine] -- machine name
  357. // [pOuterUnk] -- (optional) outer unknown pointer
  358. //
  359. // Returns: SCODE result of the operation
  360. //
  361. // History: 21-Feb-96 SitaramR Created header
  362. // 28-Feb-97 KyleP Scope to command properties
  363. // 29-May-97 EmilyB Added aggregation support, so now
  364. // returns IUnknown ptr and caller
  365. // must now call QI to get ICommand ptr
  366. //
  367. //----------------------------------------------------------------------------
  368. SCODE MakeICommand( IUnknown ** ppUnknown,
  369. WCHAR const * wcsCat,
  370. WCHAR const * wcsMachine,
  371. IUnknown * pOuterUnk )
  372. {
  373. //
  374. // don't allow setting of catalog/machine here,
  375. // Call SetScopeProperties after MakeICommand to set properties.
  376. // maintain this declaration for indexsrv compatibility.
  377. //
  378. Win4Assert( wcsCat == 0 && wcsMachine == 0 );
  379. //
  380. // Check for invalid parameters
  381. //
  382. if ( 0 == ppUnknown )
  383. return E_INVALIDARG;
  384. *ppUnknown = 0;
  385. CQuerySpec * pQuery = 0;
  386. SCODE sc = S_OK;
  387. TRANSLATE_EXCEPTIONS;
  388. TRY
  389. {
  390. // pUnknown is modified if CQuerySpec's constructor throws!
  391. IUnknown * pUnknown = 0;
  392. pQuery = new CQuerySpec( pOuterUnk, &pUnknown );
  393. *ppUnknown = pUnknown;
  394. }
  395. CATCH( CException, e )
  396. {
  397. Win4Assert(0 == pQuery);
  398. sc = e.GetErrorCode();
  399. }
  400. END_CATCH
  401. UNTRANSLATE_EXCEPTIONS;
  402. return sc;
  403. } //MakeIQuery
  404. //+---------------------------------------------------------------------------
  405. //
  406. // Function: MakeLocalICommand
  407. //
  408. // Synopsis: Instantiates an ICommand on the local machine and with
  409. // the given doc store.
  410. //
  411. // Arguments: [ppUnknown] -- Returns the IUnknown for the command
  412. // [pDocStore] -- Doc store
  413. // [pOuterUnk] -- (optional) outer unknown pointer
  414. //
  415. // Returns: SCODE result of the operation
  416. //
  417. // History: 23-Apr-97 KrishnaN Created
  418. // 29-May-97 EmilyB Added aggregation support, so now
  419. // returns IUnknown ptr and caller
  420. // must now call QI to get ICommand ptr
  421. //
  422. //----------------------------------------------------------------------------
  423. SCODE MakeLocalICommand( IUnknown ** ppUnknown,
  424. ICiCDocStore * pDocStore,
  425. IUnknown * pOuterUnk)
  426. {
  427. //
  428. // Check for invalid parameters
  429. //
  430. if ( 0 == ppUnknown || 0 == pDocStore )
  431. return E_INVALIDARG;
  432. *ppUnknown = 0;
  433. CQuerySpec * pQuery = 0;
  434. SCODE sc = S_OK;
  435. TRANSLATE_EXCEPTIONS;
  436. TRY
  437. {
  438. // pUnknown is modified if CQuerySpec's constructor throws!
  439. IUnknown * pUnknown = 0;
  440. pQuery = new CQuerySpec( pOuterUnk, &pUnknown, pDocStore );
  441. *ppUnknown = pUnknown;
  442. }
  443. CATCH( CException, e )
  444. {
  445. Win4Assert(0 == pQuery);
  446. sc = e.GetErrorCode();
  447. }
  448. END_CATCH
  449. UNTRANSLATE_EXCEPTIONS;
  450. return sc;
  451. } //MakeLocalICommand
  452. //+---------------------------------------------------------------------------
  453. //
  454. // Function: GetSimpleCommandCreatorCF, public
  455. //
  456. // Synopsis: Returns SimpleCommandCreatorCF.
  457. //
  458. // Returns: IClassFactory. Can throw exceptions.
  459. //
  460. // History: 14-May-97 KrishnaN Created
  461. //
  462. // Note: Used to avoid having to include stdqspec.hxx
  463. // into the file exposing the class factory. That
  464. // requires having to include a whole lot of files.
  465. //
  466. //----------------------------------------------------------------------------
  467. IClassFactory * GetSimpleCommandCreatorCF()
  468. {
  469. return ((IClassFactory *)new CSimpleCommandCreator);
  470. }