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.

2993 lines
90 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000.
  5. //
  6. // File: setupqry.cxx
  7. //
  8. // Contents: Indexing Service ocmgr installation routines
  9. //
  10. // Wish-list: Seek and destroy old webhits.exe files
  11. // Migrate all existing catalogs + virtual server catalogs
  12. //
  13. // History: 8-Jan-97 dlee Created
  14. // 7-7-97 mohamedn changed to work with NT setup.
  15. //
  16. //--------------------------------------------------------------------------
  17. #include "pch.cxx"
  18. #pragma hdrstop
  19. #include <xolemem.hxx>
  20. #include "catcnfg.hxx"
  21. DECLARE_INFOLEVEL( is )
  22. #define COPY_FILES_EVEN_IF_INSTALLED
  23. extern "C" ULONG DbgPrint( LPSTR Format, ... );
  24. //
  25. // external exported routines.
  26. //
  27. extern "C"
  28. {
  29. BOOL WINAPI DllMain( IN HANDLE DllHandle,
  30. IN DWORD Reason,
  31. IN LPVOID Reserved );
  32. DWORD IndexSrv( IN LPCWSTR ComponentId,
  33. IN LPCWSTR SubcomponentId,
  34. IN UINT Function,
  35. IN UINT Param1,
  36. IN OUT PVOID Param2 );
  37. }
  38. //
  39. // DLL module instance handle
  40. //
  41. HINSTANCE MyModuleHandle;
  42. //
  43. // Utility routines
  44. //
  45. void GetPreviousISSetupVersion(void);
  46. DWORD CompleteInstallation(CError &Err);
  47. DWORD QueueConfigurationParams( HINF hInf,
  48. HSPFILEQ Param2,
  49. WCHAR const * pwszSectionName,
  50. CError &Err );
  51. DWORD SetDefaultCatalog(CError &Err);
  52. void UpgradeIS1toIS3(CError & Err);
  53. DWORD SetFilterRegistryInfo( BOOL fUnRegister,CError &Err );
  54. DWORD SetDLLsToRegister(CError & Err);
  55. void ExcludeSpecialLocations( CCatalogConfig & Cat );
  56. void OcCleanup( CError & Err );
  57. void SetupW3Svc(CError &Err);
  58. void DeleteNTOPStartMenu();
  59. DWORD AddPerfData( CError &Err );
  60. DWORD RemovePerfData(void);
  61. DWORD LoadCounterAndDelete( WCHAR const * pwcINI,
  62. WCHAR const * pwcH,
  63. CError &Err );
  64. void CreateSharedDllRegSubKey(void);
  65. DWORD AddRefSharedDll( WCHAR const * pwszDllName );
  66. WCHAR * AppendMultiSZString(WCHAR * pwcTo, WCHAR const * pwcFrom );
  67. DWORD RegisterDll(WCHAR const * pwcDLL, CError &Err );
  68. BOOL IsSufficientMemory(void);
  69. void AddCiSvc(CError &Err);
  70. DWORD RenameCiSvc( SC_HANDLE hSC, CError &Err );
  71. void StopService( WCHAR const * pwszServiceName );
  72. void StartService( WCHAR const * pwszServiceName );
  73. void MyStartService( CServiceHandle & xSC,
  74. WCHAR const * pwcSVC );
  75. BOOL MyStopService( CServiceHandle & xSC,
  76. WCHAR const * pwcSVC,
  77. BOOL & fStopped );
  78. void DeleteService( WCHAR const * pwszServiceName );
  79. DWORD SetRegBasedOnMachine(CError &Err);
  80. DWORD SetRegBasedOnArchitecture(CError &Err);
  81. void GetMachineInfo(BOOL & fLotsOfMem, DWORD & cCPU );
  82. void DeleteShellLink( WCHAR const * pwcGroup,
  83. WCHAR const * pwcName );
  84. //
  85. // hardcoded globals, obtained from is30.INF file
  86. //
  87. // [indexsrv]
  88. INT g_MajorVersion = 3;
  89. INT g_dwPrevISVersion = 0;
  90. BOOL g_fNT4_To_NT5_Upgrade = FALSE;
  91. BOOL g_fIS1x_To_NT5_Upgrade = FALSE;
  92. BOOL g_fCiSvcWasRunning = FALSE;
  93. BOOL g_fCiSvcIsRequested = FALSE;
  94. WCHAR g_awcSystemDir[MAX_PATH]; // system32 directory
  95. WCHAR g_awcSourcePath[MAX_PATH * 2]; // inf source location.
  96. WCHAR g_awcIS1Path[MAX_PATH+1];
  97. OCMANAGER_ROUTINES g_HelperRoutines;
  98. //
  99. // globals needed for OCM
  100. //
  101. SETUP_INIT_COMPONENT gSetupInitComponent;
  102. BOOL g_fBatchInstall = FALSE;
  103. BOOL g_fInstallCancelled = TRUE; // Similar to aborted, but caused by user cancel, not internal exception
  104. BOOL g_fInstallAborted = FALSE;
  105. BOOL g_fComponentInitialized = FALSE;
  106. BOOL g_fUnattended = FALSE;
  107. BOOL g_fUpgrade = FALSE;
  108. BOOL g_fNtGuiMode = TRUE;
  109. DWORD g_NtType = -1;
  110. BOOL g_fLocallyOpened = FALSE;
  111. WCHAR g_awcProfilePath[MAX_PATH];
  112. WCHAR const * pwcIISAppKey = L"IndexingService";
  113. //
  114. // keep track if we're selected or not selected
  115. //
  116. BOOL g_fFalseAlready = FALSE;
  117. unsigned g_cChangeSelection = 0;
  118. //
  119. // frequently used constants
  120. //
  121. const WCHAR wcsIndexsrvSystem[] = L"indexsrv_system";
  122. //
  123. // frequently used registry keys.
  124. //
  125. const WCHAR wcsRegAdminSubKey[] =
  126. L"System\\CurrentControlSet\\Control\\ContentIndex";
  127. const WCHAR wcsRegCatalogsSubKey[] =
  128. L"System\\CurrentControlSet\\Control\\ContentIndex\\Catalogs";
  129. const WCHAR wcsRegCatalogsWebSubKey[] =
  130. L"System\\CurrentControlSet\\Control\\ContentIndex\\Catalogs\\web";
  131. const WCHAR wcsRegCatalogsWebPropertiesSubKey[] =
  132. L"System\\CurrentControlSet\\Control\\ContentIndex\\Catalogs\\web\\properties";
  133. const WCHAR wcsAllowedPaths[] =
  134. L"System\\CurrentControlSet\\Control\\SecurePipeServers\\winreg\\AllowedPaths";
  135. const WCHAR wcsPreventCisvcParam[] = L"DonotStartCiSvc";
  136. const WCHAR wcsISDefaultCatalogDirectory[] = L"IsapiDefaultCatalogDirectory";
  137. const WCHAR wszRegProfileKey[] =
  138. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList";
  139. const WCHAR wszRegProfileValue[] = L"ProfilesDirectory";
  140. const WCHAR wszProperties[] = L"properties";
  141. //
  142. // Directory name where system catalog will be placed
  143. //
  144. const WCHAR wszSysVolInfoDirectory[] = L"x:\\System Volume Information";
  145. //
  146. // Array of Dlls to register
  147. //
  148. static WCHAR * apwcDlls[] = {
  149. L"query.dll",
  150. L"ciadmin.dll",
  151. L"ixsso.dll",
  152. L"nlhtml.dll",
  153. L"offfilt.dll",
  154. L"ciodm.dll",
  155. L"infosoft.dll",
  156. L"mimefilt.dll",
  157. L"LangWrbk.dll",
  158. };
  159. const int cDlls = NUMELEM( apwcDlls );
  160. static WCHAR * apwcOldDlls[] = {
  161. L"cifrmwrk.dll",
  162. L"fsci.dll",
  163. };
  164. const int cOldDlls = NUMELEM( apwcOldDlls );
  165. //
  166. // utility routines
  167. //
  168. BOOL OpenInfFile(CError & Err);
  169. CError::CError( )
  170. {
  171. SetupOpenLog(FALSE); /* don't overwrite existing log file */
  172. }
  173. CError::~CError( )
  174. {
  175. SetupCloseLog();
  176. }
  177. //+-------------------------------------------------------------------------
  178. //
  179. // Member: CError::Report
  180. //
  181. // Synopsis: reports a message to various destinations
  182. //
  183. // Arguments: [LogSeverity] -- message severity
  184. // [dwErr] -- The error code
  185. // [MessageString]-- printf format string for message
  186. // [...] -- variable arguments for message params
  187. //
  188. // Returns: none. don't throw.
  189. //
  190. // History: 2-9-98 mohamedn
  191. //
  192. //--------------------------------------------------------------------------
  193. void CError::Report(
  194. LogSeverity Severity,
  195. DWORD dwErr,
  196. WCHAR const * MessageString,
  197. ...)
  198. {
  199. WCHAR awcMsgTemp[MAX_PATH * 2];
  200. awcMsgTemp[0] = _awcMsg[0] = L'\0';
  201. va_list va;
  202. va_start(va, MessageString);
  203. wvsprintf(awcMsgTemp, MessageString, va);
  204. va_end(va);
  205. // prepend on Our modules information.
  206. wsprintf(_awcMsg, L"setupqry: (%#x) %s\r\n", dwErr, awcMsgTemp);
  207. if ( !SetupLogError(_awcMsg, Severity) )
  208. {
  209. isDebugOut(( DEB_ERROR, "SetupLogError Failed: %d\n", GetLastError() ));
  210. }
  211. }
  212. //+-------------------------------------------------------------------------
  213. //
  214. // Function: DllMain
  215. //
  216. // Synopsis: The usual suspect
  217. //
  218. // Return: TRUE - Initialization succeeded
  219. // FALSE - Initialization failed
  220. //
  221. // History: 8-Jan-97 dlee Created
  222. //
  223. //--------------------------------------------------------------------------
  224. BOOL WINAPI DllMain(
  225. IN HANDLE DllHandle,
  226. IN DWORD Reason,
  227. IN LPVOID Reserved )
  228. {
  229. UNREFERENCED_PARAMETER(Reserved);
  230. switch( Reason )
  231. {
  232. WCHAR DllName[MAX_PATH];
  233. case DLL_PROCESS_ATTACH:
  234. MyModuleHandle = (HINSTANCE)DllHandle;
  235. DisableThreadLibraryCalls( MyModuleHandle );
  236. if (!GetModuleFileName(MyModuleHandle, DllName, MAX_PATH) ||
  237. !LoadLibrary( DllName ))
  238. {
  239. return FALSE;
  240. }
  241. break;
  242. case DLL_PROCESS_DETACH:
  243. break;
  244. }
  245. return TRUE;
  246. } //DllMain
  247. //+-------------------------------------------------------------------------
  248. //
  249. // Function: IndexSrv
  250. //
  251. // Synopsis: Called by the ocmgr when things happen
  252. //
  253. // Arguments: ComponentId -- "indexsrv_system"
  254. // SubcomponentId -- the .inf section being operated on
  255. // Function -- the operation
  256. // Param1 -- operation paramater
  257. // Param2 -- operation paramater
  258. //
  259. // Returns: Win32 error code (usually), depends on Function
  260. //
  261. //
  262. //--------------------------------------------------------------------------
  263. DWORD IndexSrv(
  264. IN LPCWSTR ComponentId,
  265. IN LPCWSTR SubcomponentId,
  266. IN UINT Function,
  267. IN UINT Param1,
  268. IN OUT PVOID Param2 )
  269. {
  270. DWORD dwRetVal = NO_ERROR;
  271. isDebugOut(( "IndexSrv, Function %d\n", Function ));
  272. //
  273. // if we're aborted, do nothing.
  274. //
  275. if ( g_fInstallAborted )
  276. return dwRetVal;
  277. CError Err;
  278. CSmartException xSmartException;
  279. TRY
  280. {
  281. switch(Function)
  282. {
  283. case OC_PREINITIALIZE:
  284. isDebugOut(( "OC_PREINITIALIZE\n" ));
  285. GetSystemDirectory( g_awcSystemDir,
  286. sizeof g_awcSystemDir / sizeof WCHAR );
  287. return OCFLAG_UNICODE;
  288. break;
  289. case OC_SET_LANGUAGE:
  290. isDebugOut(( "OC_SET_LANGUAGE\n" ));
  291. //
  292. // Param1 = low 16 bits specify Win32 LANG
  293. // Param2 = unused
  294. //
  295. // Return code is a boolean indicating whether we think we
  296. // support the requested language. We remember the language id
  297. // and say we support the language. A more exact check might involve
  298. // looking through our resources via EnumResourcesLnguages() for
  299. // example, or checking our inf to see whether there is a matching
  300. // or closely matching [strings] section. We don't bother with
  301. // any of that here.
  302. //
  303. // Locate the component and remember the language id for later use.
  304. //
  305. return TRUE;
  306. case OC_INIT_COMPONENT:
  307. isDebugOut(( "OC_INIT_COMPONENT\n" ));
  308. isDebugOut(( DEB_TRACE, "init_component: '%ws'\n", ComponentId ));
  309. if (OCMANAGER_VERSION <= ((PSETUP_INIT_COMPONENT)Param2)->OCManagerVersion)
  310. {
  311. ((PSETUP_INIT_COMPONENT)Param2)->ComponentVersion = OCMANAGER_VERSION;
  312. }
  313. else
  314. {
  315. ISError( IS_MSG_INVALID_OCM_VERSION, Err, LogSevFatalError );
  316. isDebugOut(( "wrong ocmgr version!\n" ));
  317. return ERROR_CALL_NOT_IMPLEMENTED;
  318. }
  319. if ( g_fInstallAborted )
  320. {
  321. ISError( IS_MSG_ABORT, Err, LogSevFatalError );
  322. dwRetVal = ERROR_CANCELLED;
  323. break;
  324. }
  325. //
  326. // Param1 = unused
  327. // Param2 = points to SETUP_INIT_COMPONENT structure
  328. //
  329. // Return code is Win32 error indicating outcome.
  330. // ERROR_CANCELLED means this component's install will be aborted.
  331. //
  332. // Even though this call happens once for each component that this
  333. // dll installs, we really only need to do our thing once. This is
  334. // because the data that OCM passes is the same for all calls.
  335. //
  336. if (!g_fComponentInitialized)
  337. {
  338. PSETUP_INIT_COMPONENT InitComponent = (PSETUP_INIT_COMPONENT)Param2;
  339. g_HelperRoutines = InitComponent->HelperRoutines;
  340. CopyMemory( &gSetupInitComponent, (LPVOID)Param2, sizeof(SETUP_INIT_COMPONENT) );
  341. g_fUnattended = (gSetupInitComponent.SetupData.OperationFlags & SETUPOP_BATCH) != 0;
  342. g_fUpgrade = (gSetupInitComponent.SetupData.OperationFlags & SETUPOP_NTUPGRADE) != 0;
  343. g_fNtGuiMode = (gSetupInitComponent.SetupData.OperationFlags & SETUPOP_STANDALONE) == 0;
  344. g_NtType = gSetupInitComponent.SetupData.ProductType;
  345. isDebugOut(( DEB_TRACE, "g_fUnattended: %d\n", g_fUnattended ));
  346. isDebugOut(( DEB_TRACE, "g_fUpgrade: %d\n", g_fUpgrade ));
  347. isDebugOut(( DEB_TRACE, "g_fNtGuiMode: %d\n", g_fNtGuiMode ));
  348. isDebugOut(( DEB_TRACE, "g_NtType: %d\n", g_NtType ));
  349. if (gSetupInitComponent.ComponentInfHandle == NULL)
  350. {
  351. if ( !OpenInfFile(Err) )
  352. {
  353. ISError(IS_MSG_INVALID_INF_HANDLE, Err, LogSevFatalError);
  354. dwRetVal = ERROR_CANCELLED;
  355. }
  356. else
  357. {
  358. g_fComponentInitialized = TRUE;
  359. dwRetVal = NO_ERROR;
  360. }
  361. }
  362. //
  363. // determine if this an NT4-->NT5 upgrade
  364. //
  365. GetPreviousISSetupVersion();
  366. if ( g_dwPrevISVersion > 0 && g_dwPrevISVersion < g_MajorVersion )
  367. {
  368. g_fNT4_To_NT5_Upgrade = TRUE;
  369. // g_dwPrevIsVersion is 0 if the ContentIndex key doesn't exist
  370. if ( 1 == g_dwPrevISVersion )
  371. g_fIS1x_To_NT5_Upgrade = TRUE;
  372. }
  373. }
  374. break;
  375. case OC_QUERY_STATE:
  376. isDebugOut(( "OC_QUERY_STATE\n" ));
  377. if ( !SubcomponentId || _wcsicmp(SubcomponentId,wcsIndexsrvSystem) )
  378. return NO_ERROR;
  379. //
  380. // We can't return SubcompUseOcManagerDefault if 1.x is installed
  381. // the ocmgr registry key for index server won't be set if 1.x was
  382. // installed using the non-ocmgr installation. In this case, check
  383. // if the ContentIndex key exists and if so return SubcompOn.
  384. //
  385. if ( ( OCSELSTATETYPE_ORIGINAL == Param1 ) && g_fIS1x_To_NT5_Upgrade )
  386. {
  387. isDebugOut(( "Upgrading from 1.x to NT 5, turning on IS by default\n" ));
  388. isDebugOut(( DEB_ITRACE, "Upgrading from 1.x to NT 5, turning on IS by default\n" ));
  389. dwRetVal = SubcompOn;
  390. }
  391. else
  392. dwRetVal = SubcompUseOcManagerDefault;
  393. break;
  394. case OC_REQUEST_PAGES:
  395. isDebugOut(( "OC_REQUEST_PAGES\n" ));
  396. return 0; // no pages
  397. // break;
  398. case OC_QUERY_CHANGE_SEL_STATE:
  399. isDebugOut(( "OC_QUERY_CHANGE_SEL_STATE\n" ));
  400. isDebugOut(( "queryChangeSelState %#x, %#x, %#x\n", SubcomponentId, Param1, Param2 ));
  401. if ( !SubcomponentId || _wcsicmp(SubcomponentId,wcsIndexsrvSystem) )
  402. {
  403. return NO_ERROR;
  404. }
  405. if ( Param1 == 0 )
  406. {
  407. //
  408. // we're not selected
  409. //
  410. if ( 0 == g_cChangeSelection || !g_fFalseAlready )
  411. {
  412. g_cChangeSelection++;
  413. g_fFalseAlready = TRUE;
  414. }
  415. g_fCiSvcIsRequested = FALSE;
  416. }
  417. else
  418. {
  419. //
  420. // we are selected
  421. //
  422. if ( 0 == g_cChangeSelection || g_fFalseAlready )
  423. {
  424. g_cChangeSelection++;
  425. g_fFalseAlready = FALSE;
  426. }
  427. g_fCiSvcIsRequested = TRUE;
  428. }
  429. dwRetVal = TRUE;
  430. break;
  431. case OC_CALC_DISK_SPACE:
  432. isDebugOut(( "OC_CALC_DISK_SPACE\n" ));
  433. //
  434. // skip, no files are copied.
  435. //
  436. if ( NO_ERROR != dwRetVal )
  437. {
  438. isDebugOut(( DEB_ERROR, "Calc Disk Space Failed: %d\n", dwRetVal ));
  439. ISError( IS_MSG_CALC_DISK_SPACE_FAILED, Err, LogSevError );
  440. }
  441. break;
  442. case OC_QUEUE_FILE_OPS:
  443. isDebugOut(( "OC_QUEUE_FILE_OPS\n" ));
  444. //
  445. // Param1 = unused
  446. // Param2 = HSPFILEQ to operate on
  447. //
  448. // Return value is Win32 error code indicating outcome.
  449. //
  450. // OC Manager calls this routine when it is ready for files to be
  451. // copied to effect the changes the user requested. The component
  452. // DLL must figure out whether it is being installed or uninstalled
  453. // and take appropriate action.
  454. // For this sample, we look in the private data section for this
  455. // component/subcomponent pair, and get the name of an uninstall
  456. // section for the uninstall case.
  457. //
  458. // Note that OC Manager calls us once for the *entire* component
  459. // and then once per subcomponent.
  460. //
  461. if ( NO_ERROR != dwRetVal )
  462. {
  463. isDebugOut(( DEB_ERROR, "Queue File Operations Failed: %d\n", dwRetVal ));
  464. ISError( IS_MSG_QUEUE_FILE_OPS_FAILED, Err, LogSevError );
  465. }
  466. break;
  467. case OC_QUERY_STEP_COUNT:
  468. isDebugOut(( "OC_QUERY_STEP_COUNT\n" ));
  469. //
  470. // Param1 = unused
  471. // Param2 = unused
  472. //
  473. // Return value is an arbitrary 'step' count or -1 if error.
  474. //
  475. // OC Manager calls this routine when it wants to find out how much
  476. // work the component wants to perform for nonfile operations to
  477. // install/uninstall a component/subcomponent.
  478. // It is called once for the *entire* component and then once for
  479. // each subcomponent in the component.
  480. //
  481. // One could get arbitrarily fancy here but we simply return 1 step
  482. // per subcomponent. We ignore the "entire component" case.
  483. //
  484. if ( !SubcomponentId || _wcsicmp( SubcomponentId,wcsIndexsrvSystem ) )
  485. {
  486. return NO_ERROR;
  487. }
  488. dwRetVal = 1;
  489. break;
  490. case OC_ABOUT_TO_COMMIT_QUEUE:
  491. isDebugOut(( "OC_ABOUT_TO_COMMIT_QUEUE\n" ));
  492. if ( !SubcomponentId || _wcsicmp( wcsIndexsrvSystem,SubcomponentId ) )
  493. {
  494. return NO_ERROR;
  495. }
  496. dwRetVal = QueueConfigurationParams( gSetupInitComponent.ComponentInfHandle,
  497. (HSPFILEQ) Param2,
  498. SubcomponentId,
  499. Err );
  500. if ( NO_ERROR != dwRetVal )
  501. {
  502. isDebugOut((DEB_ERROR,"QueueConfigurationParams Failed: %d\n",dwRetVal ));
  503. ISError( IS_MSG_QUEUE_CONFIG_PARAMS_FAILED, Err, LogSevError, dwRetVal );
  504. return ERROR_CANCELLED;
  505. }
  506. dwRetVal = SetRegBasedOnMachine(Err);
  507. if ( NO_ERROR != dwRetVal )
  508. {
  509. isDebugOut(( DEB_ERROR, "SetRegBasedOnMachine Failed: %d\n", dwRetVal ));
  510. ISError( IS_MSG_SetRegBasedOnMachine_FAILED, Err, LogSevError, dwRetVal );
  511. }
  512. dwRetVal = SetRegBasedOnArchitecture(Err);
  513. if ( NO_ERROR != dwRetVal )
  514. {
  515. isDebugOut(( DEB_ERROR, "SetRegBasedOnArchitecture Failed: %d\n", dwRetVal ));
  516. Err.Report(LogSevError, dwRetVal, L"SetRegBasedOnArchitecture FAILED");
  517. }
  518. break;
  519. case OC_COMPLETE_INSTALLATION:
  520. isDebugOut(( "OC_COMPLETE_INSTALLATION\n" ));
  521. if ( !SubcomponentId || _wcsicmp(SubcomponentId,wcsIndexsrvSystem) )
  522. {
  523. return NO_ERROR;
  524. }
  525. dwRetVal = CompleteInstallation(Err);
  526. if ( NO_ERROR != dwRetVal )
  527. {
  528. isDebugOut(( DEB_ERROR, "CompleteInstallation Failed: %d\n", dwRetVal ));
  529. ISError( IS_MSG_COMPLETE_INSTALLATION_FAILED, Err, LogSevError, dwRetVal );
  530. }
  531. if ( g_fLocallyOpened &&
  532. INVALID_HANDLE_VALUE != gSetupInitComponent.ComponentInfHandle )
  533. {
  534. SetupCloseInfFile(gSetupInitComponent.ComponentInfHandle);
  535. gSetupInitComponent.ComponentInfHandle = INVALID_HANDLE_VALUE;
  536. }
  537. g_fInstallCancelled = FALSE;
  538. break;
  539. case OC_CLEANUP:
  540. isDebugOut(( "OC_CLEANUP\n" ));
  541. //
  542. // Do last-minute work now that the metabase is installed
  543. //
  544. OcCleanup( Err );
  545. break;
  546. case OC_QUERY_IMAGE:
  547. isDebugOut(( "OC_QUERY_IMAGE\n" ));
  548. //
  549. // not used
  550. //
  551. break;
  552. default:
  553. isDebugOut(( "OC_ message ignored\n" ));
  554. break;
  555. }
  556. isDebugOut(( "IndexSrv is returning %d\n", dwRetVal ));
  557. return dwRetVal;
  558. }
  559. CATCH (CException, e)
  560. {
  561. isDebugOut(( "install is aborted, error %#x\n", e.GetErrorCode() ));
  562. g_fInstallAborted = TRUE;
  563. if ( g_fLocallyOpened &&
  564. INVALID_HANDLE_VALUE != gSetupInitComponent.ComponentInfHandle )
  565. {
  566. SetupCloseInfFile(gSetupInitComponent.ComponentInfHandle);
  567. gSetupInitComponent.ComponentInfHandle = INVALID_HANDLE_VALUE;
  568. }
  569. ISError( IS_MSG_EXCEPTION_CAUGHT, Err, LogSevError, e.GetErrorCode() );
  570. dwRetVal = e.GetErrorCode();
  571. }
  572. END_CATCH
  573. return dwRetVal;
  574. }
  575. //+-------------------------------------------------------------------------
  576. //
  577. // Function: OcCleanup
  578. //
  579. // Synopsis: Finish setup work now that everything else is installed. It
  580. // would be better to do this in OC_COMPLETE_INSTALLATION, but
  581. // there is no guarantee IIS is installed by that point.
  582. //
  583. // History: 11-3-98 dlee Created
  584. //
  585. //--------------------------------------------------------------------------
  586. void OcCleanup( CError & Err )
  587. {
  588. //
  589. // Add metabase settings if IIS is around
  590. //
  591. TRY
  592. {
  593. if ( !g_fInstallCancelled )
  594. SetupW3Svc(Err);
  595. }
  596. CATCH( CException, e )
  597. {
  598. // If IIS isn't installed then setting up w3svc will fail. Ignore
  599. isDebugOut(( "caught %#x adding w3svc stuff\n", e.GetErrorCode() ));
  600. }
  601. END_CATCH
  602. //
  603. // Start cisvc service if it was running, we're selected, and not in
  604. // NT setup mode.
  605. //
  606. TRY
  607. {
  608. if ( ( g_fCiSvcWasRunning && !g_cChangeSelection ) ||
  609. ( g_fCiSvcIsRequested && !g_fNtGuiMode && !g_fInstallCancelled ) )
  610. {
  611. StartService(L"CiSvc");
  612. }
  613. }
  614. CATCH( CException, e )
  615. {
  616. // Don't hose the install if we can't start the service
  617. isDebugOut(( "caught %#x starting service\n", e.GetErrorCode() ));
  618. }
  619. END_CATCH
  620. } //OcCleanup
  621. //+-------------------------------------------------------------------------
  622. //
  623. // Function: OpenInfFile
  624. //
  625. // Synopsis: opens a handle to setupqry.inf file
  626. //
  627. // Returns: True upon success, False upon failure.
  628. //
  629. // History: 6-28-97 mohamedn created
  630. //
  631. //--------------------------------------------------------------------------
  632. BOOL OpenInfFile(CError & Err)
  633. {
  634. WCHAR InfPath[MAX_PATH];
  635. DWORD dwRetVal = GetModuleFileName( MyModuleHandle, InfPath, NUMELEM(InfPath));
  636. InfPath[ NUMELEM( InfPath ) - 1 ] = 0;
  637. if ( 0 == dwRetVal )
  638. {
  639. isDebugOut(( DEB_ERROR, "GetModuleFileName() Failed: %d\n", GetLastError() ));
  640. return FALSE;
  641. }
  642. LPWSTR p = wcsrchr( InfPath, L'\\' );
  643. if (p)
  644. {
  645. wcscpy( p+1, L"setupqry.inf" );
  646. gSetupInitComponent.ComponentInfHandle = SetupOpenInfFile( InfPath, NULL, INF_STYLE_WIN4, NULL );
  647. if (gSetupInitComponent.ComponentInfHandle == INVALID_HANDLE_VALUE)
  648. {
  649. isDebugOut(( DEB_ERROR, "SetupOpenInfFile(%ws) Failed: %d\n", InfPath, GetLastError() ));
  650. return FALSE;
  651. }
  652. }
  653. else
  654. {
  655. return FALSE;
  656. }
  657. g_fLocallyOpened = TRUE;
  658. return TRUE;
  659. }
  660. //+-------------------------------------------------------------------------
  661. //
  662. // Function: QueueConfigurationParams
  663. //
  664. // Synopsis: queue-up an inf section to install
  665. //
  666. // Returns: NO_ERROR upon success, win32 error upon failure
  667. //
  668. // History: 6-28-97 mohamedn created
  669. //
  670. //--------------------------------------------------------------------------
  671. DWORD QueueConfigurationParams( HINF hInf, HSPFILEQ Param2, WCHAR const * pwszSectionName, CError &Err )
  672. {
  673. BOOL fOk = SetupInstallFromInfSection( 0,
  674. hInf,
  675. pwszSectionName,
  676. SPINST_REGISTRY,
  677. 0,
  678. 0,
  679. 0,
  680. 0,
  681. 0,
  682. 0,
  683. 0 );
  684. if ( !fOk )
  685. {
  686. isDebugOut(( DEB_ERROR, "SetupInstallFromInfSection(%ws) Failed: %d\n",
  687. pwszSectionName, GetLastError() ));
  688. ISError( IS_MSG_SETUP_INSTALL_FROM_INFSECTION_FAILED, Err,
  689. LogSevError, GetLastError() );
  690. }
  691. return ( fOk ? NO_ERROR : GetLastError() );
  692. }
  693. //+-------------------------------------------------------------------------
  694. //
  695. // Function: SetupW3Svc
  696. //
  697. // Synopsis: Setup catalogs and script mappings for IIS
  698. //
  699. // Arguments: [Err] -- Error reporting object
  700. //
  701. // History: 13-May-1998 KyleP Created
  702. //
  703. //--------------------------------------------------------------------------
  704. void SetupW3Svc(CError &Err)
  705. {
  706. BOOL fCurrentlyChecked = g_HelperRoutines.QuerySelectionState(
  707. g_HelperRoutines.OcManagerContext,
  708. wcsIndexsrvSystem,
  709. OCSELSTATETYPE_CURRENT );
  710. isDebugOut(( "currently checked: %d\n", fCurrentlyChecked ));
  711. TRY
  712. {
  713. do
  714. {
  715. //
  716. // Initialize/Uninitialize COM. Allow any old mode, and allow
  717. // for the fact that some other broken component may have left
  718. // COM initialized.
  719. //
  720. XCom xcom( TRUE );
  721. WCHAR awc[MAX_PATH];
  722. isDebugOut(( "SetupW3Svc\n" ));
  723. isDebugOut(( " g_fCiSvcIsRequested: %d\n", g_fCiSvcIsRequested ));
  724. isDebugOut(( " g_fNtGuiMode: %d\n", g_fNtGuiMode ));
  725. isDebugOut(( " g_cChangeSelection: %d\n", g_cChangeSelection ));
  726. isDebugOut(( " g_dwPrevISVersion: %d \n", g_dwPrevISVersion ));
  727. isDebugOut(( " g_fUpgrade: %d\n", g_fUpgrade ));
  728. {
  729. //
  730. // Is W3Svc even installed?
  731. //
  732. CMetaDataMgr mdMgr( TRUE, W3VRoot );
  733. //
  734. // Guess so. We didn't throw. Now, add the script mappings if
  735. // if appropriate:
  736. //
  737. // If the checkbox is selected, add scriptmaps if
  738. // clean install or
  739. // add/remove and they changed the state of the checkbox
  740. // upgrade and scriptmaps weren't deleted by hand by the user
  741. //
  742. // Delete scriptmaps if
  743. // Checkbox is unchecked and there was a change in the selection state
  744. //
  745. // Note the state of the checked/unchecked variable g_fCiSvcIsRequested
  746. // is only valid in add/remove AND if the user has changed the selection.
  747. // So this code uses fCurrentlyChecked instead.
  748. //
  749. if ( ( fCurrentlyChecked ) &&
  750. ( g_fNtGuiMode || ( 0 != g_cChangeSelection ) ) )
  751. {
  752. //
  753. // IDQ and WEBHITS are always in System32
  754. //
  755. if ( (MAX_PATH - wcslen(g_awcSystemDir)) < 30 ) // DLL won't fit
  756. break;
  757. wcscpy( awc, L".idq," );
  758. wcscat( awc, g_awcSystemDir );
  759. //
  760. // Add IDQ if add/remove OR
  761. // clean install OR
  762. // there is already a scriptmap OR
  763. // there already is a (possibly old) scriptmap pointing at the expected dll
  764. //
  765. //
  766. // Note: the "IIS lockdown" tool points our scriptmaps at
  767. // 404.dll; it doesn't delete them. I have no idea why.
  768. //
  769. //
  770. // scriptmap flags -- 0x2 is obsolete (apparently)
  771. //
  772. // #define MD_SCRIPTMAPFLAG_SCRIPT 0x00000001
  773. // #define MD_SCRIPTMAPFLAG_CHECK_PATH_INFO 0x00000004
  774. //
  775. // Can't check path info for .htw due to null.htw support
  776. //
  777. BOOL fAddSM = ( ( !g_fNtGuiMode ) ||
  778. ( g_fNtGuiMode && !g_fUpgrade ) ||
  779. ( 0 == g_dwPrevISVersion ) );
  780. BOOL fAdded = FALSE;
  781. wcscat( awc, L"\\idq.dll,7,GET,HEAD,POST" );
  782. if ( fAddSM ||
  783. ( mdMgr.ExtensionHasTargetScriptMap( L".idq", L"idq.dll" ) ) )
  784. {
  785. fAdded = TRUE;
  786. mdMgr.AddScriptMap( awc );
  787. }
  788. //
  789. // Add IDA if add/remove or there is already a valid scriptmap
  790. //
  791. awc[3] = L'a';
  792. if ( fAddSM ||
  793. ( mdMgr.ExtensionHasTargetScriptMap( L".ida", L"idq.dll" ) ) )
  794. {
  795. fAdded = TRUE;
  796. mdMgr.AddScriptMap( awc );
  797. }
  798. //
  799. // Add HTW if add/remove or there is already a valid scriptmap
  800. //
  801. wcscpy( awc, L".htw," );
  802. wcscat( awc, g_awcSystemDir );
  803. wcscat( awc, L"\\webhits.dll,3,GET,HEAD,POST" );
  804. if ( fAddSM ||
  805. ( mdMgr.ExtensionHasTargetScriptMap( L".htw", L"webhits.dll" ) ) )
  806. {
  807. fAdded = TRUE;
  808. mdMgr.AddScriptMap( awc );
  809. }
  810. //
  811. // Add IS script maps as in-process. Always do this.
  812. //
  813. wcscpy( awc, g_awcSystemDir );
  814. wcscat( awc, L"\\idq.dll" );
  815. mdMgr.AddInProcessIsapiApp( awc );
  816. //
  817. // By default, run this OOP. The user can run in IP if they need to
  818. // webhit files on remote virtual roots.
  819. //
  820. #if 0
  821. wcscpy( awc, g_awcSystemDir );
  822. wcscat( awc, L"\\webhits.dll" );
  823. mdMgr.AddInProcessIsapiApp( awc );
  824. #endif
  825. //
  826. // Add the Appliation dependencies and restriction list like this:
  827. //
  828. // ApplicationDependencies "Indexing Service;IndexingService"
  829. //
  830. // WebSvcExtRestrictionList:
  831. // "0,c:\windows\system32\idq.dll,0,IndexingService,Indexing Service
  832. // 0,c:\windows\system32\webhits.dll,0,IndexingService,Indexing Service"
  833. //
  834. if ( fAdded )
  835. {
  836. // Delete anything left around from before
  837. mdMgr.RemoveApplicationDependency( pwcIISAppKey );
  838. mdMgr.RemoveRestrictionList( pwcIISAppKey );
  839. // Add the new stuff if the service name isn't huge
  840. CResString strSvcDisplayName( IS_SERVICE_NAME );
  841. WCHAR awcTemp[ MAX_PATH * 2 ];
  842. if ( wcslen( strSvcDisplayName.Get() ) < ( MAX_PATH - 50 ) )
  843. {
  844. wcscpy( awcTemp, strSvcDisplayName.Get() );
  845. wcscat( awcTemp, L";" );
  846. wcscat( awcTemp, pwcIISAppKey );
  847. mdMgr.AddApplicationDependency( awcTemp );
  848. wcscpy( awcTemp, L"0," );
  849. wcscat( awcTemp, g_awcSystemDir );
  850. wcscat( awcTemp, L"\\idq.dll,0," );
  851. wcscat( awcTemp, pwcIISAppKey );
  852. wcscat( awcTemp, L"," );
  853. wcscat( awcTemp, strSvcDisplayName.Get() );
  854. mdMgr.AddRestrictionList( awcTemp );
  855. wcscpy( awcTemp, L"0," );
  856. wcscat( awcTemp, g_awcSystemDir );
  857. wcscat( awcTemp, L"\\webhits.dll,0," );
  858. wcscat( awcTemp, pwcIISAppKey );
  859. wcscat( awcTemp, L"," );
  860. wcscat( awcTemp, strSvcDisplayName.Get() );
  861. mdMgr.AddRestrictionList( awcTemp );
  862. }
  863. }
  864. }
  865. if ( ( !fCurrentlyChecked ) && ( 0 != g_cChangeSelection ) )
  866. {
  867. mdMgr.RemoveScriptMap( L".idq" );
  868. mdMgr.RemoveScriptMap( L".ida" );
  869. mdMgr.RemoveScriptMap( L".htw" );
  870. mdMgr.RemoveApplicationDependency( pwcIISAppKey );
  871. mdMgr.RemoveRestrictionList( pwcIISAppKey );
  872. }
  873. //
  874. // Make sure it makes it out to disk
  875. //
  876. mdMgr.Flush();
  877. }
  878. //
  879. // Only create a web catalog if everything looks like a new install...
  880. //
  881. BOOL fNew = FALSE;
  882. TRY
  883. {
  884. CWin32RegAccess reg( HKEY_LOCAL_MACHINE, wcsRegCatalogsWebSubKey );
  885. if ( reg.Ok() )
  886. {
  887. WCHAR wcsSubKeyName[MAX_PATH+1];
  888. DWORD cwcName = sizeof wcsSubKeyName / sizeof WCHAR;
  889. if ( reg.Enum( wcsSubKeyName, cwcName ) )
  890. {
  891. // There is at least one subkey
  892. do
  893. {
  894. //
  895. // if there is a subkey other than properties,
  896. // we're not createing a new web catalog
  897. //
  898. if ( 0 != _wcsicmp( wcsSubKeyName, wszProperties ) )
  899. {
  900. fNew = FALSE;
  901. break;
  902. }
  903. else
  904. fNew = TRUE;
  905. } while ( reg.Enum( wcsSubKeyName, cwcName ) );
  906. }
  907. else
  908. fNew = TRUE;
  909. }
  910. else
  911. fNew = TRUE;
  912. }
  913. CATCH( CException, e )
  914. {
  915. fNew = TRUE;
  916. }
  917. END_CATCH
  918. if ( !fNew )
  919. break;
  920. //
  921. // Must look like a default install...
  922. //
  923. CMetaDataMgr mdMgrDefaultServer( FALSE, W3VRoot, 1 );
  924. mdMgrDefaultServer.GetVRoot( L"/", awc );
  925. unsigned ccRoot = wcslen(awc) - 8; // <path> - "\wwwroot"
  926. if ( 0 != _wcsicmp( awc + ccRoot, L"\\wwwroot" ) )
  927. break;
  928. awc[ccRoot] = 0;
  929. //
  930. // Add a web catalog.
  931. //
  932. CCatReg CatReg(Err);
  933. CatReg.Init( L"Web", awc );
  934. CatReg.TrackW3Svc();
  935. //
  936. // set ISAPIDefaultCatalogDirectory to Web
  937. //
  938. CWin32RegAccess reg( HKEY_LOCAL_MACHINE, wcsRegAdminSubKey );
  939. if ( !reg.Set( wcsISDefaultCatalogDirectory, L"Web" ) )
  940. {
  941. ISError( IS_MSG_COULD_NOT_MODIFY_REGISTRY, Err,
  942. LogSevWarning, GetLastError() );
  943. return;
  944. }
  945. } while(FALSE);
  946. isDebugOut(( "successfully added w3svc stuff\n" ));
  947. }
  948. CATCH( CException, e )
  949. {
  950. isDebugOut(( "caught %x in SetupW3Svc\n", e.GetErrorCode() ));
  951. }
  952. END_CATCH
  953. }
  954. //+-------------------------------------------------------------------------
  955. //
  956. // Function: CompleteInstallation
  957. //
  958. // Synopsis: called by NT setup to cofigure Index server for operation.
  959. //
  960. // Returns: SCODE, S_OK upon success, other values upon failure
  961. //
  962. // History: 6-28-97 mohamedn created
  963. //
  964. //--------------------------------------------------------------------------
  965. DWORD CompleteInstallation(CError &Err)
  966. {
  967. SCODE sc = S_OK;
  968. DWORD dwRetVal = 0;
  969. DWORD dwLastError = 0;
  970. //MessageBox(NULL, L"BREAK HERE", NULL, MB_OK);
  971. TRY
  972. {
  973. //
  974. // Delete the "DonotStartCiSvc" registry parameter
  975. //
  976. CWin32RegAccess reg( HKEY_LOCAL_MACHINE, wcsRegAdminSubKey );
  977. reg.Remove(wcsPreventCisvcParam);
  978. dwRetVal = SetDLLsToRegister (Err);
  979. if ( NO_ERROR != dwRetVal )
  980. {
  981. isDebugOut(( DEB_ERROR, "SetDllsToRegister Failed: %d", dwRetVal ));
  982. ISError( IS_MSG_SetDllsToRegister_FAILED, Err, LogSevError, dwRetVal );
  983. THROW(CException(HRESULT_FROM_WIN32(dwRetVal)) );
  984. }
  985. dwRetVal = SetFilterRegistryInfo(FALSE, Err);
  986. if ( NO_ERROR != dwRetVal )
  987. {
  988. isDebugOut(( DEB_ERROR, "SetFilterRegistryInfo Failed: %d", dwRetVal ));
  989. ISError( IS_MSG_SetFilterRegistryInfo_FAILED, Err, LogSevError, dwRetVal );
  990. THROW(CException(HRESULT_FROM_WIN32(dwRetVal)) );
  991. }
  992. dwRetVal = AddPerfData(Err);
  993. if ( NO_ERROR != dwRetVal )
  994. {
  995. isDebugOut(( DEB_ERROR, "AddPerfData Failed: %d\n",dwRetVal));
  996. THROW(CException(HRESULT_FROM_WIN32(dwRetVal)) );
  997. }
  998. //
  999. // stop cisvc
  1000. //
  1001. StopService(L"cisvc");
  1002. //
  1003. // Upgrade 1.1 to 3.0 if needed. Must happen *before* AddCiSvc().
  1004. //
  1005. UpgradeIS1toIS3(Err);
  1006. //
  1007. // Delete the NTOP start menu items IS created
  1008. //
  1009. DeleteNTOPStartMenu();
  1010. //
  1011. // configure catalogs
  1012. //
  1013. dwRetVal = SetDefaultCatalog(Err);
  1014. if ( NO_ERROR != dwRetVal )
  1015. {
  1016. isDebugOut(( DEB_ERROR, "SetDefaultCatalog Failed: %d\n",dwRetVal));
  1017. ISError( IS_MSG_SetDefaultCatalog_FAILED, Err, LogSevError, dwRetVal );
  1018. THROW(CException(HRESULT_FROM_WIN32(dwRetVal)) );
  1019. }
  1020. //
  1021. // if selection count is odd (user changed the selection),
  1022. // delete the service to create a new one. Also delete and
  1023. // re-create if we're upgrading IS 1.x.
  1024. //
  1025. if ( ( !g_fUpgrade && ( g_cChangeSelection & 0x1 ) ) ||
  1026. 1 == g_dwPrevISVersion )
  1027. DeleteService(L"cisvc");
  1028. //
  1029. // add the service
  1030. //
  1031. AddCiSvc(Err);
  1032. }
  1033. CATCH( CException, e )
  1034. {
  1035. isDebugOut(( DEB_ERROR, "Caught Exception in CompleteInstallation: %d\n",e.GetErrorCode() ));
  1036. ISError( IS_MSG_EXCEPTION_CAUGHT, Err, LogSevError, e.GetErrorCode() );
  1037. sc = e.GetErrorCode();
  1038. isDebugOut(( "Caught Exception in CompleteInstallation: %#x\n", sc ));
  1039. }
  1040. END_CATCH
  1041. return sc;
  1042. } //CompleteInstallation
  1043. //+-------------------------------------------------------------------------
  1044. //
  1045. // Function: UpgradeIS1toIS3
  1046. //
  1047. // Synopsis: sets ISapiDefaultCatalogDirectory param if we're upgrading
  1048. // from 1.0 or 1.1 to 3.0
  1049. //
  1050. // Returns: none.
  1051. //
  1052. // History: 01-May-1998 mohamedn created
  1053. // 05-Sep-1998 KyleP Start service on upgrade
  1054. //
  1055. // Notes: This *must* be called before AddCisvc, since the decision
  1056. // about whether to start the service may be changed in
  1057. // this function.
  1058. //
  1059. //--------------------------------------------------------------------------
  1060. void UpgradeIS1toIS3(CError &Err)
  1061. {
  1062. if ( !g_fNT4_To_NT5_Upgrade || g_dwPrevISVersion >= 2 )
  1063. {
  1064. return;
  1065. }
  1066. g_awcIS1Path[0] = L'\0';
  1067. {
  1068. CWin32RegAccess reg( HKEY_LOCAL_MACHINE, wcsRegAdminSubKey );
  1069. reg.Get( wcsISDefaultCatalogDirectory, g_awcIS1Path, NUMELEM( g_awcIS1Path ) );
  1070. if ( 0 == wcslen(g_awcIS1Path) || g_awcIS1Path[1] != L':' )
  1071. {
  1072. //
  1073. // nothing to do.
  1074. //
  1075. g_awcIS1Path[0] = L'\0';
  1076. return;
  1077. }
  1078. }
  1079. //
  1080. // The 'Catalogs' key needs to be created.
  1081. //
  1082. {
  1083. CWin32RegAccess reg( HKEY_LOCAL_MACHINE, wcsRegAdminSubKey );
  1084. BOOL fExisted;
  1085. if ( !reg.CreateKey( L"Catalogs", fExisted ) )
  1086. {
  1087. DWORD dw = GetLastError();
  1088. isDebugOut(( DEB_ERROR, "created catalogs subkey Failed: %d\n", dw ));
  1089. ISError( IS_MSG_COULD_NOT_CONFIGURE_CATALOGS, Err , LogSevFatalError, dw );
  1090. return;
  1091. }
  1092. }
  1093. //
  1094. // create the web catalog
  1095. //
  1096. CCatReg CatReg(Err);
  1097. CatReg.Init( L"Web", g_awcIS1Path );
  1098. CatReg.TrackW3Svc();
  1099. //
  1100. // set ISAPIDefaultCatalogDirectory to Web
  1101. //
  1102. CWin32RegAccess reg( HKEY_LOCAL_MACHINE, wcsRegAdminSubKey );
  1103. if ( !reg.Set( wcsISDefaultCatalogDirectory, L"Web" ) )
  1104. {
  1105. ISError(IS_MSG_COULD_NOT_MODIFY_REGISTRY , Err, LogSevWarning, GetLastError() );
  1106. return;
  1107. }
  1108. //
  1109. // CI was running before the upgrade, so make sure it is running after
  1110. // the upgrade as well.
  1111. //
  1112. g_fCiSvcIsRequested = TRUE;
  1113. }
  1114. //+-------------------------------------------------------------------------
  1115. //
  1116. // Function: GetPreviousISSetupVersion
  1117. //
  1118. // Synopsis: gets version of previous installed IS, if any.
  1119. //
  1120. // Arguments: none
  1121. //
  1122. // Returns: none
  1123. //
  1124. // History: 10-16-97 mohamedn created
  1125. //
  1126. //--------------------------------------------------------------------------
  1127. void GetPreviousISSetupVersion(void)
  1128. {
  1129. HKEY hKey = 0;
  1130. DWORD dwType = 0;
  1131. DWORD dwVal = 0;
  1132. DWORD cb = sizeof DWORD;
  1133. //
  1134. // If it's not an upgrade, don't try to get the previous version as someone is
  1135. // now writing contentindex\DoNotStartCisvc to the registry so we would
  1136. // otherwise assume it's an upgrade without this check.
  1137. //
  1138. if ( !g_fUpgrade )
  1139. return;
  1140. LONG lRetVal = RegOpenKeyEx( HKEY_LOCAL_MACHINE, wcsRegAdminSubKey, 0, KEY_READ, &hKey );
  1141. if ( ERROR_SUCCESS == lRetVal )
  1142. {
  1143. lRetVal = RegQueryValueEx( hKey,
  1144. L"MajorVersion",
  1145. 0,
  1146. &dwType,
  1147. (BYTE *)&dwVal,
  1148. &cb );
  1149. if ( ERROR_SUCCESS == lRetVal )
  1150. g_dwPrevISVersion = dwVal;
  1151. else
  1152. g_dwPrevISVersion = 1; // We didn't write this key in V1.
  1153. RegCloseKey( hKey );
  1154. }
  1155. }
  1156. //+-------------------------------------------------------------------------
  1157. //
  1158. // Function: SetDefaultCatalog
  1159. //
  1160. // Synopsis: Configures IS catalog for indexing local file system based on
  1161. // available disk space.
  1162. //
  1163. // Arguments: none
  1164. //
  1165. // Returns: ErrorSuccess upon success, error value upon failure.
  1166. //
  1167. // History: 9-10-97 mohamedn
  1168. //
  1169. //--------------------------------------------------------------------------
  1170. DWORD SetDefaultCatalog(CError &Err)
  1171. {
  1172. BOOL fExisted;
  1173. DWORD dwRetVal = NO_ERROR;
  1174. if ( !IsSufficientMemory() )
  1175. {
  1176. ISError( IS_MSG_BAD_MACHINE, Err, LogSevError );
  1177. ISError( IS_MSG_NEEDED_HARDWARE, Err, LogSevError );
  1178. return ERROR_SUCCESS;
  1179. }
  1180. {
  1181. CWin32RegAccess reg( HKEY_LOCAL_MACHINE, wcsRegAdminSubKey );
  1182. if (!reg.CreateKey( L"Catalogs", fExisted ) )
  1183. {
  1184. DWORD dw = GetLastError();
  1185. isDebugOut(( DEB_ERROR, "created catalogs subkey Failed: %d\n", dw ));
  1186. ISError( IS_MSG_COULD_NOT_CONFIGURE_CATALOGS, Err , LogSevFatalError, dw );
  1187. return dw;
  1188. }
  1189. }
  1190. //
  1191. // return if Catalogs key exists, don't overwrite existing configuration
  1192. //
  1193. if ( fExisted && !g_fNT4_To_NT5_Upgrade )
  1194. {
  1195. return ERROR_SUCCESS;
  1196. }
  1197. //
  1198. // Find the default profile path (Usually %windir%\Profiles)
  1199. //
  1200. CWin32RegAccess regProfileKey( HKEY_LOCAL_MACHINE, wszRegProfileKey );
  1201. g_awcProfilePath[0] = L'\0';
  1202. WCHAR wcTemp[MAX_PATH+1];
  1203. if ( regProfileKey.Get( wszRegProfileValue, wcTemp, NUMELEM(wcTemp) ) )
  1204. {
  1205. unsigned ccTemp2 = ExpandEnvironmentStrings( wcTemp,
  1206. g_awcProfilePath,
  1207. NUMELEM(g_awcProfilePath) );
  1208. }
  1209. CCatalogConfig Cat(Err);
  1210. Cat.SetName( L"System" );
  1211. if ( !Cat.InitDriveList() )
  1212. {
  1213. ISError( IS_MSG_DRIVE_ENUMERATION_FAILED, Err, LogSevError, GetLastError() );
  1214. return ERROR_INSTALL_FAILURE;
  1215. }
  1216. BOOL bRetVal = Cat.ConfigureDefaultCatalog( g_awcProfilePath );
  1217. if (bRetVal)
  1218. {
  1219. //
  1220. // add paths to exclude indexing IE temp files.
  1221. //
  1222. ExcludeSpecialLocations( Cat );
  1223. //
  1224. // Set the catalog location
  1225. wcsncpy(wcTemp, wszSysVolInfoDirectory, sizeof wcTemp / sizeof WCHAR);
  1226. wcTemp[ (sizeof wcTemp / sizeof WCHAR) - 1 ] = 0;
  1227. wcTemp[0] = *(Cat.GetCatalogDrive());
  1228. Cat.SetLocation( wcTemp );
  1229. // NOTE: The catalog path will be created when first accessed by
  1230. // CClientDocStore.
  1231. Cat.SaveState();
  1232. }
  1233. return ( bRetVal ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE );
  1234. }
  1235. //+-------------------------------------------------------------------------
  1236. //
  1237. // Function: SetDLLsToRegister
  1238. //
  1239. // Synopsis: Sets the "DLLsToRegister" value in the registry
  1240. //
  1241. // History: 19-Jun-97 t-elainc Created
  1242. //
  1243. //--------------------------------------------------------------------------
  1244. DWORD SetDLLsToRegister(CError &Err)
  1245. {
  1246. WCHAR * apwc2[cDlls];
  1247. unsigned cwcTotal = 1;
  1248. // store full pathnames in array 2
  1249. for (int i = 0; i < cDlls; i++)
  1250. {
  1251. unsigned cwc = wcslen( g_awcSystemDir ) + 1 + wcslen( apwcDlls[i] );
  1252. if ( cwc >= MAX_PATH )
  1253. return 0;
  1254. WCHAR filepath[MAX_PATH];
  1255. wcscpy(filepath, g_awcSystemDir );
  1256. wcscat(filepath, L"\\" );
  1257. wcscat(filepath, apwcDlls[i] );
  1258. cwcTotal += ( cwc + 1 );
  1259. apwc2[i] = new WCHAR[MAX_PATH];
  1260. wcscpy(apwc2[i], filepath);
  1261. }
  1262. WCHAR * apwc2Old[cOldDlls];
  1263. // store full old pathnames in array 2
  1264. for (i = 0; i < cOldDlls; i++)
  1265. {
  1266. unsigned cwc = wcslen( g_awcSystemDir ) + 1 + wcslen( apwcOldDlls[i] );
  1267. if ( cwc >= MAX_PATH )
  1268. return 0;
  1269. WCHAR filepath[MAX_PATH];
  1270. wcscpy(filepath, g_awcSystemDir );
  1271. wcscat(filepath, L"\\" );
  1272. wcscat(filepath, apwcOldDlls[i] );
  1273. apwc2Old[i] = new WCHAR[MAX_PATH];
  1274. wcscpy(apwc2Old[i], filepath);
  1275. }
  1276. if ( cwcTotal >= 4096 )
  1277. return 0;
  1278. unsigned cwcRemaining = 4096 - cwcTotal;
  1279. WCHAR awc[4096]; //buffer for new list
  1280. WCHAR *pwc = awc; //pointer to list
  1281. *pwc = 0; //set first slot in array to null
  1282. // put our dlls in the beginning
  1283. for (int i = 0; i < cDlls; i++)
  1284. pwc = AppendMultiSZString(pwc, apwc2[i]);
  1285. CWin32RegAccess reg( HKEY_LOCAL_MACHINE, wcsRegAdminSubKey );
  1286. {
  1287. WCHAR awcOld[4096]; //the old buffer list of files to register
  1288. if ( reg.Get( L"DLLsToRegister",
  1289. awcOld,
  1290. sizeof awcOld / sizeof WCHAR ) )
  1291. {
  1292. WCHAR *p = awcOld;
  1293. while ( 0 != *p )
  1294. {
  1295. // Leave dlls not in our list -- 3rd party dlls
  1296. BOOL fFound = FALSE;
  1297. for ( int i = 0; i < cDlls; i++ )
  1298. {
  1299. if (!_wcsicmp(p, apwc2[i]) )
  1300. {
  1301. fFound = TRUE;
  1302. break;
  1303. }
  1304. }
  1305. // Remove old dlls from the list (fsci & cifrmwrk)
  1306. if ( !fFound )
  1307. {
  1308. for ( int i = 0; i < cOldDlls; i++ )
  1309. {
  1310. if (!_wcsicmp(p, apwc2Old[i]) )
  1311. {
  1312. fFound = TRUE;
  1313. break;
  1314. }
  1315. }
  1316. }
  1317. if (!fFound)
  1318. {
  1319. cwcTotal += ( wcslen( p ) + 1 );
  1320. if ( cwcTotal >= 4096 )
  1321. return 0;
  1322. pwc = AppendMultiSZString(pwc, p);
  1323. }
  1324. p += ( wcslen(p) + 1 );
  1325. }
  1326. }
  1327. *pwc++ = 0;
  1328. }
  1329. for (int j = 0; j < cDlls; j++)
  1330. delete apwc2[j];
  1331. for (j = 0; j < cOldDlls; j++)
  1332. delete apwc2Old[j];
  1333. if ( !reg.SetMultiSZ( L"DLLsToRegister",
  1334. awc,
  1335. (ULONG)(pwc-awc) * sizeof WCHAR ) )
  1336. {
  1337. DWORD dw = GetLastError();
  1338. ISError( IS_MSG_COULD_NOT_MODIFY_REGISTRY, Err, LogSevFatalError, dw );
  1339. return dw;
  1340. }
  1341. return NO_ERROR;
  1342. } //SetDLLsToRegister
  1343. //+-------------------------------------------------------------------------
  1344. //
  1345. // Function: AppendMultiSZString
  1346. //
  1347. // Synopsis: Copies one string to another.
  1348. //
  1349. // Returns: Pointer to one wchar beyond the end of the copy
  1350. //
  1351. // History: 8-Jan-97 dlee Created
  1352. //
  1353. //--------------------------------------------------------------------------
  1354. WCHAR * AppendMultiSZString(
  1355. WCHAR * pwcTo,
  1356. WCHAR const * pwcFrom )
  1357. {
  1358. isDebugOut((DEB_TRACE, "language or dll installed: '%ws'\n", pwcFrom ));
  1359. unsigned x = wcslen( pwcFrom );
  1360. wcscpy( pwcTo, pwcFrom );
  1361. return pwcTo + x + 1;
  1362. } //AppendMultiSZString
  1363. //+-------------------------------------------------------------------------
  1364. //
  1365. // Function: ExcludeSpecialLocations, private
  1366. //
  1367. // Synopsis: Writes profile-based exclude scopes into the registry
  1368. //
  1369. // Arguments: none
  1370. //
  1371. // History: 28-Aug-1998 KyleP Created
  1372. //
  1373. //--------------------------------------------------------------------------
  1374. WCHAR const wszRegShellSpecialPathsKey[] =
  1375. L".DEFAULT\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
  1376. WCHAR const * const awszRegShellSpecialPathsValue[] = {
  1377. L"AppData",
  1378. L"Local Settings"
  1379. };
  1380. WCHAR const wszUserProfile[] = L"%USERPROFILE%";
  1381. void ExcludeSpecialLocations( CCatalogConfig & Cat )
  1382. {
  1383. //
  1384. // First, find the default profile path (Usually %windir%\Profiles)
  1385. //
  1386. WCHAR wcTemp[MAX_PATH+1];
  1387. if ( g_awcProfilePath[0] )
  1388. {
  1389. WCHAR wcTemp2[MAX_PATH+1];
  1390. wcsncpy( wcTemp2, g_awcProfilePath, sizeof wcTemp2 / sizeof WCHAR );
  1391. wcTemp2[ (sizeof wcTemp2 / sizeof WCHAR) - 1 ] = 0;
  1392. unsigned ccTemp2 = wcslen( wcTemp2 );
  1393. //
  1394. // Append the wildcard, for user profile directory
  1395. //
  1396. wcscpy( wcTemp2 + ccTemp2, L"\\*\\" );
  1397. ccTemp2 += 3;
  1398. //
  1399. // Go through and look for special shell paths, which just happen
  1400. // to include all our special cases too.
  1401. //
  1402. CWin32RegAccess regShellSpecialPathsKey( HKEY_USERS, wszRegShellSpecialPathsKey );
  1403. for ( unsigned i = 0;
  1404. i < NUMELEM(awszRegShellSpecialPathsValue);
  1405. i++ )
  1406. {
  1407. if ( regShellSpecialPathsKey.Get( awszRegShellSpecialPathsValue[i],
  1408. wcTemp, NUMELEM(wcTemp), FALSE) )
  1409. {
  1410. if ( RtlEqualMemory( wszUserProfile, wcTemp,
  1411. sizeof(wszUserProfile) - sizeof(WCHAR) ) )
  1412. {
  1413. wcscpy( wcTemp2 + ccTemp2, wcTemp + NUMELEM(wszUserProfile) );
  1414. wcscpy( wcTemp, wcTemp2 );
  1415. }
  1416. if ( wcschr( wcTemp, L'%' ) != 0 )
  1417. {
  1418. WCHAR wcTemp3[MAX_PATH+1];
  1419. unsigned ccTemp3 = ExpandEnvironmentStrings(
  1420. wcTemp,
  1421. wcTemp3,
  1422. NUMELEM(wcTemp3) );
  1423. if ( 0 != ccTemp3 )
  1424. wcscpy( wcTemp, wcTemp3 );
  1425. }
  1426. wcscat( wcTemp, L"\\*" );
  1427. isDebugOut(( DEB_TRACE, "Exclude: %ws\n", wcTemp ));
  1428. Cat.AddExcludedDirOrPattern( wcTemp );
  1429. }
  1430. }
  1431. }
  1432. }
  1433. //+-------------------------------------------------------------------------
  1434. //
  1435. // Function: AddPerfData
  1436. //
  1437. // Synopsis: Runs unlodctr and lodctr on Index Server perf data
  1438. //
  1439. // History: 8-Jan-97 dlee Created
  1440. //
  1441. //--------------------------------------------------------------------------
  1442. DWORD AddPerfData(CError &Err)
  1443. {
  1444. // add counters if installing
  1445. DWORD dwError = NO_ERROR;
  1446. // remove existing counters (if they exist)
  1447. RemovePerfData();
  1448. isDebugOut((DEB_TRACE, "Installing perf data\n" ));
  1449. dwError = LoadCounterAndDelete( L"perfci.ini", L"perfci.h", Err );
  1450. if ( ERROR_SUCCESS == dwError )
  1451. {
  1452. dwError = LoadCounterAndDelete( L"perffilt.ini", L"perffilt.h", Err );
  1453. if ( ERROR_SUCCESS == dwError )
  1454. {
  1455. dwError = LoadCounterAndDelete( L"perfwci.ini", L"perfwci.h", Err );
  1456. }
  1457. }
  1458. return NO_ERROR; // Ignore failures return dwError;
  1459. } //AddPerfData
  1460. //+-------------------------------------------------------------------------
  1461. //
  1462. // Function: LoadCounterAndDelete
  1463. //
  1464. // Synopsis: Loads perf counters for a .ini and a .h, then deletes
  1465. // the files. Assumes the files are in system32.
  1466. //
  1467. // Arguments: [pwcINI] -- Name w/o path of .ini file.
  1468. // [pwcH] -- Name w/o path of .h file.
  1469. //
  1470. // History: 30-Jan-97 dlee Created
  1471. // 23-May-97 KyleP Use LoadPerfCounterTextStrings API
  1472. //
  1473. //--------------------------------------------------------------------------
  1474. DWORD LoadCounterAndDelete(
  1475. WCHAR const * pwcINI,
  1476. WCHAR const * pwcH,
  1477. CError &Err)
  1478. {
  1479. unsigned cwc = wcslen( L"lodctr " ) + wcslen( g_awcSystemDir ) + 1 + wcslen( pwcINI );
  1480. if ( cwc >= MAX_PATH )
  1481. return 0;
  1482. WCHAR awc[MAX_PATH];
  1483. WCHAR const awcLodctr[] = L"lodctr ";
  1484. wcscpy( awc, awcLodctr );
  1485. wcscat( awc, g_awcSystemDir );
  1486. wcscat( awc, L"\\" );
  1487. wcscat( awc, pwcINI );
  1488. DWORD dwError = (DWORD)LoadPerfCounterTextStrings( awc, // .INI file
  1489. TRUE ); // Quiet mode
  1490. if ( ERROR_SUCCESS != dwError )
  1491. {
  1492. isDebugOut(( DEB_ERROR, "Error %d from LoadPerfCounterTextStrings %ws\n", dwError, awc ));
  1493. isDebugOut(( "Error %d from LoadPerfCounterTextStrings %ws\n", dwError, awc ));
  1494. ISError( IS_MSG_LoadPerfCounterTextStrings_FAILED, Err, LogSevError, dwError );
  1495. return dwError;
  1496. }
  1497. return dwError;
  1498. } //LoadCounterAndDelete
  1499. //+-------------------------------------------------------------------------
  1500. //
  1501. // Function: RemovePerfData
  1502. //
  1503. // Synopsis: Runs unlodctr and lodctr on Index Server perf data
  1504. //
  1505. // History: 08-Jan-97 dlee Created
  1506. // 23-May-97 KyleP Use UnloadPerfCounterTextStrings API
  1507. //
  1508. //--------------------------------------------------------------------------
  1509. DWORD RemovePerfData()
  1510. {
  1511. // remove existing counters (if they exist )
  1512. DWORD dw0 = (DWORD)UnloadPerfCounterTextStrings( L"unlodctr ContentIndex", // Key
  1513. TRUE ); // Quiet mode
  1514. DWORD dw1 = (DWORD)UnloadPerfCounterTextStrings( L"unlodctr ContentFilter", // Key
  1515. TRUE ); // Quiet mode
  1516. DWORD dw2 = (DWORD)UnloadPerfCounterTextStrings( L"unlodctr ISAPISearch", // Key
  1517. TRUE ); // Quiet mode
  1518. if ( NO_ERROR != dw0 )
  1519. {
  1520. isDebugOut(( DEB_ERROR, "RemovePerfData: unlodctr ContentIndex failed with 0x%x\n", dw0));
  1521. return dw0;
  1522. }
  1523. else if ( NO_ERROR != dw1 )
  1524. {
  1525. isDebugOut(( DEB_ERROR, "RemovePerfData: unlodctr ContentFilter failed with 0x%x\n", dw1));
  1526. return dw1;
  1527. }
  1528. else
  1529. {
  1530. if ( NO_ERROR != dw2 )
  1531. {
  1532. isDebugOut(( DEB_ERROR, "RemovePerfData: unlodctr ISAPISearch failed with 0x%x\n", dw0));
  1533. }
  1534. return dw2;
  1535. }
  1536. } //RemovePerfData
  1537. //+-------------------------------------------------------------------------
  1538. //
  1539. // Function: IsSufficientMemory
  1540. //
  1541. // Synopsis: Determines available physical memory
  1542. //
  1543. // Arguments: none
  1544. //
  1545. // Returns: TRUE if physical memory > required phys. memory
  1546. // FALSE otherwise.
  1547. //
  1548. // History: 6-27-97 mohamedn created
  1549. //
  1550. //--------------------------------------------------------------------------
  1551. BOOL IsSufficientMemory(void)
  1552. {
  1553. // 32MB RAM.machine, taking into account up to 1M used by the system.
  1554. const ULONGLONG MIN_PHYSICAL_MEMORY = 30*ONE_MB;
  1555. MEMORYSTATUSEX memoryStatus;
  1556. RtlZeroMemory(&memoryStatus, sizeof memoryStatus );
  1557. memoryStatus.dwLength = sizeof memoryStatus;
  1558. GlobalMemoryStatusEx(&memoryStatus);
  1559. return ( MIN_PHYSICAL_MEMORY <= memoryStatus.ullTotalPhys );
  1560. }
  1561. //+-------------------------------------------------------------------------
  1562. //
  1563. // Function: AddCiSvc
  1564. //
  1565. // Synopsis: Creates the cisvc service
  1566. //
  1567. // Arguments: [Err] -- The error object to update
  1568. //
  1569. // Returns: none - throws upon fatal failure
  1570. //
  1571. // History: 6-29-97 mohamedn created
  1572. //
  1573. //--------------------------------------------------------------------------
  1574. void AddCiSvc(CError &Err)
  1575. {
  1576. DWORD dwLastError = 0;
  1577. SC_HANDLE hSC = OpenSCManager( 0, 0, SC_MANAGER_CREATE_SERVICE );
  1578. CServiceHandle xhSC(hSC);
  1579. if( 0 == hSC )
  1580. {
  1581. dwLastError = GetLastError();
  1582. isDebugOut(( DEB_ITRACE, "OpenSCManager() Failed: %x\n", dwLastError ));
  1583. THROW( CException(HRESULT_FROM_WIN32(dwLastError)) );
  1584. }
  1585. WCHAR wszServiceDependencyList[MAX_PATH];
  1586. RtlZeroMemory(wszServiceDependencyList, MAX_PATH * sizeof WCHAR );
  1587. wcscpy( wszServiceDependencyList, L"RPCSS" );
  1588. WCHAR wszServicePath[300];
  1589. unsigned cwc = wcslen( g_awcSystemDir ) + wcslen( L"\\cisvc.exe" );
  1590. if ( cwc >= ( sizeof wszServicePath / sizeof WCHAR ) )
  1591. return;
  1592. wcscpy(wszServicePath, g_awcSystemDir );
  1593. wcscat(wszServicePath, L"\\cisvc.exe" );
  1594. do
  1595. {
  1596. dwLastError = 0;
  1597. CResString strSvcDisplayName(IS_SERVICE_NAME);
  1598. SC_HANDLE hNewSC = CreateService( hSC, // handle to SCM database
  1599. TEXT("cisvc"), // pointer to name of service to start
  1600. strSvcDisplayName.Get(), // pointer to display name
  1601. SERVICE_ALL_ACCESS, // type of access to service
  1602. SERVICE_WIN32_SHARE_PROCESS, // type of service
  1603. g_fCiSvcIsRequested ?
  1604. SERVICE_AUTO_START :
  1605. SERVICE_DISABLED, // when to start service
  1606. SERVICE_ERROR_NORMAL, // severity if service fails to start
  1607. wszServicePath,
  1608. NULL, // pointer to name of load ordering group
  1609. NULL, // pointer to variable to get tag identifier
  1610. wszServiceDependencyList, // pointer to array of dependency names
  1611. NULL, // pointer to account name of service
  1612. NULL // pointer to password for service account
  1613. );
  1614. CServiceHandle xService( hNewSC );
  1615. if ( 0 == hNewSC )
  1616. {
  1617. dwLastError = GetLastError();
  1618. if ( ERROR_SERVICE_EXISTS == dwLastError )
  1619. dwLastError = RenameCiSvc( hSC, Err );
  1620. else if ( ERROR_SERVICE_MARKED_FOR_DELETE != dwLastError )
  1621. {
  1622. isDebugOut(( DEB_ERROR, "CreateService() Failed: %x\n", dwLastError ));
  1623. ISError( IS_MSG_CreateService_FAILED, Err, LogSevError, dwLastError );
  1624. THROW( CException(HRESULT_FROM_WIN32(dwLastError)) );
  1625. }
  1626. }
  1627. else
  1628. {
  1629. xService.Free();
  1630. // We added the service, now set the description.
  1631. RenameCiSvc( hSC, Err );
  1632. }
  1633. } while ( ERROR_SERVICE_MARKED_FOR_DELETE == dwLastError );
  1634. } //AddCiSvc
  1635. //+-------------------------------------------------------------------------
  1636. //
  1637. // Function: RenameCiSvc
  1638. //
  1639. // Synopsis: Renames the cisvc service to "Indexing Service".
  1640. //
  1641. // History: 05-Sep-1998 KyleP Created
  1642. //
  1643. //--------------------------------------------------------------------------
  1644. DWORD RenameCiSvc( SC_HANDLE hSC, CError &Err)
  1645. {
  1646. DWORD dwLastError = 0;
  1647. SC_HANDLE hCisvc = OpenService( hSC, L"cisvc", SERVICE_CHANGE_CONFIG );
  1648. CServiceHandle xhCisvc( hCisvc );
  1649. if( 0 == hCisvc )
  1650. {
  1651. dwLastError = GetLastError();
  1652. isDebugOut(( DEB_ERROR, "OpenService(cisvc) Failed: 0x%x\n", dwLastError ));
  1653. THROW( CException(HRESULT_FROM_WIN32(dwLastError)) );
  1654. }
  1655. CResString strSvcDisplayName(IS_SERVICE_NAME);
  1656. if ( !ChangeServiceConfig( hCisvc, // handle to service
  1657. SERVICE_NO_CHANGE, // type of service
  1658. SERVICE_NO_CHANGE, // when to start service
  1659. SERVICE_NO_CHANGE, // severity if service fails to start
  1660. 0, // pointer to service binary file name
  1661. 0, // pointer to load ordering group name
  1662. 0, // pointer to variable to get tag identifier
  1663. 0, // pointer to array of dependency names
  1664. 0, // pointer to account name of service
  1665. 0, // pointer to password for service account
  1666. strSvcDisplayName.Get() ) ) // pointer to display name);
  1667. {
  1668. dwLastError = GetLastError();
  1669. }
  1670. SERVICE_DESCRIPTION sd;
  1671. CResString strSvcDescription(IS_SERVICE_DESCRIPTION);
  1672. sd.lpDescription = (WCHAR *)strSvcDescription.Get();
  1673. if ( !ChangeServiceConfig2( hCisvc,
  1674. SERVICE_CONFIG_DESCRIPTION,
  1675. (LPVOID)&sd
  1676. )
  1677. )
  1678. dwLastError = GetLastError();
  1679. return dwLastError;
  1680. }
  1681. //+-------------------------------------------------------------------------
  1682. //
  1683. // Function: StopService
  1684. //
  1685. // Synopsis: stops service by name
  1686. //
  1687. // Arguments: pwszServiceName - name of service to stop.
  1688. //
  1689. // Returns: none - throws upon fatal failure
  1690. //
  1691. // History: 6-29-97 mohamedn created
  1692. //
  1693. //--------------------------------------------------------------------------
  1694. void StopService( WCHAR const * pwszServiceName )
  1695. {
  1696. DWORD dwLastError = 0;
  1697. SC_HANDLE hSC = OpenSCManager( 0, 0, SC_MANAGER_ALL_ACCESS );
  1698. CServiceHandle xhSC(hSC);
  1699. if( 0 == hSC )
  1700. {
  1701. dwLastError = GetLastError();
  1702. isDebugOut(( DEB_ERROR, "OpenSCManager() Failed: %x\n", dwLastError ));
  1703. THROW( CException(HRESULT_FROM_WIN32(dwLastError)) );
  1704. }
  1705. //
  1706. // stop cisvc
  1707. //
  1708. BOOL fStopped = FALSE;
  1709. if ( !MyStopService( xhSC, pwszServiceName, fStopped ) && !fStopped )
  1710. {
  1711. //
  1712. // don't throw here
  1713. //
  1714. isDebugOut(( DEB_ERROR, "Failed to stop cisvc service" ));
  1715. }
  1716. }
  1717. //+-------------------------------------------------------------------------
  1718. //
  1719. // Function: StartService
  1720. //
  1721. // Synopsis: start service by name
  1722. //
  1723. // Arguments: pwszServiceName - name of service to stop.
  1724. //
  1725. // Returns: none
  1726. //
  1727. // History: 6-29-97 mohamedn created
  1728. //
  1729. //--------------------------------------------------------------------------
  1730. void StartService( WCHAR const * pwszServiceName )
  1731. {
  1732. DWORD dwLastError = 0;
  1733. SC_HANDLE hSC = OpenSCManager( 0, 0, SC_MANAGER_ALL_ACCESS );
  1734. CServiceHandle xhSC(hSC);
  1735. if( 0 == hSC )
  1736. {
  1737. isDebugOut(( DEB_ERROR, "OpenSCManager() Failed: %x\n", GetLastError() ));
  1738. }
  1739. else
  1740. {
  1741. //
  1742. // start cisvc
  1743. //
  1744. MyStartService( xhSC, pwszServiceName );
  1745. }
  1746. }
  1747. //+-------------------------------------------------------------------------
  1748. //
  1749. // Function: MyStartService
  1750. //
  1751. // Synopsis: Starts a given service
  1752. //
  1753. // Arguments: xSC -- the service control manager
  1754. // pwcService -- name of the service to start
  1755. //
  1756. // History: 8-Jan-97 dlee Created
  1757. //
  1758. //--------------------------------------------------------------------------
  1759. void MyStartService(
  1760. CServiceHandle & xSC,
  1761. WCHAR const * pwcService )
  1762. {
  1763. CServiceHandle xSVC( OpenService( xSC.Get(),
  1764. pwcService,
  1765. SERVICE_START |
  1766. GENERIC_READ | GENERIC_WRITE ) );
  1767. if ( 0 != xSVC.Get() )
  1768. {
  1769. if ( !StartService( xSVC.Get(), 0, 0 ) )
  1770. {
  1771. isDebugOut(( DEB_ERROR, "Failed to start '%ws': %d\n", pwcService, GetLastError() ));
  1772. }
  1773. }
  1774. } //MyStartService
  1775. //+-------------------------------------------------------------------------
  1776. //
  1777. // Function: IsSvcRunning
  1778. //
  1779. // Synopsis: Determines if a service is running
  1780. //
  1781. // Arguments: xSC -- the service control manager
  1782. //
  1783. // Returns: TRUE if the service is running, FALSE otherwise
  1784. //
  1785. // History: 8-Jan-97 dlee Created
  1786. //
  1787. //--------------------------------------------------------------------------
  1788. BOOL IsSvcRunning( CServiceHandle &x )
  1789. {
  1790. SERVICE_STATUS svcStatus;
  1791. if ( QueryServiceStatus( x.Get(), &svcStatus ) )
  1792. return SERVICE_STOP_PENDING == svcStatus.dwCurrentState ||
  1793. SERVICE_RUNNING == svcStatus.dwCurrentState ||
  1794. SERVICE_PAUSED == svcStatus.dwCurrentState;
  1795. return FALSE;
  1796. } //IsSvcRunning
  1797. //+-------------------------------------------------------------------------
  1798. //
  1799. // Function: MyStopService
  1800. //
  1801. // Synopsis: Stops a given service
  1802. //
  1803. // Arguments: xSC -- the service control manager
  1804. // pwcSVC -- name of the service to stop
  1805. //
  1806. // Returns: TRUE if the service was stopped
  1807. //
  1808. // History: 8-Jan-97 dlee Created
  1809. //
  1810. //--------------------------------------------------------------------------
  1811. BOOL MyStopService(
  1812. CServiceHandle & xSC,
  1813. WCHAR const * pwcSVC,
  1814. BOOL & fStopped )
  1815. {
  1816. fStopped = FALSE;
  1817. BOOL fOK = TRUE;
  1818. CServiceHandle xSVC( OpenService( xSC.Get(),
  1819. pwcSVC,
  1820. SERVICE_STOP |
  1821. GENERIC_READ | GENERIC_WRITE ) );
  1822. if ( 0 != xSVC.Get() )
  1823. {
  1824. SERVICE_STATUS svcStatus;
  1825. if ( IsSvcRunning( xSVC ) )
  1826. {
  1827. g_fCiSvcWasRunning = TRUE;
  1828. if ( ControlService( xSVC.Get(),
  1829. SERVICE_CONTROL_STOP,
  1830. &svcStatus ) )
  1831. {
  1832. for ( unsigned i = 0; i < 30 && IsSvcRunning( xSVC ); i++ )
  1833. {
  1834. isDebugOut(( DEB_ITRACE, "sleeping waiting for service '%ws' to stop\n", pwcSVC ));
  1835. Sleep( 1000 );
  1836. }
  1837. if ( IsSvcRunning( xSVC ) )
  1838. {
  1839. THROW( CException( E_FAIL ) );
  1840. }
  1841. isDebugOut(( DEB_TRACE, "stopped service '%ws'\n", pwcSVC ));
  1842. fStopped = TRUE;
  1843. }
  1844. else
  1845. {
  1846. DWORD dw = GetLastError();
  1847. isDebugOut(( DEB_ERROR, "can't stop service '%ws', error %d\n", pwcSVC, dw ));
  1848. // failures other than timeout and out-of-control are ok
  1849. if ( ERROR_SERVICE_REQUEST_TIMEOUT == dw ||
  1850. ERROR_SERVICE_CANNOT_ACCEPT_CTRL == dw )
  1851. fOK = FALSE;
  1852. }
  1853. }
  1854. }
  1855. return fOK;
  1856. } //MyStopService
  1857. //+-------------------------------------------------------------------------
  1858. //
  1859. // Function: DeleteService
  1860. //
  1861. // Synopsis: deletes a service by name
  1862. //
  1863. // Arguments: pwszServiceName - name of service to delete
  1864. //
  1865. // Returns: none - throws upon fatal failure
  1866. //
  1867. // History: 6-29-97 mohamedn created
  1868. //
  1869. //--------------------------------------------------------------------------
  1870. void DeleteService( WCHAR const * pwszServiceName )
  1871. {
  1872. DWORD dwLastError = 0;
  1873. SC_HANDLE hSC = OpenSCManager( 0, 0, SC_MANAGER_ALL_ACCESS );
  1874. CServiceHandle xhSC(hSC);
  1875. if( 0 == hSC )
  1876. {
  1877. dwLastError = GetLastError();
  1878. isDebugOut(( DEB_ERROR, "OpenSCManager() Failed: %x\n", dwLastError ));
  1879. THROW( CException(HRESULT_FROM_WIN32(dwLastError)) );
  1880. }
  1881. SC_HANDLE hCiSvc = OpenService( hSC, pwszServiceName, DELETE );
  1882. CServiceHandle xhCiSvc( hCiSvc );
  1883. if ( 0 == hCiSvc )
  1884. {
  1885. dwLastError = GetLastError();
  1886. isDebugOut(( DEB_ERROR, "OpenService(Cisvc for delete) Failed: %x\n", dwLastError ));
  1887. }
  1888. else if ( !DeleteService(hCiSvc) )
  1889. {
  1890. dwLastError = GetLastError();
  1891. isDebugOut(( DEB_ERROR, "DeleteService(Cisvc) Failed: %x\n", dwLastError ));
  1892. THROW( CException(HRESULT_FROM_WIN32(dwLastError)) );
  1893. }
  1894. }
  1895. //+-------------------------------------------------------------------------
  1896. //
  1897. // Function: ISError
  1898. //
  1899. // Synopsis: Reports a non-recoverable Index Server Install error
  1900. //
  1901. // Arguments: id -- resource identifier for the error string
  1902. //
  1903. // History: 8-Jan-97 dlee Created
  1904. //
  1905. //--------------------------------------------------------------------------
  1906. void ISError( UINT id, CError &Err, LogSeverity Severity, DWORD dwErr )
  1907. {
  1908. CResString msg( id );
  1909. CResString title( IS_MSG_INDEX_SERVER );
  1910. Err.Report( Severity, dwErr, msg.Get() );
  1911. if ( LogSevFatalError == Severity )
  1912. {
  1913. isDebugOut(( "ISError, error %#x abort install: '%ws'\n",
  1914. dwErr, msg.Get() ));
  1915. isDebugOut(( DEB_ERROR, "ISError, error %#x abort install: '%ws'\n",
  1916. dwErr, msg.Get() ));
  1917. g_fInstallAborted = TRUE;
  1918. }
  1919. } //ISError
  1920. //+-------------------------------------------------------------------------
  1921. //
  1922. // Function: Exec
  1923. //
  1924. // Synopsis: Runs an app and waits for it to complete
  1925. //
  1926. // History: 8-Jan-97 dlee Created from cistp.dll code
  1927. //
  1928. //--------------------------------------------------------------------------
  1929. void Exec(
  1930. WCHAR * pwc )
  1931. {
  1932. isDebugOut(( "exec: '%ws'\n", pwc ));
  1933. STARTUPINFO si;
  1934. RtlZeroMemory( &si, sizeof si );
  1935. si.dwFlags = STARTF_USESHOWWINDOW;
  1936. si.wShowWindow = SW_HIDE;
  1937. PROCESS_INFORMATION pi;
  1938. if ( CreateProcess( 0, // pointer to name of executable module
  1939. pwc, // pointer to command line string
  1940. 0, // pointer to process security attributes
  1941. 0, // pointer to thread security attributes
  1942. FALSE, // handle inheritance flag
  1943. 0, // creation flags
  1944. 0, // pointer to new environment block
  1945. 0, // pointer to current directory name
  1946. &si, // pointer to STARTUPINFO
  1947. &pi ) ) // pointer to PROCESS_INFORMATION
  1948. {
  1949. WaitForSingleObject( pi.hProcess, 0xFFFFFFFF );
  1950. }
  1951. } //Exec
  1952. //+-------------------------------------------------------------------------
  1953. //
  1954. // Function: RegisterDll
  1955. //
  1956. // Synopsis: Calls DllRegisterServer on a given dll
  1957. //
  1958. // Returns: Win32 error code
  1959. //
  1960. // History: 21-Jan-97 dlee Created
  1961. //
  1962. //--------------------------------------------------------------------------
  1963. DWORD RegisterDll(WCHAR const * pwcDLL, CError &Err )
  1964. {
  1965. DWORD dwErr = NO_ERROR;
  1966. // All Index Server dlls are currently in system32
  1967. TRY
  1968. {
  1969. unsigned cwc = wcslen( g_awcSystemDir ) + 1 + wcslen( pwcDLL );
  1970. if ( cwc >= MAX_PATH )
  1971. return 0;
  1972. WCHAR awcPath[ MAX_PATH ];
  1973. wcscpy( awcPath, g_awcSystemDir );
  1974. wcscat( awcPath, L"\\" );
  1975. wcscat( awcPath, pwcDLL );
  1976. HINSTANCE hDll = LoadLibraryEx( awcPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
  1977. if( 0 != hDll )
  1978. {
  1979. SCODE (STDAPICALLTYPE *pfnDllRegisterServer)();
  1980. pfnDllRegisterServer = (HRESULT (STDAPICALLTYPE *)())
  1981. GetProcAddress(hDll, "DllRegisterServer");
  1982. if ( 0 != pfnDllRegisterServer )
  1983. {
  1984. SCODE sc = (*pfnDllRegisterServer)();
  1985. if ( S_OK != sc )
  1986. {
  1987. isDebugOut(( DEB_ERROR, "dllregister server '%ws' failed 0x%x\n",
  1988. awcPath, sc));
  1989. ISError(IS_MSG_DllRegisterServer_FAILED ,Err, LogSevError, sc );
  1990. // no way to map a scode to a win32 error
  1991. dwErr = sc; // kylep suggested this would be valuable.
  1992. }
  1993. }
  1994. else
  1995. dwErr = GetLastError();
  1996. FreeLibrary( hDll );
  1997. }
  1998. else
  1999. {
  2000. dwErr = GetLastError();
  2001. }
  2002. isDebugOut((DEB_TRACE, "result of registering '%ws': %d\n", awcPath, dwErr ));
  2003. #ifdef _WIN64
  2004. //
  2005. // Register the 32 bit version of the DLL
  2006. //
  2007. WCHAR awcSysWow64[ MAX_PATH ];
  2008. cwc = GetSystemWow64Directory( awcSysWow64, sizeof awcSysWow64 / sizeof WCHAR );
  2009. if ( 0 == cwc )
  2010. return GetLastError();
  2011. if ( L'\\' != awcSysWow64[ cwc - 1 ] )
  2012. {
  2013. awcSysWow64[ cwc++ ] = '\\';
  2014. awcSysWow64[ cwc ] = 0;
  2015. }
  2016. WCHAR awcCmd[ MAX_PATH * 2 ];
  2017. wcscpy( awcCmd, awcSysWow64 );
  2018. wcscat( awcCmd, L"regsvr32 /s " );
  2019. wcscat( awcCmd, awcSysWow64 );
  2020. wcscat( awcCmd, pwcDLL );
  2021. Exec( awcCmd );
  2022. #endif //_WIN64
  2023. }
  2024. CATCH( CException, e )
  2025. {
  2026. // ignore, since it's probably the new html filter
  2027. isDebugOut(( "caught %#x registering '%ws'\n",
  2028. e.GetErrorCode(),
  2029. pwcDLL ));
  2030. }
  2031. END_CATCH
  2032. return dwErr; // used to return 0 to avoid returning error!
  2033. } //RegisterDll
  2034. //+-------------------------------------------------------------------------
  2035. //
  2036. // Function: UnregisterDll
  2037. //
  2038. // Synopsis: Calls DllUnregisterServer on a given dll
  2039. //
  2040. // Returns: Win32 error code
  2041. //
  2042. // History: 21-Jan-97 dlee Created
  2043. //
  2044. //--------------------------------------------------------------------------
  2045. DWORD UnregisterDll(
  2046. WCHAR const * pwcDLL )
  2047. {
  2048. UINT uiOld = SetErrorMode( SEM_NOOPENFILEERRORBOX |
  2049. SEM_FAILCRITICALERRORS );
  2050. TRY
  2051. {
  2052. // All Index Server dlls are currently in system32
  2053. unsigned cwc = wcslen( g_awcSystemDir ) + 1 + wcslen( pwcDLL );
  2054. if ( cwc >= MAX_PATH )
  2055. return 0;
  2056. WCHAR awcPath[ MAX_PATH ];
  2057. wcscpy( awcPath, g_awcSystemDir );
  2058. wcscat( awcPath, L"\\" );
  2059. wcscat( awcPath, pwcDLL );
  2060. // don't display popups if a dll can't be loaded when trying to
  2061. // unregister.
  2062. DWORD dwErr = NO_ERROR;
  2063. HINSTANCE hDll = LoadLibraryEx( awcPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
  2064. if( 0 != hDll )
  2065. {
  2066. SCODE (STDAPICALLTYPE *pfnDllUnregisterServer)();
  2067. pfnDllUnregisterServer = (HRESULT (STDAPICALLTYPE *)())
  2068. GetProcAddress(hDll, "DllUnregisterServer");
  2069. if ( 0 != pfnDllUnregisterServer )
  2070. {
  2071. SCODE sc = (*pfnDllUnregisterServer)();
  2072. if ( S_OK != sc )
  2073. dwErr = ERROR_INVALID_FUNCTION;
  2074. }
  2075. else
  2076. dwErr = GetLastError();
  2077. FreeLibrary( hDll );
  2078. }
  2079. else
  2080. {
  2081. dwErr = GetLastError();
  2082. }
  2083. isDebugOut((DEB_TRACE, "result of unregistering '%ws': %d\n", awcPath, dwErr ));
  2084. }
  2085. CATCH( CException, e )
  2086. {
  2087. // ignore, since it's probably the new html filter
  2088. }
  2089. END_CATCH
  2090. SetErrorMode( uiOld );
  2091. return 0; // explicitly ignore unregister errors
  2092. } //UnregisterDll
  2093. //+-------------------------------------------------------------------------
  2094. //
  2095. // Function: SetFilterRegistryInfo
  2096. //
  2097. // Synopsis: Installs registry info for Index Server filters
  2098. //
  2099. // Returns: Win32 error code
  2100. //
  2101. // History: 8-Jan-97 dlee Created
  2102. // 7-01-97 mohamedn cleanedup for IS3.0 with NT5.0 setup.
  2103. //
  2104. //--------------------------------------------------------------------------
  2105. DWORD SetFilterRegistryInfo( BOOL fUnRegister, CError &Err )
  2106. {
  2107. if ( fUnRegister )
  2108. {
  2109. // try to unregister old dlls
  2110. UnregisterDll( L"query.dll" );
  2111. UnregisterDll( L"htmlfilt.dll" );
  2112. UnregisterDll( L"nlfilt.dll" );
  2113. UnregisterDll( L"sccifilt.dll" );
  2114. UnregisterDll( L"ciadmin.dll" );
  2115. UnregisterDll( L"cifrmwrk.dll" );
  2116. UnregisterDll( L"fsci.dll" );
  2117. UnregisterDll( L"OffFilt.dll" );
  2118. UnregisterDll( L"ixsso.dll" );
  2119. UnregisterDll( L"ciodm.dll" );
  2120. UnregisterDll( L"infosoft.dll" );
  2121. UnregisterDll( L"mimefilt.dll" );
  2122. UnregisterDll( L"LangWrBk.dll" );
  2123. }
  2124. else
  2125. {
  2126. // call the .dlls to have them registered
  2127. for ( unsigned i = 0; i < cDlls; i++ )
  2128. {
  2129. DWORD dwErr = RegisterDll( apwcDlls[i], Err );
  2130. if ( NO_ERROR != dwErr )
  2131. {
  2132. isDebugOut(( DEB_ERROR, "Failed to register(%ws): error code: %d\n",
  2133. apwcDlls[i], dwErr ));
  2134. ISError(IS_MSG_DLL_REGISTRATION_FAILED , Err, LogSevError, dwErr );
  2135. return dwErr;
  2136. }
  2137. }
  2138. }
  2139. return NO_ERROR;
  2140. } //SetFilterregistryInfo
  2141. //+-------------------------------------------------------------------------
  2142. //
  2143. // Function: SetRegBasedOnMachine
  2144. //
  2145. // Synopsis: Sets Index Server registry tuning paramaters based on the
  2146. // capabilities of the machine. Uninstall is .inf-based.
  2147. //
  2148. // History: 8-Jan-97 dlee Created
  2149. //
  2150. //--------------------------------------------------------------------------
  2151. DWORD SetRegBasedOnMachine(CError &Err)
  2152. {
  2153. if ( 0 == gSetupInitComponent.ComponentInfHandle )
  2154. {
  2155. ISError( IS_MSG_INVALID_INF_HANDLE, Err, LogSevError );
  2156. return NO_ERROR;
  2157. }
  2158. WCHAR * pwcInf = 0;
  2159. BOOL fServer = FALSE;
  2160. switch(g_NtType)
  2161. {
  2162. case PRODUCT_SERVER_STANDALONE:
  2163. case PRODUCT_SERVER_PRIMARY:
  2164. case PRODUCT_SERVER_SECONDARY:
  2165. {
  2166. BOOL fLotsOfMem;
  2167. DWORD cCpu;
  2168. GetMachineInfo( fLotsOfMem, cCpu );
  2169. if ( fLotsOfMem )
  2170. {
  2171. if ( 1 == cCpu )
  2172. pwcInf = L"IndexSrv_Large";
  2173. else if ( 2 == cCpu )
  2174. pwcInf = L"IndexSrv_LargeMP2";
  2175. else
  2176. pwcInf = L"IndexSrv_LargeMPMany";
  2177. }
  2178. else
  2179. {
  2180. if ( 1 == cCpu )
  2181. pwcInf = L"IndexSrv_Small";
  2182. else
  2183. pwcInf = L"IndexSrv_SmallMP2";
  2184. }
  2185. }
  2186. fServer = TRUE;
  2187. break;
  2188. case PRODUCT_WORKSTATION:
  2189. default:
  2190. pwcInf = L"IndexSrv_Workstation";
  2191. }
  2192. if ( !SetupInstallFromInfSection( 0,
  2193. gSetupInitComponent.ComponentInfHandle,
  2194. pwcInf,
  2195. SPINST_REGISTRY,
  2196. 0, 0, 0, 0, 0, 0, 0 ) )
  2197. return GetLastError();
  2198. // If a server, allow catalogs key to be read-only visible
  2199. // to the world. See KB Q155363
  2200. // Note: In Win2k, the professional version requires this as well,
  2201. // so I commented out the fServer check.
  2202. // if ( fServer )
  2203. {
  2204. CWin32RegAccess regAllowed( HKEY_LOCAL_MACHINE, wcsAllowedPaths );
  2205. WCHAR awcValue[ 8192 ];
  2206. if ( regAllowed.Get( L"Machine",
  2207. awcValue,
  2208. sizeof awcValue / sizeof WCHAR ) )
  2209. {
  2210. // don't re-add it if it already exists
  2211. BOOL fFound = FALSE;
  2212. WCHAR *p = awcValue;
  2213. while ( 0 != *p )
  2214. {
  2215. if ( !_wcsicmp( p, wcsRegAdminSubKey ) )
  2216. {
  2217. fFound = TRUE;
  2218. break;
  2219. }
  2220. while ( 0 != *p )
  2221. p++;
  2222. p++;
  2223. }
  2224. if ( !fFound )
  2225. {
  2226. wcscpy( p, wcsRegAdminSubKey );
  2227. p += ( 1 + wcslen( wcsRegAdminSubKey ) );
  2228. *p++ = 0;
  2229. if ( !regAllowed.SetMultiSZ( L"Machine",
  2230. awcValue,
  2231. (ULONG)(p-awcValue) * sizeof WCHAR ) )
  2232. {
  2233. DWORD dw = GetLastError();
  2234. ISError( IS_MSG_COULD_NOT_MODIFY_REGISTRY, Err, LogSevFatalError, dw );
  2235. return dw;
  2236. }
  2237. }
  2238. }
  2239. }
  2240. return NO_ERROR;
  2241. } //SetRegBasedOnMachine
  2242. //+-------------------------------------------------------------------------
  2243. //
  2244. // Function: SetRegBasedOnArchitecture
  2245. //
  2246. // Synopsis: Sets Index Server registry tuning paramaters based on the
  2247. // architecture. Uninstall is .inf-based.
  2248. //
  2249. // History: 24-Feb-98 KrishnaN Created
  2250. //
  2251. //--------------------------------------------------------------------------
  2252. DWORD SetRegBasedOnArchitecture(CError &Err)
  2253. {
  2254. if ( 0 == gSetupInitComponent.ComponentInfHandle )
  2255. {
  2256. Err.Report(LogSevError,0,L"Couldn't set registry based on architecture, Invalid Inf Handle");
  2257. return NO_ERROR;
  2258. }
  2259. WCHAR * pwcInf = 0;
  2260. #if defined (_X86_)
  2261. pwcInf = L"IndexSrv_X86";
  2262. #else
  2263. pwcInf = L"IndexSrv_RISC";
  2264. #endif
  2265. if ( !SetupInstallFromInfSection( 0,
  2266. gSetupInitComponent.ComponentInfHandle,
  2267. pwcInf,
  2268. SPINST_REGISTRY,
  2269. 0, 0, 0, 0, 0, 0, 0 ) )
  2270. return GetLastError();
  2271. return NO_ERROR;
  2272. } //SetRegBasedOnArchitecture
  2273. //+-------------------------------------------------------------------------
  2274. //
  2275. // Function: GetMachineInfo
  2276. //
  2277. // Synopsis: Retrieves stats about the machine
  2278. //
  2279. // Arguments: fLotsOfMem -- returns TRUE if the machine has "lots" of mem
  2280. // cCPU -- returns a count of CPUs
  2281. //
  2282. // History: 8-Jan-97 dlee Created
  2283. //
  2284. //--------------------------------------------------------------------------
  2285. void GetMachineInfo(
  2286. BOOL & fLotsOfMem,
  2287. DWORD & cCPU )
  2288. {
  2289. SYSTEM_INFO si;
  2290. GetSystemInfo( &si );
  2291. cCPU = si.dwNumberOfProcessors;
  2292. MEMORYSTATUSEX memStatus;
  2293. memStatus.dwLength = sizeof( memStatus );
  2294. GlobalMemoryStatusEx( &memStatus );
  2295. fLotsOfMem = ( memStatus.ullTotalPhys >= 64000000 );
  2296. } //GetMachineInfo
  2297. //+-------------------------------------------------------------------------
  2298. //
  2299. // Function: isLogString
  2300. //
  2301. // Synopsis: Logs the string to %windir%\setupqry.log
  2302. //
  2303. // Arguments: pc -- ansi string
  2304. //
  2305. // History: 11-Nov-98 dlee Created
  2306. //
  2307. //--------------------------------------------------------------------------
  2308. BOOL g_fCalledYet = FALSE;
  2309. void isLogString( const char * pc )
  2310. {
  2311. WCHAR awc[ MAX_PATH ];
  2312. UINT ui = GetWindowsDirectory( awc, sizeof awc / sizeof WCHAR );
  2313. if ( 0 == ui )
  2314. return;
  2315. wcscat( awc, L"\\setupqry.log" );
  2316. WCHAR const * pwcOpen = L"a";
  2317. if ( !g_fCalledYet )
  2318. {
  2319. g_fCalledYet = TRUE;
  2320. pwcOpen = L"w";
  2321. }
  2322. FILE *fp = _wfopen( awc, pwcOpen );
  2323. if ( 0 != fp )
  2324. {
  2325. fprintf( fp, "%s", pc );
  2326. fclose( fp );
  2327. }
  2328. } //isLogString
  2329. //+-------------------------------------------------------------------------
  2330. //
  2331. // Function: SystemExceptionTranslator
  2332. //
  2333. // Synopsis: Translates system exceptions into C++ exceptions
  2334. //
  2335. // History: 1-Dec-98 dlee Copied from query.dll's version
  2336. //
  2337. //--------------------------------------------------------------------------
  2338. void _cdecl SystemExceptionTranslator(
  2339. unsigned int uiWhat,
  2340. struct _EXCEPTION_POINTERS * pexcept )
  2341. {
  2342. throw CException( uiWhat );
  2343. } //SystemExceptionTranslator
  2344. //+-------------------------------------------------------------------------
  2345. //
  2346. // Function: DeleteNTOPStartMenu
  2347. //
  2348. // Synopsis: Deletes start menu items created by IS in the NTOP
  2349. //
  2350. // History: 6-Jan-99 dlee Created
  2351. //
  2352. //--------------------------------------------------------------------------
  2353. void DeleteNTOPStartMenu()
  2354. {
  2355. //
  2356. // Ignore all failures here -- it's ok if the link don't exist
  2357. //
  2358. CWin32RegAccess reg( HKEY_LOCAL_MACHINE,
  2359. L"software\\microsoft\\windows\\currentversion\\explorer\\shell folders" );
  2360. WCHAR awc[MAX_PATH];
  2361. if ( reg.Get( L"common programs",
  2362. awc,
  2363. MAX_PATH ) )
  2364. {
  2365. //
  2366. // Build the directory where the links are located
  2367. //
  2368. wcscat( awc, L"\\" );
  2369. CResString strNTOP( IS_MSG_NTOP );
  2370. wcscat( awc, strNTOP.Get() );
  2371. wcscat( awc, L"\\" );
  2372. CResString strMIS( IS_MSG_START_MENU_NAME );
  2373. wcscat( awc, strMIS.Get() );
  2374. isDebugOut(( "NTOP start menu location: '%ws'\n", awc ));
  2375. //
  2376. // Delete the links
  2377. //
  2378. CResString strSample( IS_MSG_LINK_SAMPLE_NAME );
  2379. DeleteShellLink( awc, strSample.Get() );
  2380. isDebugOut(( "deleting NTOP item '%ws'\n", strSample.Get() ));
  2381. CResString strAdmin( IS_MSG_LINK_ADMIN_NAME );
  2382. DeleteShellLink( awc, strAdmin.Get() );
  2383. isDebugOut(( "deleting NTOP item '%ws'\n", strAdmin.Get() ));
  2384. CResString strMMC( IS_MSG_LINK_MMC_NAME );
  2385. DeleteShellLink( awc, strMMC.Get() );
  2386. isDebugOut(( "deleting NTOP item '%ws'\n", strMMC.Get() ));
  2387. //
  2388. // Note: when the last item is deleted, DeleteShellLink deletes
  2389. // the directory
  2390. //
  2391. }
  2392. } //DeleteNTOPStartMenu