Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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