Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2495 lines
80 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-2000.
  5. //
  6. // File: Catalog.cxx
  7. //
  8. // Contents: Used to manage catalog(s) state
  9. //
  10. // History: 27-Nov-1996 KyleP Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include <params.hxx>
  16. #include <ciregkey.hxx>
  17. #include <snapin.hxx>
  18. #include <catalog.hxx>
  19. #include <catadmin.hxx>
  20. #include <CIARes.h>
  21. #include <callback.hxx>
  22. #include <fsciexps.hxx>
  23. CDynArrayInPlace<CCatalogs *> gapCats;
  24. CDynArrayInPlace<UINT_PTR> gaTimerIds;
  25. UINT gsIndex = 0;
  26. UINT gcMaxCats = 0;
  27. CStaticMutexSem gmtxTimer;
  28. const cRefreshDelay = 5000;
  29. //
  30. // Global data
  31. //
  32. SCatalogColumn coldefCatalog[] = { { CCatalog::GetCat, MSG_COL_CATNAME },
  33. { CCatalog::GetDrive, MSG_COL_DRIVE },
  34. { CCatalog::GetSize, MSG_COL_SIZE },
  35. { CCatalog::GetDocs, MSG_COL_DOCTOTAL },
  36. { CCatalog::GetDocsToFilter, MSG_COL_DOCFILTER },
  37. { CCatalog::GetSecQDocuments, MSG_COL_SECQDOCUMENTS },
  38. { CCatalog::GetWordlists, MSG_COL_WORDLISTS },
  39. { CCatalog::GetPersIndex, MSG_COL_PERSINDEX },
  40. { CCatalog::GetStatus, MSG_COL_STATUS }
  41. };
  42. const unsigned cColDefCatalog = sizeof(coldefCatalog) / sizeof(coldefCatalog[0]);
  43. //
  44. // Static command tree to fetch property metadata.
  45. //
  46. // NOTE: There are some funny casts below, because of the requirement to
  47. // statically initialize a union.
  48. //
  49. const DBID dbcolGuid = { { 0x624c9360, 0x93d0, 0x11cf, 0xa7, 0x87, 0x00, 0x00, 0x4c, 0x75, 0x27, 0x52 },
  50. DBKIND_GUID_PROPID,
  51. (LPWSTR)5 };
  52. const DBID dbcolPropDispid = { { 0x624c9360, 0x93d0, 0x11cf, 0xa7, 0x87, 0x00, 0x00, 0x4c, 0x75, 0x27, 0x52 },
  53. DBKIND_GUID_PROPID,
  54. (LPWSTR)6 };
  55. const DBID dbcolPropName = { { 0x624c9360, 0x93d0, 0x11cf, 0xa7, 0x87, 0x00, 0x00, 0x4c, 0x75, 0x27, 0x52 },
  56. DBKIND_GUID_PROPID,
  57. (LPWSTR)7 };
  58. const DBID dbcolPropLevel = { { 0x624c9360, 0x93d0, 0x11cf, 0xa7, 0x87, 0x00, 0x00, 0x4c, 0x75, 0x27, 0x52 },
  59. DBKIND_GUID_PROPID,
  60. (LPWSTR)8 };
  61. const DBID dbcolPropDataModifiable = { { 0x624c9360, 0x93d0, 0x11cf, 0xa7, 0x87, 0x00, 0x00, 0x4c, 0x75, 0x27, 0x52 },
  62. DBKIND_GUID_PROPID,
  63. (LPWSTR)9 };
  64. const DBID dbcolPropType = { { 0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac },
  65. DBKIND_GUID_PROPID,
  66. (LPWSTR)4 };
  67. const DBID dbcolSize = { { 0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac },
  68. DBKIND_GUID_PROPID,
  69. (LPWSTR)12 };
  70. const DBID dbcolPath = { { 0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac },
  71. DBKIND_GUID_PROPID,
  72. (LPWSTR)11 };
  73. //
  74. // This is just like PROPVARIANT, but w/o all the arms. Lets you statically
  75. // assign a VT_CLSID.
  76. //
  77. struct tag_Kyle_PROPVARIANT
  78. {
  79. VARTYPE vt;
  80. PROPVAR_PAD1 wReserved1;
  81. PROPVAR_PAD2 wReserved2;
  82. PROPVAR_PAD3 wReserved3;
  83. CLSID __RPC_FAR *puuid;
  84. };
  85. GUID psguidStorage = PSGUID_STORAGE;
  86. tag_Kyle_PROPVARIANT stVar = { VT_CLSID, 0, 0, 0, &psguidStorage };
  87. //CStorageVariant stVar((CLSID *)&psguidStorage);
  88. //
  89. // Columns
  90. //
  91. DBCOMMANDTREE dbcmdColumnPath = { DBOP_column_name, DBVALUEKIND_ID, 0, 0, (ULONG_PTR)&dbcolPath, S_OK };
  92. DBCOMMANDTREE dbcmdColumnGuid = { DBOP_column_name, DBVALUEKIND_ID, 0, 0, (ULONG_PTR)&dbcolGuid, S_OK };
  93. DBCOMMANDTREE dbcmdColumnPropDispid = { DBOP_column_name, DBVALUEKIND_ID, 0, 0, (ULONG_PTR)&dbcolPropDispid, S_OK };
  94. DBCOMMANDTREE dbcmdColumnPropName = { DBOP_column_name, DBVALUEKIND_ID, 0, 0, (ULONG_PTR)&dbcolPropName, S_OK };
  95. DBCOMMANDTREE dbcmdColumnPropType = { DBOP_column_name, DBVALUEKIND_ID, 0, 0, (ULONG_PTR)&dbcolPropType, S_OK };
  96. DBCOMMANDTREE dbcmdColumnSize = { DBOP_column_name, DBVALUEKIND_ID, 0, 0, (ULONG_PTR)&dbcolSize, S_OK };
  97. DBCOMMANDTREE dbcmdColumnStoreLevel = { DBOP_column_name, DBVALUEKIND_ID, 0, 0, (ULONG_PTR)&dbcolPropLevel, S_OK };
  98. DBCOMMANDTREE dbcmdColumnModifiable = { DBOP_column_name, DBVALUEKIND_ID, 0, 0, (ULONG_PTR)&dbcolPropDataModifiable, S_OK };
  99. //
  100. // Forward declare a few nodes to make linking easy
  101. //
  102. extern DBCOMMANDTREE dbcmdSortListAnchor;
  103. extern DBCOMMANDTREE dbcmdProjectListAnchor;
  104. //
  105. // Select NOT (guid == PSGUID_STORAGE AND dispid == 19) ; everything but CONTENTS property
  106. //
  107. // the guid == psguid_storage clause
  108. DBCOMMANDTREE dbcmdGuidStorage = { DBOP_scalar_constant,
  109. DBVALUEKIND_VARIANT,
  110. 0,
  111. 0,
  112. (ULONG_PTR)&stVar,
  113. S_OK };
  114. DBCOMMANDTREE dbcmdColumnGuid2 = { DBOP_column_name,
  115. DBVALUEKIND_ID,
  116. 0,
  117. &dbcmdGuidStorage,
  118. (ULONG_PTR)&dbcolGuid,
  119. S_OK };
  120. DBCOMMANDTREE dbcmdEqual = { DBOP_equal,
  121. DBVALUEKIND_I4,
  122. &dbcmdColumnGuid2,
  123. 0,
  124. 0,
  125. S_OK };
  126. // the dispid == 19 clause
  127. DBCOMMANDTREE dbcmdContentsId = { DBOP_scalar_constant,
  128. DBVALUEKIND_UI4,
  129. 0,
  130. 0,
  131. 19,
  132. S_OK };
  133. DBCOMMANDTREE dbcmdColumnDispid = { DBOP_column_name,
  134. DBVALUEKIND_ID,
  135. 0,
  136. &dbcmdContentsId,
  137. (ULONG_PTR)&dbcolPropDispid,
  138. S_OK };
  139. DBCOMMANDTREE dbcmdEqual2 = { DBOP_equal,
  140. DBVALUEKIND_I4,
  141. &dbcmdColumnDispid,
  142. &dbcmdEqual,
  143. 0,
  144. S_OK };
  145. // the and node between the above two clauses
  146. DBCOMMANDTREE dbcmdAnd = { DBOP_and,
  147. DBVALUEKIND_I4,
  148. &dbcmdEqual2,
  149. 0,
  150. 0,
  151. S_OK };
  152. // the not in front of the above node
  153. DBCOMMANDTREE dbcmdNot = { DBOP_not,
  154. DBVALUEKIND_I4,
  155. &dbcmdAnd,
  156. 0,
  157. 0,
  158. S_OK };
  159. WCHAR wszTable[] = L"Table";
  160. DBCOMMANDTREE dbcmdTable = { DBOP_table_name,
  161. DBVALUEKIND_WSTR,
  162. 0,
  163. &dbcmdNot,
  164. (ULONG_PTR)&wszTable[0],
  165. S_OK };
  166. DBCOMMANDTREE dbcmdSelect = { DBOP_select,
  167. DBVALUEKIND_EMPTY,
  168. &dbcmdTable,
  169. &dbcmdProjectListAnchor,
  170. 0,
  171. S_OK };
  172. //
  173. // Project (Path, GUID, ...)
  174. //
  175. // NOTE: The order here defines the ordinals of columns.
  176. // The first one here is the last entry in the
  177. // column list, as it is the last child in the
  178. // projection list command tree.
  179. //
  180. DBCOMMANDTREE dbcmdProjectModifiable = { DBOP_project_list_element,
  181. DBVALUEKIND_EMPTY,
  182. &dbcmdColumnModifiable,
  183. 0,
  184. 0,
  185. S_OK };
  186. DBCOMMANDTREE dbcmdProjectStoreLevel = { DBOP_project_list_element,
  187. DBVALUEKIND_EMPTY,
  188. &dbcmdColumnStoreLevel,
  189. &dbcmdProjectModifiable,
  190. 0,
  191. S_OK };
  192. DBCOMMANDTREE dbcmdProjectSize = { DBOP_project_list_element,
  193. DBVALUEKIND_EMPTY,
  194. &dbcmdColumnSize,
  195. &dbcmdProjectStoreLevel,
  196. 0,
  197. S_OK };
  198. DBCOMMANDTREE dbcmdProjectPropType = { DBOP_project_list_element,
  199. DBVALUEKIND_EMPTY,
  200. &dbcmdColumnPropType,
  201. &dbcmdProjectSize,
  202. 0,
  203. S_OK };
  204. DBCOMMANDTREE dbcmdProjectPropName = { DBOP_project_list_element,
  205. DBVALUEKIND_EMPTY,
  206. &dbcmdColumnPropName,
  207. &dbcmdProjectPropType,
  208. 0,
  209. S_OK };
  210. DBCOMMANDTREE dbcmdProjectPropDispid = { DBOP_project_list_element,
  211. DBVALUEKIND_EMPTY,
  212. &dbcmdColumnPropDispid,
  213. &dbcmdProjectPropName,
  214. 0,
  215. S_OK };
  216. DBCOMMANDTREE dbcmdProjectGuid = { DBOP_project_list_element,
  217. DBVALUEKIND_EMPTY,
  218. &dbcmdColumnGuid,
  219. &dbcmdProjectPropDispid,
  220. 0,
  221. S_OK };
  222. DBCOMMANDTREE dbcmdProjectListAnchor = { DBOP_project_list_anchor,
  223. DBVALUEKIND_EMPTY,
  224. &dbcmdProjectGuid,
  225. 0,
  226. 0,
  227. S_OK };
  228. DBCOMMANDTREE dbcmdProject = { DBOP_project,
  229. DBVALUEKIND_EMPTY,
  230. &dbcmdSelect,
  231. &dbcmdSortListAnchor,
  232. 0,
  233. S_OK };
  234. //
  235. // Sort (Ascending by GUID)
  236. //
  237. DBSORTINFO dbsortAscending = { FALSE, LOCALE_NEUTRAL };
  238. DBCOMMANDTREE dbcmdSortByGuid = { DBOP_sort_list_element,
  239. DBVALUEKIND_SORTINFO,
  240. &dbcmdColumnGuid,
  241. 0,
  242. (ULONG_PTR)&dbsortAscending,
  243. S_OK };
  244. DBCOMMANDTREE dbcmdSortListAnchor = { DBOP_sort_list_anchor,
  245. DBVALUEKIND_EMPTY,
  246. &dbcmdSortByGuid,
  247. 0,
  248. 0,
  249. S_OK };
  250. DBCOMMANDTREE dbcmdSort = { DBOP_sort,
  251. DBVALUEKIND_EMPTY,
  252. &dbcmdProject,
  253. 0,
  254. 0,
  255. S_OK };
  256. //
  257. // Static set of bindings for fetching property info.
  258. //
  259. struct SPropInfo
  260. {
  261. GUID guidPropertySet;
  262. PROPID propid;
  263. ULONG statusPropid;
  264. WCHAR * pwcsName;
  265. ULONG statusName;
  266. ULONG type;
  267. ULONGLONG size;
  268. DWORD level;
  269. VARIANT_BOOL fModifiable;
  270. };
  271. DBBINDING abindPropInfo[] = { { 1, // Ordinal
  272. (ULONG) (ULONG_PTR)&((SPropInfo *)0)->guidPropertySet, // Value offset
  273. 0, // Length offset
  274. 0, // Status offset
  275. 0, // Typeinfo
  276. 0, // Object
  277. 0, // BindExt
  278. DBPART_VALUE, // Fetch value
  279. DBMEMOWNER_CLIENTOWNED, // Client owned memory
  280. DBPARAMIO_NOTPARAM, // Not a parameter
  281. sizeof( ((SPropInfo *)0)->guidPropertySet ),// Value length
  282. 0, // Flags
  283. VT_CLSID, // Datatype expected
  284. 0, // Precision (unused)
  285. 0 }, // Scale (unused)
  286. { 2, // Ordinal
  287. (ULONG) (ULONG_PTR)&((SPropInfo *)0)->propid, // Value offset
  288. 0, // Length offset
  289. (ULONG) (ULONG_PTR)&((SPropInfo *)0)->statusPropid, // Status offset
  290. 0, // Typeinfo
  291. 0, // Object
  292. 0, // BindExt
  293. DBPART_VALUE | DBPART_STATUS, // Fetch value
  294. DBMEMOWNER_CLIENTOWNED, // Client owned memory
  295. DBPARAMIO_NOTPARAM, // Not a parameter
  296. sizeof( ((SPropInfo *)0)->propid ), // Value length
  297. 0, // Flags
  298. DBTYPE_I4, // Datatype expected
  299. 0, // Precision (unused)
  300. 0 }, // Scale (unused)
  301. { 3, // Ordinal
  302. (ULONG) (ULONG_PTR)&((SPropInfo *)0)->pwcsName, // Value offset
  303. 0, // Length offset
  304. (ULONG) (ULONG_PTR)&((SPropInfo *)0)->statusName, // Status offset
  305. 0, // Typeinfo
  306. 0, // Object
  307. 0, // BindExt
  308. DBPART_VALUE | DBPART_STATUS, // Fetch value
  309. DBMEMOWNER_PROVIDEROWNED, // Client owned memory
  310. DBPARAMIO_NOTPARAM, // Not a parameter
  311. sizeof( ((SPropInfo *)0)->pwcsName ), // Value length
  312. 0, // Flags
  313. DBTYPE_WSTR | DBTYPE_BYREF, // Datatype expected
  314. 0, // Precision (unused)
  315. 0 }, // Scale (unused)
  316. { 4, // Ordinal
  317. (ULONG) (ULONG_PTR)&((SPropInfo *)0)->type, // Value offset
  318. 0, // Length offset
  319. 0, // Status offset
  320. 0, // Typeinfo
  321. 0, // Object
  322. 0, // BindExt
  323. DBPART_VALUE, // Fetch value
  324. DBMEMOWNER_CLIENTOWNED, // Client owned memory
  325. DBPARAMIO_NOTPARAM, // Not a parameter
  326. sizeof( ((SPropInfo *)0)->type ), // Value length
  327. 0, // Flags
  328. DBTYPE_UI4, // Datatype expected
  329. 0, // Precision (unused)
  330. 0 }, // Scale (unused)
  331. { 5, // Ordinal
  332. (ULONG) (ULONG_PTR)&((SPropInfo *)0)->size, // Value offset
  333. 0, // Length offset
  334. 0, // Status offset
  335. 0, // Typeinfo
  336. 0, // Object
  337. 0, // BindExt
  338. DBPART_VALUE, // Fetch value
  339. DBMEMOWNER_CLIENTOWNED, // Client owned memory
  340. DBPARAMIO_NOTPARAM, // Not a parameter
  341. sizeof( ((SPropInfo *)0)->size ), // Value length
  342. 0, // Flags
  343. DBTYPE_I8, // Datatype expected
  344. 0, // Precision (unused)
  345. 0 }, // Scale (unused)
  346. { 6, // Ordinal
  347. (ULONG) (ULONG_PTR)&((SPropInfo *)0)->level, // Value offset
  348. 0, // Length offset
  349. 0, // Status offset
  350. 0, // Typeinfo
  351. 0, // Object
  352. 0, // BindExt
  353. DBPART_VALUE, // Fetch value
  354. DBMEMOWNER_CLIENTOWNED, // Client owned memory
  355. DBPARAMIO_NOTPARAM, // Not a parameter
  356. sizeof( ((SPropInfo *)0)->level ), // Value length
  357. 0, // Flags
  358. DBTYPE_UI4, // Datatype expected
  359. 0, // Precision (unused)
  360. 0 },
  361. { 7, // Ordinal
  362. (ULONG) (ULONG_PTR)&((SPropInfo *)0)->fModifiable, // Value offset
  363. 0, // Length offset
  364. 0, // Status offset
  365. 0, // Typeinfo
  366. 0, // Object
  367. 0, // BindExt
  368. DBPART_VALUE, // Fetch value
  369. DBMEMOWNER_CLIENTOWNED, // Client owned memory
  370. DBPARAMIO_NOTPARAM, // Not a parameter
  371. sizeof( ((SPropInfo *)0)->fModifiable ), // Value length
  372. 0, // Flags
  373. DBTYPE_BOOL, // Datatype expected
  374. 0, // Precision (unused)
  375. 0 }};
  376. BOOL CCatalogs::_fFirstTime = TRUE;
  377. CCatalog::CCatalog( CCatalogs & parent, WCHAR const * pwcsCat )
  378. : _idScope( 0 ),
  379. _idResult( 0 ),
  380. _pwcsDrive( 0 ),
  381. _pwcsCat( 0 ),
  382. _parent( parent ),
  383. _fZombie( FALSE ),
  384. #pragma warning( disable : 4355 ) // this used in base initialization
  385. _interScopes( *this, Intermediate_Scope ),
  386. _interProperties( *this, Intermediate_Properties ),
  387. _interUnfiltered( *this, Intermediate_UnfilteredURL )
  388. #pragma warning( default : 4355 )
  389. {
  390. //
  391. // Hack Alert! This will fake ::Update into thinking all the values need to be
  392. // changed.
  393. //
  394. RtlFillMemory( &_state, sizeof(_state), 0xAA );
  395. _state.cbStruct = sizeof(_state);
  396. TRY
  397. {
  398. //
  399. // Initialize string(s)
  400. //
  401. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  402. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( pwcsCat ) );
  403. Set( xCatalogAdmin->GetLocation(), _pwcsDrive );
  404. Set( pwcsCat, _pwcsCat );
  405. _fInactive = xCatalogAdmin->IsCatalogInactive();
  406. Update();
  407. //
  408. // Make sure we think the orignal value is new
  409. //
  410. _fSizeChanged = TRUE;
  411. _fPropCacheSizeChanged = TRUE;
  412. _fDocsChanged = TRUE;
  413. _fDocsToFilterChanged = TRUE;
  414. _fWordlistsChanged = TRUE;
  415. _fPersIndexChanged = TRUE;
  416. _fStatusChanged = TRUE;
  417. _fSecQDocumentsChanged = TRUE;
  418. }
  419. CATCH( CException, e )
  420. {
  421. delete [] _pwcsDrive;
  422. delete [] _pwcsCat;
  423. RETHROW();
  424. }
  425. END_CATCH
  426. }
  427. void CCatalog::InitScopeHeader( CListViewHeader & Header )
  428. {
  429. CScope::InitHeader( Header );
  430. }
  431. void CCatalog::InitPropertyHeader( CListViewHeader & Header )
  432. {
  433. CCachedProperty::InitHeader( Header );
  434. }
  435. CCatalog::~CCatalog()
  436. {
  437. delete [] _pwcsDrive;
  438. delete [] _pwcsCat;
  439. }
  440. SCODE CCatalog::AddScope( WCHAR const * pwszScope,
  441. WCHAR const * pwszAlias,
  442. BOOL fExclude,
  443. WCHAR const * pwszLogon,
  444. WCHAR const * pwszPassword )
  445. {
  446. ciaDebugOut(( DEB_ITRACE,
  447. "CCatalog::AddScope( %ws, %ws, %s, %ws, %ws )\n",
  448. pwszScope,
  449. (0 == pwszAlias) ? L"" : pwszAlias,
  450. fExclude ? "TRUE" : "FALSE",
  451. (0 == pwszLogon) ? L"n/a" : pwszLogon,
  452. (0 == pwszPassword) ? L"n/a" : pwszPassword ));
  453. SCODE sc = S_OK;
  454. TRY
  455. {
  456. //
  457. // First, add to CI.
  458. //
  459. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  460. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  461. xCatalogAdmin->AddScope( pwszScope,
  462. pwszAlias,
  463. fExclude,
  464. pwszLogon,
  465. pwszPassword );
  466. }
  467. CATCH (CException, e)
  468. {
  469. sc = e.GetErrorCode();
  470. }
  471. END_CATCH
  472. return (FAILED(sc) ? sc : S_OK);
  473. }
  474. void CCatalog::RemoveScope( CScope * pScope )
  475. {
  476. SCODE sc = S_OK;
  477. TRY
  478. {
  479. //
  480. // First, remove from CI.
  481. //
  482. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  483. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  484. xCatalogAdmin->RemoveScope( pScope->GetPath() );
  485. }
  486. CATCH (CException, e)
  487. {
  488. sc = e.GetErrorCode();
  489. }
  490. END_CATCH
  491. if (FAILED(sc))
  492. {
  493. // At this point nothing was removed from the registry, so we shouldn't zombify the scope.
  494. return;
  495. }
  496. //
  497. // Then, from display.
  498. //
  499. pScope->Zombify();
  500. }
  501. SCODE CCatalog::ModifyScope( CScope & rScope,
  502. WCHAR const * pwszScope,
  503. WCHAR const * pwszAlias,
  504. BOOL fExclude,
  505. WCHAR const * pwszLogon,
  506. WCHAR const * pwszPassword )
  507. {
  508. ciaDebugOut(( DEB_ITRACE,
  509. "CCatalog::ModifyScope( %ws, %ws, %s, %ws, %ws )\n",
  510. pwszScope,
  511. (0 == pwszAlias) ? L"" : pwszAlias,
  512. fExclude ? "TRUE" : "FALSE",
  513. (0 == pwszLogon) ? L"n/a" : pwszLogon,
  514. (0 == pwszPassword) ? L"n/a" : pwszPassword ));
  515. SCODE sc = S_OK;
  516. TRY
  517. {
  518. //
  519. // First, remove from CI.
  520. //
  521. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  522. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  523. //
  524. // If the path hasn't changed, we should only change properties that have
  525. // changed. If the path has changed, it will cause the value to be deleted
  526. // anyway, so we can remove the scope and add the replacement in one shot.
  527. //
  528. if (0 == _wcsicmp(rScope.GetPath(), pwszScope))
  529. {
  530. XPtr<CScopeAdmin> xScopeAdmin(
  531. xCatalogAdmin->QueryScopeAdmin(rScope.GetPath()) );
  532. xScopeAdmin->SetAlias(pwszAlias);
  533. xScopeAdmin->SetExclude(fExclude);
  534. xScopeAdmin->SetLogonInfo(pwszLogon,
  535. pwszPassword,
  536. xCatalogAdmin.GetReference());
  537. }
  538. else
  539. {
  540. xCatalogAdmin->RemoveScope( rScope.GetPath() );
  541. // Then add the entry to CI
  542. xCatalogAdmin->AddScope( pwszScope,
  543. pwszAlias,
  544. fExclude,
  545. pwszLogon,
  546. pwszPassword );
  547. }
  548. // Then modify the display entry in place
  549. rScope.Modify( pwszScope, pwszAlias, fExclude );
  550. }
  551. CATCH (CException, e)
  552. {
  553. sc = e.GetErrorCode();
  554. }
  555. END_CATCH
  556. return sc;
  557. }
  558. void CCatalog::RescanScope( WCHAR const * pwszScope, BOOL fFull )
  559. {
  560. SCODE sc = UpdateContentIndex ( pwszScope,
  561. _pwcsCat,
  562. _parent.GetMachine(),
  563. fFull );
  564. if ( FAILED(sc) )
  565. {
  566. ciaDebugOut(( DEB_ERROR, "UpdateContentIndex( %ws ) returned 0x%x\n",
  567. pwszScope, sc ));
  568. THROW( CException( sc ) );
  569. }
  570. }
  571. void CCatalog::Merge()
  572. {
  573. SCODE sc = ForceMasterMerge ( L"\\",
  574. _pwcsCat,
  575. _parent.GetMachine() );
  576. if ( FAILED(sc) )
  577. {
  578. ciaDebugOut(( DEB_ERROR, "ForceMasterMerge( %ws ) returned 0x%x\n",
  579. _pwcsCat, sc ));
  580. THROW( CException( sc ) );
  581. }
  582. }
  583. void CCatalog::DisplayIntermediate( IConsoleNameSpace * pScopePane )
  584. {
  585. //
  586. // Now, insert the intermediate nodes.
  587. //
  588. SCOPEDATAITEM item;
  589. RtlZeroMemory( &item, sizeof(item) );
  590. //
  591. // 'Scope'
  592. //
  593. item.mask |= SDI_STR | SDI_IMAGE | SDI_CHILDREN;
  594. item.nImage = ICON_FOLDER;
  595. //item.displayname = (WCHAR *)pCat->GetCat( TRUE );
  596. item.displayname = MMC_CALLBACK;
  597. item.cChildren = 0;
  598. item.mask |= SDI_PARAM;
  599. item.lParam = (LPARAM)GetIntermediateScopeNode();
  600. item.relativeID = ScopeHandle();
  601. ciaDebugOut(( DEB_ITRACE, "Inserting (intermediate) scope item (lParam = 0x%x)\n", item.lParam ));
  602. pScopePane->InsertItem( &item );
  603. //
  604. // 'Properties'
  605. //
  606. item.mask |= SDI_STR | SDI_IMAGE | SDI_CHILDREN;
  607. item.nImage = ICON_FOLDER;
  608. //item.displayname = (WCHAR *)pCat->GetCat( TRUE );
  609. item.displayname = MMC_CALLBACK;
  610. item.cChildren = 0;
  611. item.mask |= SDI_PARAM;
  612. item.lParam = (LPARAM)GetIntermediatePropNode();
  613. item.relativeID = ScopeHandle();
  614. ciaDebugOut(( DEB_ITRACE, "Inserting (intermediate) property item (lParam = 0x%x)\n", item.lParam ));
  615. pScopePane->InsertItem( &item );
  616. //
  617. // Unfiltered query URL
  618. //
  619. item.mask |= SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_CHILDREN;
  620. item.nImage = item.nOpenImage = ICON_URL;
  621. item.displayname = MMC_CALLBACK;
  622. item.cChildren = 0;
  623. item.mask |= SDI_PARAM;
  624. item.lParam = (LPARAM)GetIntermediateUnfilteredNode();
  625. item.relativeID = ScopeHandle();
  626. ciaDebugOut(( DEB_ITRACE, "Inserting (intermediate) URL item (lParam = 0x%x)\n", item.lParam ));
  627. pScopePane->InsertItem( &item );
  628. }
  629. void CCatalog::DisplayScopes( BOOL fFirstTime, IResultData * pResultPane )
  630. {
  631. ciaDebugOut(( DEB_ITRACE, "CCatalog::DisplayScopes (fFirstTime = %d)\n", fFirstTime ));
  632. ClearScopes(pResultPane);
  633. PopulateScopes();
  634. for ( unsigned i = 0; i < _aScope.Count(); i++ )
  635. {
  636. CScope * pScope = _aScope.Get( i );
  637. Win4Assert(!pScope->IsZombie());
  638. //
  639. // All items were freshly enumerated. add them all
  640. //
  641. RESULTDATAITEM item;
  642. RtlZeroMemory( &item, sizeof(item) );
  643. item.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  644. item.nCol = 0;
  645. // item.nImage will be set by ::GetDisplayInfo
  646. pScope->GetDisplayInfo( &item );
  647. item.str = MMC_CALLBACK;
  648. item.lParam = (LPARAM)pScope;
  649. ciaDebugOut(( DEB_ITRACE, "Inserting result item %ws (lParam = 0x%x)\n",
  650. pScope->GetPath(), item.lParam ));
  651. pResultPane->InsertItem( &item );
  652. pScope->SetResultHandle( item.itemID );
  653. }
  654. }
  655. void CCatalog::ClearProperties(IResultData * pResultPane)
  656. {
  657. // Clear out the display list
  658. pResultPane->DeleteAllRsltItems();
  659. // Delete the entries from the property list
  660. _aProperty.Clear();
  661. }
  662. void CCatalog::DisplayProperties( BOOL fFirstTime, IResultData * pResultPane )
  663. {
  664. ciaDebugOut(( DEB_ITRACE, "CCatalog::DisplayProperties (fFirstTime = %d)\n", fFirstTime ));
  665. // If catalog is stopped OR service is stopped, clear the list.
  666. BOOL fStopped = FALSE;
  667. TRY
  668. {
  669. CMachineAdmin MachineAdmin( _parent.IsLocalMachine() ? 0 : _parent.GetMachine() );
  670. XPtr<CCatalogAdmin> xCat( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  671. fStopped = xCat->IsStopped() || MachineAdmin.IsCIStopped();
  672. if (fStopped)
  673. ClearProperties(pResultPane);
  674. }
  675. CATCH( CException, e)
  676. {
  677. // nothing to do
  678. }
  679. END_CATCH
  680. if (fStopped)
  681. return;
  682. if ( fFirstTime )
  683. UpdateProps();
  684. for ( unsigned i = 0; i < _aProperty.Count(); i++ )
  685. {
  686. CCachedProperty * pProperty = _aProperty.Get( i );
  687. if ( pProperty->IsZombie() )
  688. {
  689. pResultPane->DeleteItem( pProperty->ResultHandle(), 0 );
  690. //
  691. // Delete scope and move highest entry down.
  692. //
  693. pProperty = _aProperty.Acquire( i );
  694. delete pProperty;
  695. if ( _aProperty.Count() > 0 && _aProperty.Count() != i )
  696. {
  697. pProperty = _aProperty.Acquire( _aProperty.Count() - 1 );
  698. _aProperty.Add( pProperty, i );
  699. }
  700. continue;
  701. }
  702. if ( fFirstTime || pProperty->IsNew() )
  703. {
  704. //
  705. // Add item
  706. //
  707. RESULTDATAITEM item;
  708. RtlZeroMemory( &item, sizeof(item) );
  709. item.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  710. item.nCol = 0;
  711. pProperty->GetDisplayInfo( &item );
  712. // item.nImage is set from ::GetDisplayInfo
  713. item.str = MMC_CALLBACK;
  714. item.lParam = (LPARAM)pProperty;
  715. ciaDebugOut(( DEB_ITRACE, "Inserting result item %ws (lParam = 0x%x)\n",
  716. pProperty->GetProperty(), item.lParam ));
  717. pResultPane->InsertItem( &item );
  718. pProperty->SetResultHandle( item.itemID );
  719. pProperty->MakeOld();
  720. }
  721. if ( !fFirstTime && !pProperty->IsNew() )
  722. {
  723. if ( !pProperty->IsUnappliedChange() )
  724. {
  725. //
  726. // Set the icon back to normal.
  727. //
  728. RESULTDATAITEM rdi;
  729. RtlZeroMemory(&rdi, sizeof(rdi));
  730. rdi.mask = RDI_IMAGE;
  731. rdi.itemID = pProperty->ResultHandle();
  732. // item.nImage is set from ::GetDisplayInfo
  733. pProperty->GetDisplayInfo( &rdi );
  734. SCODE sc = pResultPane->SetItem( &rdi );
  735. }
  736. }
  737. }
  738. }
  739. void CCatalog::GetGeneration( BOOL & fFilterUnknown,
  740. BOOL & fGenerateCharacterization,
  741. ULONG & ccCharacterization )
  742. {
  743. // Caller will deal with exceptions.
  744. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  745. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  746. DWORD dw;
  747. //
  748. // Filter Unknown
  749. //
  750. if ( !xCatalogAdmin->GetDWORDParam( wcsFilterFilesWithUnknownExtensions, dw ) &&
  751. !MachineAdmin.GetDWORDParam( wcsFilterFilesWithUnknownExtensions, dw ) )
  752. dw = CI_FILTER_FILES_WITH_UNKNOWN_EXTENSIONS_DEFAULT;
  753. fFilterUnknown = (0 != dw);
  754. //
  755. // Characterization. We should check if generatecharacterization flag is set to
  756. // TRUE and also check the characterization size. Only when the flag is set to TRUE
  757. // and size > 0, should we generate characterization.
  758. //
  759. DWORD dwGenCharacterization = 0;
  760. if ( !xCatalogAdmin->GetDWORDParam( wcsGenerateCharacterization, dwGenCharacterization ) &&
  761. !MachineAdmin.GetDWORDParam( wcsGenerateCharacterization, dwGenCharacterization ) )
  762. dwGenCharacterization = 1;
  763. if ( !xCatalogAdmin->GetDWORDParam( wcsMaxCharacterization, ccCharacterization ) &&
  764. !MachineAdmin.GetDWORDParam( wcsMaxCharacterization, ccCharacterization ) )
  765. ccCharacterization = CI_MAX_CHARACTERIZATION_DEFAULT;
  766. fGenerateCharacterization = (ccCharacterization > 0) && (0 != dwGenCharacterization);
  767. }
  768. void CCatalog::SetGeneration( BOOL fFilterUnknown,
  769. BOOL fGenerateCharacterization,
  770. ULONG ccCharacterization )
  771. {
  772. //
  773. // fGenerateCharacterization is obsolete.
  774. //
  775. if ( !fGenerateCharacterization )
  776. ccCharacterization = 0;
  777. // Caller will deal with exceptions
  778. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  779. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  780. xCatalogAdmin->SetDWORDParam( wcsFilterFilesWithUnknownExtensions, fFilterUnknown );
  781. xCatalogAdmin->SetDWORDParam( wcsGenerateCharacterization, fGenerateCharacterization );
  782. xCatalogAdmin->SetDWORDParam( wcsMaxCharacterization, ccCharacterization );
  783. }
  784. void CCatalog::GetTracking( BOOL & fAutoAlias )
  785. {
  786. // Caller will deal with exceptions
  787. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  788. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  789. DWORD dw;
  790. if ( !xCatalogAdmin->GetDWORDParam( wcsIsAutoAlias, dw ) &&
  791. !MachineAdmin.GetDWORDParam( wcsIsAutoAlias, dw ) )
  792. dw = CI_IS_AUTO_ALIAS_DEFAULT;
  793. fAutoAlias = (0 != dw);
  794. }
  795. void CCatalog::SetTracking( BOOL fAutoAlias )
  796. {
  797. // Caller will deal with exceptions
  798. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  799. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  800. xCatalogAdmin->SetDWORDParam( wcsIsAutoAlias, fAutoAlias );
  801. }
  802. void CCatalog::GetWeb( BOOL & fVirtualRoots,
  803. BOOL & fNNTPRoots,
  804. ULONG & iVirtualServer,
  805. ULONG & iNNTPServer )
  806. {
  807. // Caller will deal with exceptions
  808. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  809. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  810. DWORD dw;
  811. //
  812. // Filter Virtual Roots
  813. //
  814. if ( !xCatalogAdmin->GetDWORDParam( wcsIsIndexingW3Roots, dw ) &&
  815. !MachineAdmin.GetDWORDParam( wcsIsIndexingW3Roots, dw ) )
  816. dw = CI_IS_INDEXING_W3_ROOTS_DEFAULT;
  817. fVirtualRoots = (0 != dw);
  818. //
  819. // Filter NNTP Roots
  820. //
  821. if ( !xCatalogAdmin->GetDWORDParam( wcsIsIndexingNNTPRoots, dw ) &&
  822. !MachineAdmin.GetDWORDParam( wcsIsIndexingNNTPRoots, dw ) )
  823. dw = CI_IS_INDEXING_NNTP_ROOTS_DEFAULT;
  824. fNNTPRoots = (0 != dw);
  825. //
  826. // Virtual server
  827. //
  828. if ( !xCatalogAdmin->GetDWORDParam( wcsW3SvcInstance, iVirtualServer ) &&
  829. !MachineAdmin.GetDWORDParam( wcsW3SvcInstance, iVirtualServer ) )
  830. iVirtualServer = CI_W3SVC_INSTANCE_DEFAULT;
  831. //
  832. // NNTP Virtual server
  833. //
  834. if ( !xCatalogAdmin->GetDWORDParam( wcsNNTPSvcInstance, iNNTPServer ) &&
  835. !MachineAdmin.GetDWORDParam( wcsNNTPSvcInstance, iNNTPServer ) )
  836. iNNTPServer = CI_NNTPSVC_INSTANCE_DEFAULT;
  837. }
  838. void CCatalog::SetWeb( BOOL fVirtualRoots,
  839. BOOL fNNTPRoots,
  840. ULONG iVirtualServer,
  841. ULONG iNNTPServer )
  842. {
  843. // Caller will deal with exceptions
  844. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  845. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  846. xCatalogAdmin->SetDWORDParam( wcsIsIndexingW3Roots, fVirtualRoots );
  847. xCatalogAdmin->SetDWORDParam( wcsIsIndexingNNTPRoots, fNNTPRoots );
  848. xCatalogAdmin->SetDWORDParam( wcsW3SvcInstance, iVirtualServer );
  849. xCatalogAdmin->SetDWORDParam( wcsNNTPSvcInstance, iNNTPServer );
  850. }
  851. void CCatalog::UpdateCachedProperty(CCachedProperty *pProperty)
  852. {
  853. TRY
  854. {
  855. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  856. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin(GetCat(TRUE)) );
  857. Win4Assert(pProperty->IsUnappliedChange() );
  858. xCatalogAdmin->AddCachedProperty( *((CFullPropSpec const *)pProperty->GetFullPropspec()),
  859. pProperty->GetVT(),
  860. pProperty->Allocation(),
  861. pProperty->StoreLevel(),
  862. pProperty->IsModifiable());
  863. pProperty->ClearUnappliedChange();
  864. }
  865. CATCH(CException, e)
  866. {
  867. ULONG cc = wcslen(pProperty->GetPropSet());
  868. cc++;
  869. cc += wcslen(pProperty->GetProperty());
  870. cc++;
  871. XGrowable<WCHAR> xPropDescription(cc);
  872. wcscpy(xPropDescription.Get(), pProperty->GetPropSet());
  873. wcscat(xPropDescription.Get(), L" ");
  874. wcscat(xPropDescription.Get(), pProperty->GetProperty());
  875. MessageBox(GetFocus(), xPropDescription.Get(),
  876. STRINGRESOURCE( srPropCommitErrorT ), MB_ICONWARNING);
  877. }
  878. END_CATCH
  879. }
  880. void CCatalog::Set( WCHAR const * pwcsSrc, WCHAR * & pwcsDst )
  881. {
  882. if ( 0 == pwcsSrc )
  883. {
  884. pwcsDst = new WCHAR[2];
  885. RtlCopyMemory( pwcsDst, L" ", 2*sizeof(WCHAR) );
  886. }
  887. else
  888. {
  889. unsigned cc = wcslen( pwcsSrc ) + 1;
  890. pwcsDst = new WCHAR [cc];
  891. RtlCopyMemory( pwcsDst, pwcsSrc, cc * sizeof(WCHAR) );
  892. }
  893. }
  894. void CCatalog::Stringize( DWORD dwValue, WCHAR * pwcsDst, unsigned ccDst )
  895. {
  896. //
  897. // GetNumberFormat places additional decimals at the end...
  898. //
  899. #if 0
  900. WCHAR wcTemp[100];
  901. _ultow( dwValue, wcTemp, 10 );
  902. GetNumberFormat( LOCALE_USER_DEFAULT, // Default locale
  903. 0, // Flags
  904. wcTemp, // Input
  905. 0, // More formatting info
  906. pwcsDst, // Output buffer
  907. ccDst ); // Size
  908. #else
  909. _ultow( dwValue, pwcsDst, 10 );
  910. #endif
  911. }
  912. BOOL CCatalog::Update()
  913. {
  914. //
  915. // Get state
  916. //
  917. CI_STATE state;
  918. ULONG ulCacheSizeInKB;
  919. state.cbStruct = sizeof(state);
  920. SCODE sc = CIState( _pwcsCat,
  921. _parent.GetMachine(),
  922. &state );
  923. if ( FAILED(sc) )
  924. {
  925. Null( _awcWordlists );
  926. Null( _awcPersIndex );
  927. Null( _awcSize );
  928. Null( _awcPropCacheSize );
  929. Null( _awcDocsToFilter );
  930. Null( _awcSecQDocuments );
  931. Null( _awcDocs );
  932. Null( _awcStatus );
  933. //
  934. // Make sure when we come back to life we will update values.
  935. //
  936. RtlFillMemory( &_state, sizeof(_state), 0xAA );
  937. _state.cbStruct = sizeof(_state);
  938. _fSizeChanged = TRUE;
  939. _fPropCacheSizeChanged = TRUE;
  940. _fDocsChanged = TRUE;
  941. _fDocsToFilterChanged = TRUE;
  942. _fWordlistsChanged = TRUE;
  943. _fPersIndexChanged = TRUE;
  944. _fStatusChanged = TRUE;
  945. _fSecQDocumentsChanged = TRUE;
  946. TRY
  947. {
  948. CMachineAdmin MachineAdmin( _parent.IsLocalMachine() ? 0 : _parent.GetMachine() );
  949. XPtr<CCatalogAdmin> xCat( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  950. if (xCat->IsStopped())
  951. {
  952. wcscpy( _awcStatus, STRINGRESOURCE(srStopped) );
  953. }
  954. }
  955. CATCH( CException, e)
  956. {
  957. // nothing to do
  958. }
  959. END_CATCH
  960. }
  961. else
  962. {
  963. //
  964. // String-ize
  965. //
  966. //
  967. // Could put more of this in a method, but it seems like overkill. A table based
  968. // solution will be necessary if this list grows.
  969. //
  970. if ( _state.cWordList != state.cWordList )
  971. {
  972. Stringize( state.cWordList, _awcWordlists, sizeof(_awcWordlists)/sizeof(WCHAR) );
  973. _fWordlistsChanged = TRUE;
  974. }
  975. else
  976. _fWordlistsChanged = FALSE;
  977. if ( _state.cPersistentIndex != state.cPersistentIndex )
  978. {
  979. Stringize( state.cPersistentIndex, _awcPersIndex, sizeof(_awcPersIndex)/sizeof(WCHAR) );
  980. _fPersIndexChanged = TRUE;
  981. }
  982. else
  983. _fPersIndexChanged = FALSE;
  984. if ( _state.dwIndexSize != state.dwIndexSize )
  985. {
  986. Stringize( state.dwIndexSize, _awcSize, sizeof(_awcSize)/sizeof(WCHAR) );
  987. _fSizeChanged = TRUE;
  988. }
  989. else
  990. _fSizeChanged = FALSE;
  991. if (_state.dwPropCacheSize != state.dwPropCacheSize)
  992. {
  993. Stringize(state.dwPropCacheSize/1024, _awcPropCacheSize, sizeof(_awcPropCacheSize)/sizeof(WCHAR));
  994. _fPropCacheSizeChanged = TRUE;
  995. }
  996. else
  997. _fPropCacheSizeChanged = FALSE;
  998. if ( _state.cDocuments != state.cDocuments )
  999. {
  1000. Stringize( state.cDocuments, _awcDocsToFilter, sizeof(_awcDocsToFilter)/sizeof(WCHAR) );
  1001. _fDocsToFilterChanged = TRUE;
  1002. }
  1003. else
  1004. _fDocsToFilterChanged = FALSE;
  1005. if ( _state.cSecQDocuments != state.cSecQDocuments )
  1006. {
  1007. Stringize( state.cSecQDocuments, _awcSecQDocuments, sizeof(_awcSecQDocuments)/sizeof(WCHAR) );
  1008. _fSecQDocumentsChanged = TRUE;
  1009. }
  1010. else
  1011. _fSecQDocumentsChanged = FALSE;
  1012. if ( _state.cTotalDocuments != state.cTotalDocuments )
  1013. {
  1014. Stringize( state.cTotalDocuments, _awcDocs, sizeof(_awcDocs)/sizeof(WCHAR) );
  1015. _fDocsChanged = TRUE;
  1016. }
  1017. else
  1018. _fDocsChanged = FALSE;
  1019. if ( _state.eState != state.eState || _state.dwMergeProgress != state.dwMergeProgress )
  1020. {
  1021. FormatStatus( state );
  1022. _fStatusChanged = TRUE;
  1023. }
  1024. else
  1025. _fStatusChanged = FALSE;
  1026. RtlCopyMemory( &_state, &state, sizeof(state) );
  1027. }
  1028. return ChangesPending();
  1029. }
  1030. BOOL CCatalog::UpdateProps()
  1031. {
  1032. if ( 0 != _aProperty.Count() )
  1033. return FALSE;
  1034. //
  1035. // Look for cached properties
  1036. //
  1037. IUnknown * pIUnknown;
  1038. XInterface<ICommand> xCmd;
  1039. SCODE sc = MakeMetadataICommand( &pIUnknown,
  1040. CiProperties,
  1041. _pwcsCat,
  1042. _parent.GetMachine() );
  1043. if ( FAILED(sc) )
  1044. {
  1045. ciaDebugOut(( DEB_ERROR, "Error 0x%x creating metadata ICommand\n", sc ));
  1046. //THROW( CException(sc) );
  1047. return FALSE;
  1048. }
  1049. XInterface<IUnknown> xUnk( pIUnknown );
  1050. sc = pIUnknown->QueryInterface(IID_ICommand, xCmd.GetQIPointer());
  1051. if ( FAILED(sc) )
  1052. {
  1053. ciaDebugOut(( DEB_ERROR, "Error 0x%x on QueryInterface IID_ICommand\n", sc ));
  1054. //THROW( CException(sc) );
  1055. return FALSE;
  1056. }
  1057. XInterface<ICommandTree> xCmdTree;
  1058. sc = xCmd->QueryInterface( IID_ICommandTree, xCmdTree.GetQIPointer() );
  1059. if ( FAILED(sc) )
  1060. {
  1061. ciaDebugOut(( DEB_ERROR, "Error 0x%x binding to ICommandTree\n", sc ));
  1062. //THROW( CException(sc) );
  1063. return FALSE;
  1064. }
  1065. DBCOMMANDTREE * pTree = &dbcmdSort;
  1066. sc = xCmdTree->SetCommandTree( &pTree, DBCOMMANDREUSE_NONE, TRUE );
  1067. Win4Assert( 0 != pTree ); // Make sure it wasn't taken from us!
  1068. if ( FAILED(sc) )
  1069. {
  1070. ciaDebugOut(( DEB_ERROR, "Error 0x%x setting command tree\n", sc ));
  1071. //THROW( CException(sc) );
  1072. return FALSE;
  1073. }
  1074. XInterface<IRowset> xRowset;
  1075. sc = xCmd->Execute( 0, IID_IRowset, 0, 0, (IUnknown **)xRowset.GetQIPointer() );
  1076. if ( FAILED(sc) )
  1077. {
  1078. ciaDebugOut(( DEB_ERROR, "Error 0x%x creating metadata rowset.\n", sc ));
  1079. //THROW( CException(sc) );
  1080. return FALSE;
  1081. }
  1082. //
  1083. // Now, we have a cursor. Create some bindings. Below this point, we shouldn't
  1084. // expect any errors.
  1085. //
  1086. XInterface<IAccessor> xAccessor;
  1087. sc = xRowset->QueryInterface( IID_IAccessor, xAccessor.GetQIPointer() );
  1088. if ( FAILED(sc) )
  1089. {
  1090. ciaDebugOut(( DEB_ERROR, "Error 0x%x binding to IAccessor\n", sc ));
  1091. THROW( CException(sc) );
  1092. }
  1093. HACCESSOR hacc;
  1094. sc = xAccessor->CreateAccessor( DBACCESSOR_ROWDATA,
  1095. sizeof(abindPropInfo) / sizeof(abindPropInfo[0]),
  1096. abindPropInfo,
  1097. 0,
  1098. &hacc,
  1099. 0 );
  1100. if ( FAILED(sc) )
  1101. {
  1102. ciaDebugOut(( DEB_ERROR, "Error 0x%x binding to IAccessor\n", sc ));
  1103. THROW( CException(sc) );
  1104. }
  1105. //
  1106. // Now we have a cursor and bindings. Iterate over the data.
  1107. //
  1108. while ( SUCCEEDED(sc) && sc != DB_S_ENDOFROWSET )
  1109. {
  1110. HROW ahrow[10];
  1111. DBCOUNTITEM cRow;
  1112. HROW* phrow = ahrow;
  1113. sc = xRowset->GetNextRows( 0, // Chapter
  1114. 0, // Skip
  1115. sizeof(ahrow)/sizeof(ahrow[0]), // Count requested
  1116. &cRow, // Count fetched
  1117. &phrow );
  1118. if ( SUCCEEDED(sc) )
  1119. {
  1120. for ( ULONG i = 0; SUCCEEDED(sc) && i < cRow; i++ )
  1121. {
  1122. SPropInfo sprop;
  1123. sc = xRowset->GetData( ahrow[i], hacc, &sprop );
  1124. Win4Assert( DBSTATUS_S_OK == sprop.statusPropid ||
  1125. DBSTATUS_S_OK == sprop.statusName );
  1126. if ( SUCCEEDED(sc) &&
  1127. ( DBSTATUS_S_OK == sprop.statusPropid ||
  1128. DBSTATUS_S_OK == sprop.statusName ) )
  1129. {
  1130. PROPSPEC ps = { PRSPEC_PROPID, 1 };
  1131. if ( DBSTATUS_S_OK == sprop.statusName )
  1132. {
  1133. ps.ulKind = PRSPEC_LPWSTR;
  1134. ps.lpwstr = sprop.pwcsName;
  1135. }
  1136. else
  1137. ps.propid = sprop.propid;
  1138. CCachedProperty * pProp = new CCachedProperty( *this,
  1139. sprop.guidPropertySet,
  1140. ps,
  1141. sprop.type,
  1142. sprop.size,
  1143. sprop.level,
  1144. sprop.fModifiable );
  1145. _aProperty.Add( pProp, _aProperty.Count() );
  1146. }
  1147. }
  1148. if ( FAILED(sc) || sc == DB_S_ENDOFROWSET )
  1149. xRowset->ReleaseRows( cRow, ahrow, 0, 0, 0 );
  1150. else
  1151. sc = xRowset->ReleaseRows( cRow, ahrow, 0, 0, 0 );
  1152. }
  1153. }
  1154. if ( FAILED(sc) )
  1155. {
  1156. ciaDebugOut(( DEB_ERROR, "Something bad during row fetch (0x%x)\n", sc ));
  1157. THROW( CException(sc) );
  1158. }
  1159. xAccessor->ReleaseAccessor( hacc, 0 );
  1160. return TRUE;
  1161. }
  1162. void CCatalog::FormatStatus( CI_STATE & state )
  1163. {
  1164. //
  1165. // One-shot initialization
  1166. //
  1167. static unsigned ccScanReq;
  1168. static unsigned ccScanning;
  1169. static unsigned ccRecovering;
  1170. static unsigned ccMMPaused;
  1171. static unsigned ccHighIo;
  1172. static unsigned ccLowMemory;
  1173. static unsigned ccReadOnly;
  1174. static unsigned ccBattery;
  1175. static unsigned ccUserActive;
  1176. static unsigned ccStarting;
  1177. static unsigned ccReadingUsns;
  1178. static unsigned ccStarted;
  1179. if ( 0 == ccScanReq )
  1180. {
  1181. ccScanReq = wcslen( STRINGRESOURCE( srScanReq ) );
  1182. ccScanning = wcslen( STRINGRESOURCE( srScanning ) );
  1183. ccRecovering = wcslen( STRINGRESOURCE( srRecovering ) );
  1184. ccMMPaused = wcslen( STRINGRESOURCE( srMMPaused ) );
  1185. ccHighIo = wcslen( STRINGRESOURCE( srHighIo ) );
  1186. ccLowMemory = wcslen( STRINGRESOURCE( srLowMemory ) );
  1187. ccReadOnly = wcslen( STRINGRESOURCE( srReadOnly ) );
  1188. ccBattery = wcslen( STRINGRESOURCE( srBattery ) );
  1189. ccUserActive = wcslen( STRINGRESOURCE( srUserActive ) );
  1190. ccStarting = wcslen( STRINGRESOURCE( srStarting ) );
  1191. ccReadingUsns = wcslen( STRINGRESOURCE( srReadingUsns ) );
  1192. ccStarted = wcslen( STRINGRESOURCE( srStarted ) );
  1193. }
  1194. _awcStatus[0] = 0;
  1195. WCHAR * pwcsStatus = _awcStatus;
  1196. unsigned ccLeft = sizeof(_awcStatus) / sizeof(WCHAR) - 1;
  1197. // Changed srShadow and srAnnealing to just be "Merge" so the end user won't have
  1198. // to be told what shadow and annealing merges are. KISS
  1199. if ( state.eState & CI_STATE_SHADOW_MERGE )
  1200. {
  1201. wsprintf( _awcStatus, STRINGRESOURCE( srShadow ), state.dwMergeProgress );
  1202. ccLeft -= wcslen( _awcStatus );
  1203. }
  1204. else if ( state.eState & CI_STATE_ANNEALING_MERGE )
  1205. {
  1206. wsprintf( _awcStatus, STRINGRESOURCE( srAnnealing ), state.dwMergeProgress );
  1207. ccLeft -= wcslen( _awcStatus );
  1208. }
  1209. else if ( state.eState & CI_STATE_MASTER_MERGE )
  1210. {
  1211. wsprintf( _awcStatus, STRINGRESOURCE( srMaster ), state.dwMergeProgress );
  1212. ccLeft -= wcslen( _awcStatus );
  1213. }
  1214. else if ( state.eState & CI_STATE_MASTER_MERGE_PAUSED )
  1215. {
  1216. RtlCopyMemory( _awcStatus, STRINGRESOURCE( srMMPaused ), (ccMMPaused + 1) * sizeof(WCHAR) );
  1217. ccLeft -= ccMMPaused;
  1218. }
  1219. ccLeft = AppendToStatus( ccLeft, state, CI_STATE_SCANNING, srScanning, ccScanning );
  1220. ccLeft = AppendToStatus( ccLeft, state, CI_STATE_HIGH_IO, srHighIo, ccHighIo );
  1221. ccLeft = AppendToStatus( ccLeft, state, CI_STATE_LOW_MEMORY, srLowMemory, ccLowMemory );
  1222. ccLeft = AppendToStatus( ccLeft, state, CI_STATE_BATTERY_POWER, srBattery, ccBattery );
  1223. ccLeft = AppendToStatus( ccLeft, state, CI_STATE_USER_ACTIVE, srUserActive, ccUserActive );
  1224. ccLeft = AppendToStatus( ccLeft, state, CI_STATE_STARTING, srStarting, ccStarting );
  1225. ccLeft = AppendToStatus( ccLeft, state, CI_STATE_READING_USNS, srReadingUsns, ccReadingUsns );
  1226. ccLeft = AppendToStatus( ccLeft, state, CI_STATE_RECOVERING, srRecovering, ccRecovering );
  1227. ccLeft = AppendToStatus( ccLeft, state, CI_STATE_CONTENT_SCAN_REQUIRED, srScanReq, ccScanReq );
  1228. ccLeft = AppendToStatus( ccLeft, state, CI_STATE_READ_ONLY, srReadOnly, ccReadOnly );
  1229. // If the status is not "Starting", then it should be "Started" so we don't have
  1230. // an empty status field
  1231. if ( (!(state.eState & CI_STATE_STARTING)) && ccLeft >= ccStarted+2)
  1232. {
  1233. if ( _awcStatus[0] == 0 )
  1234. {
  1235. RtlCopyMemory( _awcStatus, STRINGRESOURCE(srStarted), (ccStarted+1) * sizeof(WCHAR) );
  1236. ccLeft -= ccStarted;
  1237. }
  1238. else
  1239. {
  1240. wcscat( _awcStatus, L", " );
  1241. wcscat( _awcStatus, STRINGRESOURCE(srStarted) );
  1242. ccLeft -= ccStarted + 2;
  1243. }
  1244. }
  1245. }
  1246. unsigned CCatalog::AppendToStatus( unsigned ccLeft,
  1247. CI_STATE & state,
  1248. DWORD dwFlag,
  1249. StringResource & srFlag,
  1250. unsigned ccFlag )
  1251. {
  1252. if ( state.eState & dwFlag && ccLeft >= ccFlag + 2 )
  1253. {
  1254. if ( _awcStatus[0] == 0 )
  1255. {
  1256. RtlCopyMemory( _awcStatus, STRINGRESOURCE(srFlag), (ccFlag+1) * sizeof(WCHAR) );
  1257. ccLeft -= ccFlag;
  1258. }
  1259. else
  1260. {
  1261. wcscat( _awcStatus, L", " );
  1262. wcscat( _awcStatus, STRINGRESOURCE(srFlag) );
  1263. ccLeft -= ccFlag + 2;
  1264. }
  1265. }
  1266. return ccLeft;
  1267. }
  1268. void CCatalog::ClearScopes(IResultData * pResultPane)
  1269. {
  1270. // Clear out the display list
  1271. pResultPane->DeleteAllRsltItems();
  1272. // Delete the entries from the property list
  1273. _aScope.Clear();
  1274. }
  1275. void CCatalog::PopulateScopes()
  1276. {
  1277. if ( 0 != _aScope.Count() )
  1278. return;
  1279. TRY
  1280. {
  1281. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  1282. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  1283. XPtr<CScopeEnum> xScopeEnum( xCatalogAdmin->QueryScopeEnum() );
  1284. for ( ; xScopeEnum->Next(); )
  1285. {
  1286. XPtr<CScopeAdmin> xScopeAdmin( xScopeEnum->QueryScopeAdmin() );
  1287. CScope * pScope = new CScope( *this,
  1288. xScopeAdmin->GetPath(),
  1289. xScopeAdmin->GetAlias(),
  1290. xScopeAdmin->IsExclude(),
  1291. xScopeAdmin->IsVirtual(),
  1292. xScopeAdmin->IsShadowAlias() );
  1293. _aScope.Add( pScope, _aScope.Count() );
  1294. }
  1295. }
  1296. CATCH( CException, e )
  1297. {
  1298. ciaDebugOut(( DEB_WARN, "Error enumerating scopes for %ws.\n", _pwcsCat ));
  1299. }
  1300. END_CATCH
  1301. }
  1302. // Delete registry values for grouped settings. Deletion ensures that those
  1303. // registry parameters are inherited from the service.
  1304. // Group1 settings are wcsGenerateCharacterization and
  1305. // wcsFilterFilesWithUnknownExtensions
  1306. // Group2 settings are wcsIsAutoAlias
  1307. // Check to see if parameter groups are available
  1308. BOOL CCatalog::DoGroup1SettingsExist()
  1309. {
  1310. // Caller will deal with exceptions
  1311. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  1312. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  1313. DWORD dwVal;
  1314. BOOL fParamsExist = xCatalogAdmin->GetDWORDParam( wcsGenerateCharacterization, dwVal )
  1315. || xCatalogAdmin->GetDWORDParam( wcsFilterFilesWithUnknownExtensions, dwVal )
  1316. || xCatalogAdmin->GetDWORDParam( wcsMaxCharacterization, dwVal );
  1317. return fParamsExist;
  1318. }
  1319. BOOL CCatalog::DoGroup2SettingsExist()
  1320. {
  1321. // Caller will deal with exceptions
  1322. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  1323. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  1324. DWORD dwVal;
  1325. BOOL fParamsExist = xCatalogAdmin->GetDWORDParam( wcsIsAutoAlias, dwVal );
  1326. return fParamsExist;
  1327. }
  1328. void CCatalog::FillGroup1Settings()
  1329. {
  1330. BOOL fFilterUnknown, fGenerateCharacterization;
  1331. ULONG ccCharacterization;
  1332. // GetGeneration gets registry params from catalog or
  1333. // service (if they don't exist at catalog level)
  1334. GetGeneration(fFilterUnknown, fGenerateCharacterization, ccCharacterization);
  1335. SetGeneration(fFilterUnknown, fGenerateCharacterization, ccCharacterization);
  1336. }
  1337. void CCatalog::FillGroup2Settings()
  1338. {
  1339. BOOL fTracking;
  1340. GetTracking(fTracking);
  1341. SetTracking(fTracking);
  1342. }
  1343. void CCatalog::DeleteGroup1Settings()
  1344. {
  1345. // Caller will deal with exceptions
  1346. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  1347. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  1348. xCatalogAdmin->DeleteRegistryParamNoThrow( wcsGenerateCharacterization );
  1349. xCatalogAdmin->DeleteRegistryParamNoThrow( wcsFilterFilesWithUnknownExtensions );
  1350. xCatalogAdmin->DeleteRegistryParamNoThrow( wcsMaxCharacterization );
  1351. }
  1352. // Group2 settings are wcsIsAutoAlias
  1353. void CCatalog::DeleteGroup2Settings()
  1354. {
  1355. // Caller will deal with exceptions
  1356. CMachineAdmin MachineAdmin( _parent.GetMachine() );
  1357. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _pwcsCat ) );
  1358. xCatalogAdmin->DeleteRegistryParamNoThrow( wcsIsAutoAlias );
  1359. }
  1360. CCatalogs::CCatalogs()
  1361. : _fFirstScopeExpansion( TRUE ),
  1362. _fAbort( FALSE ),
  1363. _pScopePane( 0 ),
  1364. _uiTimerIndex( 0xFFFFFFFF ),
  1365. _wIndexingPos( -1 ),
  1366. _wQueryingPos( -1 ),
  1367. _pSnapinData( 0 )
  1368. {
  1369. //
  1370. // By default, point at local machine.
  1371. //
  1372. _xwcsMachine[0] = L'.';
  1373. _xwcsMachine[1] = 0;
  1374. }
  1375. CCatalogs::~CCatalogs()
  1376. {
  1377. _fAbort = TRUE;
  1378. if (0xFFFFFFFF != _uiTimerIndex && gaTimerIds[_uiTimerIndex])
  1379. {
  1380. CLock lock(gmtxTimer);
  1381. KillTimer(NULL, gaTimerIds[_uiTimerIndex]);
  1382. gapCats[_uiTimerIndex] = 0;
  1383. }
  1384. if ( 0 != _pScopePane )
  1385. _pScopePane->Release();
  1386. }
  1387. void CCatalogs::SetMachine( WCHAR const * pwcsMachine )
  1388. {
  1389. unsigned cc = wcslen( pwcsMachine ) + 1;
  1390. // Remove leading '\' characters. We don't need them, although they
  1391. // are commonly included as part of server names
  1392. WCHAR const *pwcsStart = pwcsMachine;
  1393. while ( *pwcsStart == L'\\' )
  1394. {
  1395. cc--;
  1396. pwcsStart++;
  1397. }
  1398. _xwcsMachine.SetSize( cc );
  1399. RtlCopyMemory( _xwcsMachine.Get(), pwcsStart, cc * sizeof(WCHAR) );
  1400. ciaDebugOut((DEB_ITRACE, "Input machine name %ws is converted to %ws\n",
  1401. pwcsMachine, pwcsStart));
  1402. }
  1403. void CCatalogs::Init( IConsoleNameSpace * pScopePane )
  1404. {
  1405. Win4Assert( 0 == _pScopePane );
  1406. _pScopePane = pScopePane;
  1407. _pScopePane->AddRef();
  1408. // timer stuff
  1409. CLock lock(gmtxTimer);
  1410. gsIndex++;
  1411. gapCats[gsIndex-1] = this;
  1412. _uiTimerIndex = gcMaxCats;
  1413. gaTimerIds[_uiTimerIndex] = SetTimer(NULL, 0, cRefreshDelay, (TIMERPROC)DisplayTimerProc);
  1414. gcMaxCats++;
  1415. }
  1416. void CCatalogs::InitHeader( CListViewHeader & Header )
  1417. {
  1418. //
  1419. // Initialize header
  1420. //
  1421. for ( unsigned i = 0; i < sizeof(coldefCatalog)/sizeof(coldefCatalog[0]); i++ )
  1422. {
  1423. if ( _fFirstTime )
  1424. coldefCatalog[i].srTitle.Init( ghInstance );
  1425. Header.Add( i, STRINGRESOURCE( coldefCatalog[i].srTitle ), LVCFMT_LEFT, MMCLV_AUTO );
  1426. }
  1427. _fFirstTime = FALSE;
  1428. }
  1429. void CCatalogs::DisplayScope( HSCOPEITEM hScopeItem )
  1430. {
  1431. ciaDebugOut(( DEB_ITRACE, "CCatalogs::DisplayScope (hScopeItem = 0x%x)\n", hScopeItem ));
  1432. Populate();
  1433. Win4Assert( 0 != _pScopePane );
  1434. //
  1435. // Squirrel away the parent pointer.
  1436. //
  1437. if ( 0xFFFFFFFF != hScopeItem )
  1438. _hRootScopeItem = hScopeItem;
  1439. if ( _hRootScopeItem == 0xFFFFFFFF )
  1440. return;
  1441. for ( unsigned i = 0; i < _aCatalog.Count(); i++ )
  1442. {
  1443. CCatalog * pCat = _aCatalog.Get( i );
  1444. if ( pCat->IsZombie() )
  1445. {
  1446. _pScopePane->DeleteItem( pCat->ScopeHandle(), TRUE );
  1447. //
  1448. // Delete catalog and move highest entry down.
  1449. //
  1450. pCat = _aCatalog.Acquire( i );
  1451. delete pCat;
  1452. if ( _aCatalog.Count() > 0 && _aCatalog.Count() != i )
  1453. {
  1454. pCat = _aCatalog.Acquire( _aCatalog.Count() - 1 );
  1455. _aCatalog.Add( pCat, i );
  1456. i--;
  1457. }
  1458. continue;
  1459. }
  1460. if (pCat->IsInactive())
  1461. {
  1462. RemoveCatalogFromScope(pCat);
  1463. continue;
  1464. }
  1465. if ( pCat->IsAddedToScope())
  1466. continue;
  1467. AddCatalogToScope(pCat);
  1468. }
  1469. }
  1470. void CCatalogs::AddCatalogToScope(CCatalog *pCat)
  1471. {
  1472. SCOPEDATAITEM item;
  1473. RtlZeroMemory( &item, sizeof(item) );
  1474. item.mask |= SDI_STR | SDI_IMAGE | SDI_OPENIMAGE;
  1475. item.nImage = item.nOpenImage = ICON_CATALOG;
  1476. //item.displayname = (WCHAR *)pCat->GetCat( TRUE );
  1477. item.displayname = MMC_CALLBACK;
  1478. item.mask |= SDI_PARAM;
  1479. item.lParam = (LPARAM)pCat;
  1480. item.relativeID = _hRootScopeItem;
  1481. ciaDebugOut(( DEB_ITRACE, "Inserting scope item %ws (lParam = 0x%x)\n",
  1482. pCat->GetCat( TRUE ), item.lParam ));
  1483. _pScopePane->InsertItem( &item );
  1484. pCat->SetScopeHandle( item.ID );
  1485. }
  1486. void CCatalogs::RemoveCatalogFromScope(CCatalog *pCat)
  1487. {
  1488. if (pCat->ScopeHandle())
  1489. {
  1490. _pScopePane->DeleteItem( pCat->ScopeHandle(), TRUE );
  1491. pCat->SetScopeHandle(0);
  1492. }
  1493. }
  1494. //+-------------------------------------------------------------------------
  1495. //
  1496. // Method: CCatalogs::ReInit, public
  1497. //
  1498. // Synopsis: Re-Initialize catalogs node to default state
  1499. //
  1500. // History: 27-Jul-1998 KyleP Created
  1501. //
  1502. // Notes: Used when MMCN_REMOVE_CHILDREN is sent to snapin, and we
  1503. // need to blast away all state.
  1504. //
  1505. //--------------------------------------------------------------------------
  1506. SCODE CCatalogs::ReInit()
  1507. {
  1508. SCODE sc = S_OK;
  1509. Win4Assert( 0 != _pScopePane );
  1510. _fAbort = TRUE;
  1511. //
  1512. // Get rid of the old timer.
  1513. //
  1514. if ( 0xFFFFFFFF != _uiTimerIndex && gaTimerIds[_uiTimerIndex] )
  1515. {
  1516. CLock lock(gmtxTimer);
  1517. KillTimer(NULL, gaTimerIds[_uiTimerIndex]);
  1518. gapCats[_uiTimerIndex] = 0;
  1519. }
  1520. //
  1521. // And the old catalogs...
  1522. //
  1523. while ( _aCatalog.Count() > 0 )
  1524. {
  1525. RemoveCatalogFromScope( _aCatalog.Get( _aCatalog.Count()-1 ) );
  1526. delete _aCatalog.AcquireAndShrink( _aCatalog.Count()-1 );
  1527. }
  1528. _fAbort = FALSE;
  1529. //
  1530. // Now, a new timer.
  1531. //
  1532. CLock lock2(gmtxTimer);
  1533. gsIndex++;
  1534. gapCats[gsIndex-1] = this;
  1535. _uiTimerIndex = gcMaxCats;
  1536. gaTimerIds[_uiTimerIndex] = SetTimer(NULL, 0, cRefreshDelay, (TIMERPROC)DisplayTimerProc);
  1537. gcMaxCats++;
  1538. return sc;
  1539. }
  1540. void CCatalogs::Display( BOOL fFirstTime )
  1541. {
  1542. ciaDebugOut(( DEB_ITRACE, "CCatalogs::Display (fFirstTime = %d)\n", fFirstTime ));
  1543. for ( unsigned i = 0; i < _aCatalog.Count(); i++ )
  1544. {
  1545. CCatalog * pCat = _aCatalog.Get( i );
  1546. if ( pCat->IsZombie() || !pCat->IsAddedToScope() || pCat->IsInactive() )
  1547. continue;
  1548. if ( pCat->Update() )
  1549. {
  1550. // Ping scope pane...
  1551. SCOPEDATAITEM item;
  1552. RtlZeroMemory( &item, sizeof(item) );
  1553. item.mask |= SDI_STR | SDI_IMAGE | SDI_OPENIMAGE;
  1554. item.nImage = item.nOpenImage = ICON_CATALOG;
  1555. //item.displayname = (WCHAR *)pCat->GetCat( TRUE );
  1556. item.displayname = MMC_CALLBACK;
  1557. item.mask |= SDI_PARAM;
  1558. item.lParam = (LPARAM)pCat;
  1559. item.ID = pCat->ScopeHandle();
  1560. ciaDebugOut(( DEB_ITRACE, "Ping-ing scope item %ws (lParam = 0x%x)\n",
  1561. pCat->GetCat( TRUE ), item.lParam ));
  1562. _pScopePane->SetItem( &item );
  1563. }
  1564. }
  1565. }
  1566. SCODE CCatalogs::AddCatalog( WCHAR const * pwszCatName,
  1567. WCHAR const * pwszLocation )
  1568. {
  1569. SCODE sc = S_OK;
  1570. ciaDebugOut(( DEB_ITRACE,
  1571. "CCatalogs::AddCatalog( %ws, %ws )\n",
  1572. pwszCatName, pwszLocation ));
  1573. //
  1574. // First, check to see if the catalog name and location are already used
  1575. //
  1576. for (ULONG i = 0; i < _aCatalog.Count(); i++)
  1577. {
  1578. if (0 == _wcsicmp(_aCatalog[i]->GetCat(TRUE), pwszCatName) ||
  1579. 0 == _wcsicmp(_aCatalog[i]->GetDrive(TRUE), pwszLocation))
  1580. {
  1581. return E_INVALIDARG;
  1582. }
  1583. }
  1584. TRY
  1585. {
  1586. //
  1587. // First, add to CI.
  1588. //
  1589. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1590. MachineAdmin.AddCatalog( pwszCatName, pwszLocation );
  1591. //
  1592. // Then, to display.
  1593. //
  1594. XPtr<CCatalog> xCat(new CCatalog( *this, pwszCatName ));
  1595. _aCatalog.Add( xCat.GetPointer(), _aCatalog.Count() );
  1596. xCat.Acquire();
  1597. }
  1598. CATCH(CException, e)
  1599. {
  1600. ciaDebugOut(( DEB_WARN, "AddCatalog( %ws, %ws ) caught exception 0x%x\n",
  1601. pwszCatName, pwszLocation, sc ));
  1602. sc = e.GetErrorCode();
  1603. }
  1604. END_CATCH
  1605. return sc;
  1606. }
  1607. SCODE CCatalogs::RemoveCatalog( CCatalog * pCat )
  1608. {
  1609. ciaDebugOut(( DEB_ITRACE, "CCatalogs::RemoveCatalog( %ws )\n", pCat->GetCat(TRUE) ));
  1610. SCODE sc = S_OK;
  1611. TRY
  1612. {
  1613. //
  1614. // First, remove from CI.
  1615. //
  1616. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1617. MachineAdmin.RemoveCatalog( pCat->GetCat(TRUE), TRUE );
  1618. }
  1619. CATCH (CException, e)
  1620. {
  1621. sc = e.GetErrorCode();
  1622. }
  1623. END_CATCH
  1624. //
  1625. // Then, from display. Go ahead and Zombify even if catalog wasn't successfully
  1626. // removed. Parts of it may have been removed, so it is probably unusable anyway.
  1627. //
  1628. pCat->Zombify();
  1629. return sc;
  1630. }
  1631. void CCatalogs::Quiesce()
  1632. {
  1633. //_Header.Update();
  1634. }
  1635. void CCatalogs::GetGeneration( BOOL & fFilterUnknown,
  1636. BOOL & fGenerateCharacterization,
  1637. ULONG & ccCharacterization )
  1638. {
  1639. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1640. DWORD dw;
  1641. //
  1642. // Filter Unknown
  1643. //
  1644. if ( !MachineAdmin.GetDWORDParam( wcsFilterFilesWithUnknownExtensions, dw ) )
  1645. dw = CI_FILTER_FILES_WITH_UNKNOWN_EXTENSIONS_DEFAULT;
  1646. fFilterUnknown = (0 != dw);
  1647. //
  1648. // Characterization. We should check if generatecharacterization flag is set to
  1649. // TRUE and also check the characterization size. Only when the flag is set to TRUE
  1650. // and size > 0, should we generate characterization.
  1651. //
  1652. DWORD dwGenCharacterization = 0;
  1653. if ( !MachineAdmin.GetDWORDParam( wcsGenerateCharacterization, dwGenCharacterization ) )
  1654. dwGenCharacterization = 1;
  1655. if ( !MachineAdmin.GetDWORDParam( wcsMaxCharacterization, ccCharacterization ) )
  1656. ccCharacterization = CI_MAX_CHARACTERIZATION_DEFAULT;
  1657. fGenerateCharacterization = (ccCharacterization > 0) && (0 != dwGenCharacterization);
  1658. }
  1659. void CCatalogs::SetGeneration( BOOL fFilterUnknown,
  1660. BOOL fGenerateCharacterization,
  1661. ULONG ccCharacterization )
  1662. {
  1663. //
  1664. // fGenerateCharacterization is obsolete.
  1665. //
  1666. if ( !fGenerateCharacterization )
  1667. ccCharacterization = 0;
  1668. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1669. MachineAdmin.SetDWORDParam( wcsFilterFilesWithUnknownExtensions, fFilterUnknown );
  1670. MachineAdmin.SetDWORDParam( wcsGenerateCharacterization, fGenerateCharacterization );
  1671. MachineAdmin.SetDWORDParam( wcsMaxCharacterization, ccCharacterization );
  1672. }
  1673. void CCatalogs::GetTracking( BOOL & fAutoAlias )
  1674. {
  1675. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1676. DWORD dw;
  1677. if ( !MachineAdmin.GetDWORDParam( wcsIsAutoAlias, dw ) )
  1678. dw = CI_IS_AUTO_ALIAS_DEFAULT;
  1679. fAutoAlias = (0 != dw);
  1680. }
  1681. void CCatalogs::SetTracking( BOOL fAutoAlias )
  1682. {
  1683. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1684. MachineAdmin.SetDWORDParam( wcsIsAutoAlias, fAutoAlias );
  1685. }
  1686. void CCatalogs::Populate()
  1687. {
  1688. if ( 0 != _aCatalog.Count() )
  1689. return;
  1690. //
  1691. // Populate catalog array.
  1692. //
  1693. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1694. XPtr<CCatalogEnum> xCatEnum( MachineAdmin.QueryCatalogEnum() );
  1695. while ( 0 != xCatEnum->Next() )
  1696. {
  1697. TRY
  1698. {
  1699. XPtr<CCatalog> xCat(new CCatalog( *this, xCatEnum->Name() ));
  1700. _aCatalog.Add( xCat.GetPointer(), _aCatalog.Count() );
  1701. xCat.Acquire();
  1702. }
  1703. CATCH(CException, e)
  1704. {
  1705. ciaDebugOut((DEB_WARN,
  1706. "Unable to populate admin's display with catalog %ws on machine %ws\n",
  1707. xCatEnum->Name(), _xwcsMachine.Get() ));
  1708. }
  1709. END_CATCH
  1710. }
  1711. }
  1712. // Differs from Populate in that this only adds newly added catalogs to the
  1713. // admin's catalog array.
  1714. void CCatalogs::PickupNewCatalogs()
  1715. {
  1716. //
  1717. // Populate catalog array. Add only newer catalogs
  1718. //
  1719. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1720. XPtr<CCatalogEnum> xCatEnum( MachineAdmin.QueryCatalogEnum() );
  1721. while ( 0 != xCatEnum->Next() )
  1722. {
  1723. for (ULONG i = 0; i < _aCatalog.Count(); i++)
  1724. {
  1725. if ( 0 == _wcsicmp(xCatEnum->Name(), _aCatalog[i]->GetCat(TRUE)) )
  1726. break;
  1727. }
  1728. // Have we found the catalog? If so, continue with the next one.
  1729. if (i < _aCatalog.Count())
  1730. continue;
  1731. // We haven't found the catalog in the list. Add it.
  1732. TRY
  1733. {
  1734. XPtr<CCatalog> xCat(new CCatalog( *this, xCatEnum->Name() ));
  1735. _aCatalog.Add( xCat.GetPointer(), _aCatalog.Count() );
  1736. xCat.Acquire();
  1737. }
  1738. CATCH(CException, e)
  1739. {
  1740. ciaDebugOut((DEB_WARN,
  1741. "Unable to populate admin's display with catalog %ws on machine %ws\n",
  1742. xCatEnum->Name(), _xwcsMachine.Get() ));
  1743. }
  1744. END_CATCH
  1745. }
  1746. }
  1747. void CCatalogs::UpdateActiveState()
  1748. {
  1749. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1750. // Enumerate all the catalogs and add new additions
  1751. PickupNewCatalogs();
  1752. // Identify what stays and what goes
  1753. for (ULONG i = 0; i < _aCatalog.Count(); i++)
  1754. {
  1755. TRY
  1756. {
  1757. XPtr<CCatalogAdmin> xCatalogAdmin( MachineAdmin.QueryCatalogAdmin( _aCatalog[i]->GetCat(TRUE) ) );
  1758. _aCatalog[i]->SetInactive(xCatalogAdmin->IsCatalogInactive());
  1759. if (!_aCatalog[i]->IsInactive() && !_aCatalog[i]->IsAddedToScope())
  1760. AddCatalogToScope(_aCatalog[i]);
  1761. }
  1762. CATCH (CException, e)
  1763. {
  1764. // We have an exception attempting to access a catalog, it is either
  1765. // deleted or has its registry messed up. Remove it from list of displayed scopes.
  1766. RemoveCatalogFromScope(_aCatalog[i]);
  1767. _aCatalog[i]->Zombify();
  1768. }
  1769. END_CATCH
  1770. }
  1771. // Cleanup...
  1772. for ( i = 0; i < _aCatalog.Count(); i++ )
  1773. {
  1774. CCatalog * pCat = _aCatalog.Get( i );
  1775. if ( pCat->IsZombie() )
  1776. {
  1777. _pScopePane->DeleteItem( pCat->ScopeHandle(), TRUE );
  1778. //
  1779. // Delete catalog and move highest entry down.
  1780. //
  1781. pCat = _aCatalog.Acquire( i );
  1782. delete pCat;
  1783. if ( _aCatalog.Count() > 0 && _aCatalog.Count() != i )
  1784. {
  1785. pCat = _aCatalog.Acquire( _aCatalog.Count() - 1 );
  1786. _aCatalog.Add( pCat, i );
  1787. i--;
  1788. }
  1789. continue;
  1790. }
  1791. if ( pCat->IsInactive() )
  1792. {
  1793. if ( pCat->IsAddedToScope() )
  1794. RemoveCatalogFromScope(pCat);
  1795. continue;
  1796. }
  1797. if ( pCat->IsAddedToScope() )
  1798. continue;
  1799. AddCatalogToScope(pCat);
  1800. }
  1801. }
  1802. //
  1803. // Implementation of TuneServicePerformance
  1804. // wIndexingPos is on a scale of 1 to 3, where 1 is least aggressive
  1805. // and 3 is most aggressive. wQueryingPos is on the same scale.
  1806. //
  1807. SCODE CCatalogs::TuneServicePerformance()
  1808. {
  1809. BOOL fServer = IsNTServer();
  1810. SCODE sc = S_OK;
  1811. // Ensure that these settings were made.
  1812. Win4Assert(_wIndexingPos != -1 && _wQueryingPos != -1);
  1813. TRY
  1814. {
  1815. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1816. MachineAdmin.TunePerformance(fServer, _wIndexingPos, _wQueryingPos);
  1817. }
  1818. CATCH( CException, e )
  1819. {
  1820. sc = e.GetErrorCode();
  1821. ciDebugOut((DEB_WARN,
  1822. "Caught exception %d (0x%x) attempting to tune performance.",
  1823. sc, sc));
  1824. }
  1825. END_CATCH
  1826. return sc;
  1827. }
  1828. void CCatalogs::SaveServicePerformanceSettings(WORD wIndexingPos, WORD wQueryingPos)
  1829. {
  1830. _wIndexingPos = wIndexingPos;
  1831. _wQueryingPos = wQueryingPos;
  1832. }
  1833. void CCatalogs::GetServicePerformanceSettings(WORD &wIndexingPos, WORD &wQueryingPos)
  1834. {
  1835. wIndexingPos = _wIndexingPos;
  1836. wQueryingPos = _wQueryingPos;
  1837. }
  1838. SCODE CCatalogs::DisableService()
  1839. {
  1840. SCODE sc = S_OK;
  1841. TRY
  1842. {
  1843. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1844. MachineAdmin.StopCI();
  1845. sc = MachineAdmin.DisableCI() ? S_OK : E_FAIL;
  1846. }
  1847. CATCH( CException, e )
  1848. {
  1849. sc = e.GetErrorCode();
  1850. ciDebugOut((DEB_WARN,
  1851. "Caught exception %d (0x%x) attempting to tune performance.",
  1852. sc, sc));
  1853. }
  1854. END_CATCH
  1855. return sc;
  1856. }
  1857. SCODE CCatalogs::EnableService()
  1858. {
  1859. SCODE sc = S_OK;
  1860. TRY
  1861. {
  1862. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1863. if ( !MachineAdmin.IsCIEnabled() )
  1864. sc = MachineAdmin.EnableCI() ? S_OK : E_FAIL;
  1865. }
  1866. CATCH( CException, e )
  1867. {
  1868. sc = e.GetErrorCode();
  1869. ciDebugOut((DEB_WARN,
  1870. "Caught exception %d (0x%x) attempting to enable service",
  1871. sc, sc));
  1872. }
  1873. END_CATCH
  1874. return sc;
  1875. }
  1876. SCODE CCatalogs::GetSavedServiceUsage(DWORD &dwUsage,
  1877. DWORD &dwIdxPos,
  1878. DWORD &dwQryPos)
  1879. {
  1880. SCODE sc = S_OK;
  1881. TRY
  1882. {
  1883. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1884. if (!MachineAdmin.GetDWORDParam(wcsServiceUsage, dwUsage))
  1885. {
  1886. // plug in a default value
  1887. dwUsage = wUsedOften;
  1888. }
  1889. if (!MachineAdmin.GetDWORDParam(wcsDesiredIndexingPerf, dwIdxPos))
  1890. {
  1891. // plug in a default value
  1892. dwIdxPos = wMidPos;
  1893. }
  1894. if (!MachineAdmin.GetDWORDParam(wcsDesiredQueryingPerf, dwQryPos))
  1895. {
  1896. // plug in a default value
  1897. dwQryPos = wMidPos;
  1898. }
  1899. }
  1900. CATCH( CException, e )
  1901. {
  1902. sc = e.GetErrorCode();
  1903. ciDebugOut((DEB_WARN,
  1904. "Caught exception %d (0x%x) attempting to retrieve service usage.",
  1905. sc, sc));
  1906. }
  1907. END_CATCH
  1908. return sc;
  1909. }
  1910. SCODE CCatalogs::SaveServiceUsage(DWORD dwUsage,
  1911. DWORD dwIdxPos,
  1912. DWORD dwQryPos)
  1913. {
  1914. SCODE sc = S_OK;
  1915. TRY
  1916. {
  1917. CMachineAdmin MachineAdmin( _xwcsMachine.Get() );
  1918. MachineAdmin.SetDWORDParam(wcsServiceUsage, dwUsage);
  1919. MachineAdmin.SetDWORDParam(wcsDesiredIndexingPerf, dwIdxPos);
  1920. MachineAdmin.SetDWORDParam(wcsDesiredQueryingPerf, dwQryPos);
  1921. }
  1922. CATCH( CException, e )
  1923. {
  1924. sc = e.GetErrorCode();
  1925. ciDebugOut((DEB_WARN,
  1926. "Caught exception %d (0x%x) attempting to save service usage.",
  1927. sc, sc));
  1928. }
  1929. END_CATCH
  1930. return sc;
  1931. }
  1932. void CALLBACK DisplayTimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  1933. {
  1934. CLock lock(gmtxTimer);
  1935. // seek the index of the catalog associated with this timer event
  1936. for (UINT i = 0; i < gcMaxCats; i++)
  1937. if (gaTimerIds[i] == idEvent)
  1938. break;
  1939. if (i >= gcMaxCats)
  1940. {
  1941. Win4Assert(!"How did this happen?");
  1942. return;
  1943. }
  1944. // Fix for bug 150471
  1945. // If the snapin went away just as the timer triggered a timer proc,
  1946. // and the destructor in CCatalogs gets to the lock before this
  1947. // function, then gapCats[i] will be 0. That is what happened in
  1948. CCatalogs *pCats = gapCats[i];
  1949. if (0 == pCats || pCats->_fAbort)
  1950. return;
  1951. // Cause display
  1952. pCats->Display( FALSE );
  1953. // Special case: Update the status of the iconbar. This is only needed for
  1954. // the case where the service was started. Service startup could take a while,
  1955. // and we don't know how long it could take. So we cannot wait to update the
  1956. // display when the service is actually started. Instead, we will check frequently
  1957. // and update the status.
  1958. TRY
  1959. {
  1960. CMachineAdmin MachineAdmin( pCats->IsLocalMachine() ? 0 : pCats->GetMachine() );
  1961. if ( MachineAdmin.IsCIStarted() && 0 != pCats->SnapinData() )
  1962. {
  1963. pCats->SnapinData()->SetButtonState(comidStartCITop, ENABLED, FALSE);
  1964. pCats->SnapinData()->SetButtonState(comidStopCITop, ENABLED, TRUE);
  1965. pCats->SnapinData()->SetButtonState(comidPauseCITop, ENABLED, TRUE);
  1966. // We only want to update once after the service has started. If the service
  1967. // is stopped and restarted, the pointer will be set to an appropriate value
  1968. // at a later time, so we can go ahead and get rid of the snapindata ptr for now.
  1969. pCats->SetSnapinData( 0 );
  1970. }
  1971. }
  1972. CATCH(CException, e)
  1973. {
  1974. // Nothing specific to do in this case
  1975. }
  1976. END_CATCH
  1977. }