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.

1233 lines
35 KiB

  1. /*===================================================================
  2. Microsoft IIS
  3. Microsoft Confidential.
  4. Copyright 1997 Microsoft Corporation. All Rights Reserved.
  5. Component: WAMREG Wam Registration
  6. File: export.cpp
  7. Owner: LeiJin
  8. Note:
  9. WAMREG Export functions.
  10. ===================================================================*/
  11. #define _WAMREG_DLL_
  12. #include "common.h"
  13. #include <stdio.h>
  14. #include "objbase.h"
  15. #include "dbgutil.h"
  16. #include "wmrgexp.h"
  17. #include "auxfunc.h"
  18. #include "iiscnfg.h"
  19. #include "export.h"
  20. PFNServiceNotify g_pfnW3ServiceSink;
  21. //
  22. // Setup support
  23. //
  24. IIS5LOG_FUNCTION g_pfnSetupWriteLog = NULL;
  25. VOID
  26. LogSetupTraceImpl
  27. (
  28. LPCSTR szPrefixFormat,
  29. LPCSTR szFilePath,
  30. INT nLineNum,
  31. INT nTraceLevel,
  32. LPCSTR szFormat,
  33. va_list argptr
  34. );
  35. class CWamSetupManager
  36. /*++
  37. Class description:
  38. Collects those helper functions used exclusively by setup.
  39. Most of these methods were formerly in WamRegGlobal.
  40. Public Interface:
  41. --*/
  42. {
  43. public:
  44. CWamSetupManager()
  45. : m_hrCoInit( NOERROR )
  46. {
  47. }
  48. ~CWamSetupManager()
  49. {
  50. }
  51. HRESULT SetupInit( WamRegPackageConfig &refPackageConfig );
  52. VOID SetupUnInit( WamRegPackageConfig &refPackageConfig )
  53. {
  54. refPackageConfig.Cleanup();
  55. WamRegMetabaseConfig::MetabaseUnInit();
  56. if( SUCCEEDED(m_hrCoInit) )
  57. {
  58. CoUninitialize();
  59. }
  60. }
  61. HRESULT UpgradeInProcApplications( VOID );
  62. HRESULT AppCleanupAll( VOID );
  63. private:
  64. HRESULT DoGoryCoInitialize( VOID );
  65. HRESULT RemoveWAMCLSIDFromInProcApp( IN LPCWSTR pszMetabasePath );
  66. private:
  67. HRESULT m_hrCoInit;
  68. };
  69. #define MAX_SETUP_TRACE_OUTPUTSTR 1024
  70. HRESULT PACKMGR_LIBAPI
  71. InstallWam
  72. (
  73. HMODULE hIIsSetupModule
  74. )
  75. /*++
  76. Routine Description:
  77. Setup entry point. The handle to iis.dll is passed in to allow us
  78. to log to the setup log.
  79. Parameters
  80. hIIsSetupModule -
  81. Return Value
  82. HRESULT
  83. --*/
  84. {
  85. HRESULT hr = NOERROR;
  86. // Get the logging entry point from iis.dll
  87. #ifdef WAMREG_DEBUG_SETUP_LOG
  88. SetLogFile();
  89. #else
  90. g_pfnSetupWriteLog = (IIS5LOG_FUNCTION) GetProcAddress( hIIsSetupModule, "IIS5Log");
  91. #endif
  92. hr = CreateIISPackage();
  93. #ifdef WAMREG_DEBUG_SETUP_LOG
  94. ClearLogFile();
  95. #endif
  96. g_pfnSetupWriteLog = NULL;
  97. return hr;
  98. }
  99. HRESULT PACKMGR_LIBAPI
  100. UnInstallWam
  101. (
  102. HMODULE hIIsSetupModule
  103. )
  104. /*++
  105. Routine Description:
  106. Setup entry point. The handle to iis.dll is passed in to allow us
  107. to log to the setup log.
  108. Parameters
  109. hIIsSetupModule -
  110. Return Value
  111. HRESULT
  112. --*/
  113. {
  114. HRESULT hr = NOERROR;
  115. // Get the logging entry point from iis.dll
  116. #ifdef WAMREG_DEBUG_SETUP_LOG
  117. SetLogFile();
  118. #else
  119. g_pfnSetupWriteLog = (IIS5LOG_FUNCTION) GetProcAddress( hIIsSetupModule, "IIS5Log");
  120. #endif
  121. hr = DeleteIISPackage();
  122. #ifdef WAMREG_DEBUG_SETUP_LOG
  123. ClearLogFile();
  124. #endif
  125. g_pfnSetupWriteLog = NULL;
  126. return hr;
  127. }
  128. VOID
  129. LogSetupTrace
  130. (
  131. IN LPDEBUG_PRINTS pDebugPrints,
  132. IN const char * pszFilePath,
  133. IN int nLineNum,
  134. IN const char * /* pszFunction */,
  135. IN const char * pszFormat,
  136. ...
  137. )
  138. /*++
  139. Routine Description:
  140. Called by SETUP_TRACE* logging macros. Passes va_list to LogSetupTraceImpl.
  141. Parameters
  142. IN LPDEBUG_PRINTS pDebugPrints - from DBG_CONTEXT unused
  143. IN const char * pszFilePath - from DBG_CONTEXT unused
  144. IN int nLineNum - from DBG_CONTEXT unused
  145. IN const char * pszFormat - format string
  146. --*/
  147. {
  148. DBG_ASSERT( pszFormat );
  149. va_list argsList;
  150. va_start( argsList, pszFormat);
  151. LogSetupTraceImpl(
  152. "[WAMTRACE - %14s : %05d]\t",
  153. pszFilePath,
  154. nLineNum,
  155. LOG_TYPE_TRACE,
  156. pszFormat,
  157. argsList
  158. );
  159. va_end( argsList);
  160. }
  161. VOID
  162. LogSetupTraceError
  163. (
  164. IN LPDEBUG_PRINTS pDebugPrints,
  165. IN const char * pszFilePath,
  166. IN int nLineNum,
  167. IN const char * /* pszFunction */,
  168. IN const char * pszFormat,
  169. ...
  170. )
  171. /*++
  172. Routine Description:
  173. Called by SETUP_TRACE* logging macros. Passes va_list to LogSetupTraceImpl.
  174. Parameters
  175. IN LPDEBUG_PRINTS pDebugPrints - from DBG_CONTEXT unused
  176. IN const char * pszFilePath - from DBG_CONTEXT unused
  177. IN int nLineNum - from DBG_CONTEXT unused
  178. IN const char * pszFormat - format string
  179. --*/
  180. {
  181. DBG_ASSERT( pszFormat );
  182. va_list argsList;
  183. va_start( argsList, pszFormat);
  184. LogSetupTraceImpl(
  185. "[WAMERROR - %14s : %05d]\t",
  186. pszFilePath,
  187. nLineNum,
  188. LOG_TYPE_ERROR,
  189. pszFormat,
  190. argsList
  191. );
  192. va_end( argsList);
  193. }
  194. VOID
  195. LogSetupTraceImpl
  196. (
  197. LPCSTR szPrefixFormat,
  198. LPCSTR szFilePath,
  199. INT nLineNum,
  200. INT nTraceLevel,
  201. LPCSTR szFormat,
  202. va_list argptr
  203. )
  204. /*++
  205. Routine Description:
  206. All the logging macros resolve to this function. Formats the
  207. message to be logged and logs it using g_pfnSetupWriteLog.
  208. Parameters
  209. LPCSTR szPrefixFormat -
  210. LPCSTR szFilePath -
  211. INT nLineNum -
  212. INT nTraceLevel - LOG_TYPE_ERROR, LOG_TYPE_TRACE
  213. LPCSTR szFormat - format string
  214. va_list argptr - arguments to format
  215. --*/
  216. {
  217. WCHAR wszOutput[MAX_SETUP_TRACE_OUTPUTSTR + 1];
  218. CHAR szOutput[MAX_SETUP_TRACE_OUTPUTSTR + 1];
  219. LPCSTR szFileName = strrchr( szFilePath, '\\');
  220. szFileName++;
  221. int cchPrefix = wsprintf( szOutput, szPrefixFormat, szFileName, nLineNum );
  222. int cchOutputString = _vsnprintf( szOutput + cchPrefix,
  223. MAX_SETUP_TRACE_OUTPUTSTR - cchPrefix,
  224. szFormat,
  225. argptr
  226. );
  227. if( -1 == cchOutputString )
  228. {
  229. // Terminate properly if too much data
  230. szOutput[MAX_SETUP_TRACE_OUTPUTSTR] = '\0';
  231. }
  232. if( MultiByteToWideChar( CP_ACP,
  233. 0,
  234. szOutput,
  235. -1,
  236. wszOutput,
  237. MAX_SETUP_TRACE_OUTPUTSTR + 1 )
  238. )
  239. {
  240. if( g_pfnSetupWriteLog )
  241. {
  242. g_pfnSetupWriteLog( nTraceLevel, wszOutput );
  243. }
  244. }
  245. }
  246. HRESULT
  247. PACKMGR_LIBAPI
  248. CreateCOMPlusApplication(
  249. LPCWSTR szMDPath,
  250. LPCWSTR szOOPPackageID,
  251. LPCWSTR szOOPWAMCLSID,
  252. BOOL * pfAppCreated
  253. )
  254. {
  255. HRESULT hr = S_OK;
  256. WamRegPackageConfig PackageConfig;
  257. DWORD dwMDPathLen;
  258. *pfAppCreated = FALSE;
  259. //
  260. // Initilize COM+ catalog
  261. //
  262. hr = PackageConfig.CreateCatalog();
  263. if( FAILED( hr ) )
  264. {
  265. return hr;
  266. }
  267. if( !PackageConfig.IsPackageInstalled( szOOPPackageID,
  268. szOOPWAMCLSID ) )
  269. {
  270. hr = g_WamRegGlobal.CreateOutProcApp( szMDPath, FALSE, FALSE );
  271. if (FAILED(hr))
  272. {
  273. DBGPRINTF(( DBG_CONTEXT,
  274. "Failed to create new application on path %S, hr = 08x\n",
  275. szMDPath,
  276. hr ));
  277. }
  278. *pfAppCreated = TRUE;
  279. }
  280. return hr;
  281. }
  282. /*===================================================================
  283. CreateIISPackage
  284. Called at IIS Setup time.
  285. This is a pseudo dll entry point. It shouldn't be called by setup directly.
  286. Setup calls InstallWam(). This entry still exists so there is a function
  287. that can be called by rundll32 that takes no parameters and provides
  288. equivalent functionality to setup.
  289. rundll32 wamreg.dll,CreateIISPackage
  290. This routine's logic has changed to do two ways. One, it won't
  291. cleanup when it fails. The cleanup logic made it much more difficult
  292. to determine what worked and what didn't. Two, it doesn't skip steps
  293. when a failure happens. Some multistep actions may be cut short if
  294. there is a failure, but we won't bail and skip an unrelated action
  295. anymore.
  296. Returns:
  297. HRESULT - NOERROR on success
  298. Side effects:
  299. ===================================================================*/
  300. HRESULT PACKMGR_LIBAPI CreateIISPackage(void)
  301. {
  302. CWamSetupManager setupMgr;
  303. WamRegPackageConfig PackageConfig;
  304. WamRegMetabaseConfig MDConfig;
  305. HRESULT hrReturn = NOERROR;
  306. HRESULT hrCurrent = NOERROR;
  307. SETUP_TRACE(( DBG_CONTEXT, "CALL - CreateIISPackage\n" ));
  308. hrReturn = setupMgr.SetupInit( PackageConfig );
  309. if( SUCCEEDED(hrReturn) )
  310. {
  311. //
  312. // Determine what packages are currently installed. This will
  313. // drive the logic of the rest of the install.
  314. //
  315. SETUP_TRACE((
  316. DBG_CONTEXT,
  317. "CreateIISPackage - Finding installed WAM packages.\n"
  318. ));
  319. BOOL fIPPackageInstalled =
  320. PackageConfig.IsPackageInstalled(
  321. WamRegGlobal::g_szIISInProcPackageID,
  322. WamRegGlobal::g_szInProcWAMCLSID
  323. );
  324. BOOL fPOOPPackageInstalled =
  325. PackageConfig.IsPackageInstalled(
  326. WamRegGlobal::g_szIISOOPPoolPackageID,
  327. WamRegGlobal::g_szOOPPoolWAMCLSID
  328. );
  329. SETUP_TRACE((
  330. DBG_CONTEXT,
  331. "CreateIISPackage - IP Package exists (%x) POOL Package exists (%x).\n",
  332. fIPPackageInstalled,
  333. fPOOPPackageInstalled
  334. ));
  335. SETUP_TRACE((
  336. DBG_CONTEXT,
  337. "CreateIISPackage - Registering WAM CLSIDs.\n"
  338. ));
  339. hrCurrent = g_RegistryConfig.RegisterCLSID(
  340. WamRegGlobal::g_szOOPPoolWAMCLSID,
  341. WamRegGlobal::g_szOOPPoolWAMProgID,
  342. TRUE
  343. );
  344. if( FAILED(hrCurrent) )
  345. {
  346. hrReturn = hrCurrent;
  347. SETUP_TRACE_ERROR(( DBG_CONTEXT,
  348. "FAIL - RegisterCLSID POOL(%S) - error=%08x\n",
  349. WamRegGlobal::g_szOOPPoolWAMCLSID,
  350. hrReturn
  351. ));
  352. }
  353. if( fIPPackageInstalled )
  354. {
  355. //
  356. // Clean up the in process package all in process
  357. // configuration is obsolete in IIS6
  358. //
  359. SETUP_TRACE((
  360. DBG_CONTEXT,
  361. "CreateIISPackage - Removing the WAM IP application.\n"
  362. ));
  363. hrCurrent = PackageConfig.RemovePackage(
  364. WamRegGlobal::g_szIISInProcPackageID
  365. );
  366. if( FAILED(hrCurrent) )
  367. {
  368. hrReturn = hrCurrent;
  369. SETUP_TRACE_ERROR((
  370. DBG_CONTEXT,
  371. "Failed to remove WAM IP Package(%S). Error %08x\n",
  372. WamRegGlobal::g_szIISInProcPackageID,
  373. hrReturn
  374. ));
  375. }
  376. hrCurrent = g_RegistryConfig.UnRegisterCLSID(
  377. WamRegGlobal::g_szInProcWAMCLSID,
  378. TRUE
  379. );
  380. if( FAILED(hrCurrent) )
  381. {
  382. hrReturn = hrCurrent;
  383. SETUP_TRACE_ERROR((
  384. DBG_CONTEXT,
  385. "Failed to remove registry entries (%S). Error %08x\n",
  386. WamRegGlobal::g_szInProcWAMCLSID,
  387. hrReturn
  388. ));
  389. }
  390. } // create IP package
  391. if( !fPOOPPackageInstalled )
  392. {
  393. //
  394. // Create the POOP package.
  395. //
  396. SETUP_TRACE((
  397. DBG_CONTEXT,
  398. "CreateIISPackage - Creating the WAM POOL application.\n"
  399. ));
  400. // Get IWAM_* account information.
  401. WCHAR szIdentity[MAX_PATH];
  402. WCHAR szPwd[MAX_PATH];
  403. *szIdentity = *szPwd = 0;
  404. hrCurrent = MDConfig.MDGetIdentity( szIdentity,
  405. sizeof(szIdentity),
  406. szPwd,
  407. sizeof(szPwd)
  408. );
  409. if( FAILED(hrCurrent) )
  410. {
  411. hrReturn = hrCurrent;
  412. SETUP_TRACE_ERROR((
  413. DBG_CONTEXT,
  414. "FAIL - MDGetIdentity, Getting the IWAM_* account from the Metabase - error=%08x\n",
  415. hrReturn
  416. ));
  417. }
  418. else
  419. {
  420. // succeeded
  421. hrCurrent = PackageConfig.CreatePackage(
  422. WamRegGlobal::g_szIISOOPPoolPackageID,
  423. WamRegGlobal::g_szIISOOPPoolPackageName,
  424. szIdentity,
  425. szPwd );
  426. if( FAILED(hrCurrent) )
  427. {
  428. hrReturn = hrCurrent;
  429. SETUP_TRACE_ERROR((
  430. DBG_CONTEXT,
  431. "FAIL - CreatePackage POOL(%S) - error=%08x\n",
  432. WamRegGlobal::g_szIISOOPPoolPackageID,
  433. hrReturn
  434. ));
  435. }
  436. else
  437. {
  438. hrCurrent = PackageConfig.AddComponentToPackage(
  439. WamRegGlobal::g_szIISOOPPoolPackageID,
  440. WamRegGlobal::g_szOOPPoolWAMCLSID
  441. );
  442. if( FAILED(hrCurrent) )
  443. {
  444. hrReturn = hrCurrent;
  445. SETUP_TRACE_ERROR((
  446. DBG_CONTEXT,
  447. "FAIL - AddComponentToPackage POOL(%S) - error=%08x\n",
  448. WamRegGlobal::g_szOOPPoolWAMCLSID,
  449. hrReturn
  450. ));
  451. }
  452. }
  453. }
  454. } // create POOL package
  455. //
  456. // Remove the default application /LM/W3SVC Obsolete in IIS6
  457. //
  458. SETUP_TRACE((
  459. DBG_CONTEXT,
  460. "Cleanup obsolete metabase data.\n"
  461. ));
  462. hrCurrent = MDConfig.MDUpdateIISDefault();
  463. if( FAILED(hrCurrent) )
  464. {
  465. SETUP_TRACE((
  466. DBG_CONTEXT,
  467. "Unable to remove service defaults - error=%08x\n",
  468. hrCurrent
  469. ));
  470. }
  471. //
  472. // This really only needs to happen on IIS4 upgrade. But it
  473. // shouldn't actually make any changes unless this is an upgrade.
  474. //
  475. // Update inproc applications by removing WAMCLSID from inproc
  476. // applications. This step does not change inproc application to a
  477. // oop pool application.
  478. //
  479. hrCurrent = setupMgr.UpgradeInProcApplications();
  480. if( FAILED(hrCurrent) )
  481. {
  482. SETUP_TRACE((
  483. DBG_CONTEXT,
  484. "UpgradeInProcApplications - error=%08x\n",
  485. hrCurrent
  486. ));
  487. }
  488. } // init succeeded
  489. setupMgr.SetupUnInit( PackageConfig );
  490. SETUP_TRACE(( DBG_CONTEXT, "RETURN - CreateIISPackage, hr=%08x\n", hrReturn ));
  491. return hrReturn;
  492. }
  493. /*===================================================================
  494. DeleteIISPackage
  495. Delete IIS Package from ViperSpace, and unregister the default IIS
  496. CLSID.
  497. Returns:
  498. HRESULT - NOERROR on success
  499. Side effects:
  500. remove IIS default package from Viperspace.
  501. Note:
  502. No need to delete the metabase entries.
  503. This function is called when IIS is uninstalled.
  504. In this case anyway Metabase will go away - so we don't clean it explicitly
  505. ===================================================================*/
  506. HRESULT PACKMGR_LIBAPI DeleteIISPackage(void)
  507. {
  508. HRESULT hrReturn = NOERROR;
  509. HRESULT hrCurrent = NOERROR;
  510. CWamSetupManager setupMgr;
  511. WamRegPackageConfig PackageConfig;
  512. SETUP_TRACE(( DBG_CONTEXT, "CALL - DeleteIISPackage\n" ));
  513. hrReturn = setupMgr.SetupInit( PackageConfig );
  514. if( SUCCEEDED(hrReturn) )
  515. {
  516. // Blow away all the applications.
  517. SETUP_TRACE((
  518. DBG_CONTEXT,
  519. "DeleteIISPackage - Removing WAM Applications\n"
  520. ));
  521. hrCurrent = setupMgr.AppCleanupAll();
  522. if( FAILED(hrCurrent) )
  523. {
  524. hrReturn = hrCurrent;
  525. SETUP_TRACE_ERROR((
  526. DBG_CONTEXT,
  527. "Failed to remove WAM Applications. Error %08x\n",
  528. hrReturn
  529. ));
  530. }
  531. // Remove the global packages
  532. SETUP_TRACE((
  533. DBG_CONTEXT,
  534. "DeleteIISPackage - Removing WAM packages\n"
  535. ));
  536. //
  537. // Attempt to remove the in process stuff anyway (it shouldn't be there).
  538. //
  539. hrCurrent = PackageConfig.RemovePackage(
  540. WamRegGlobal::g_szIISInProcPackageID
  541. );
  542. if( FAILED(hrCurrent) )
  543. {
  544. SETUP_TRACE((
  545. DBG_CONTEXT,
  546. "Unable to remove IP package (%S). Error %08x.\n",
  547. WamRegGlobal::g_szIISInProcPackageID,
  548. hrReturn
  549. ));
  550. }
  551. hrCurrent = PackageConfig.RemovePackage(
  552. WamRegGlobal::g_szIISOOPPoolPackageID
  553. );
  554. if( FAILED(hrCurrent) )
  555. {
  556. hrReturn = hrCurrent;
  557. SETUP_TRACE_ERROR((
  558. DBG_CONTEXT,
  559. "Failed to remove POOL package (%S). Error %08x\n",
  560. WamRegGlobal::g_szIISOOPPoolPackageID,
  561. hrReturn
  562. ));
  563. }
  564. // Unregister the global WAM CLSIDs
  565. SETUP_TRACE((
  566. DBG_CONTEXT,
  567. "DeleteIISPackage - Removing WAM CLSIDs from the registry\n"
  568. ));
  569. hrCurrent = g_RegistryConfig.UnRegisterCLSID(
  570. WamRegGlobal::g_szInProcWAMCLSID,
  571. TRUE
  572. );
  573. if( FAILED(hrCurrent) )
  574. {
  575. SETUP_TRACE((
  576. DBG_CONTEXT,
  577. "Unable to remove IP registry entries (%S). Error %08x\n",
  578. WamRegGlobal::g_szInProcWAMCLSID,
  579. hrReturn
  580. ));
  581. }
  582. hrCurrent = g_RegistryConfig.UnRegisterCLSID(
  583. WamRegGlobal::g_szOOPPoolWAMCLSID,
  584. FALSE // Already deleted VI Prog ID
  585. );
  586. if( FAILED(hrCurrent) )
  587. {
  588. hrReturn = hrCurrent;
  589. SETUP_TRACE_ERROR((
  590. DBG_CONTEXT,
  591. "Failed to remove registry entries (%S). Error %08x\n",
  592. WamRegGlobal::g_szOOPPoolWAMCLSID,
  593. hrReturn
  594. ));
  595. }
  596. }
  597. setupMgr.SetupUnInit( PackageConfig );
  598. SETUP_TRACE(( DBG_CONTEXT, "RETURN - DeleteIISPackage, hr=%08x\n", hrReturn ));
  599. return hrReturn;
  600. }
  601. /*===================================================================
  602. WamReg_RegisterSinkNotify
  603. Register a function pointer(a back pointer) to Runtime WAM_Dictator. So that
  604. any changes in WAMREG will ssync with RunTime WAM_Dictator state.
  605. Returns:
  606. HRESULT - NOERROR on success
  607. Side effects:
  608. register a function pointer.
  609. ===================================================================*/
  610. HRESULT PACKMGR_LIBAPI WamReg_RegisterSinkNotify
  611. (
  612. PFNServiceNotify pfnW3ServiceSink
  613. )
  614. {
  615. g_pfnW3ServiceSink = pfnW3ServiceSink;
  616. return NOERROR;
  617. }
  618. /*===================================================================
  619. WamReg_RegisterSinkNotify
  620. Register a function pointer(a back pointer) to Runtime WAM_Dictator. So that
  621. any changes in WAMREG will ssync with RunTime WAM_Dictator state.
  622. Returns:
  623. HRESULT - NOERROR on success
  624. Side effects:
  625. register a function pointer.
  626. ===================================================================*/
  627. HRESULT PACKMGR_LIBAPI WamReg_UnRegisterSinkNotify
  628. (
  629. void
  630. )
  631. {
  632. g_pfnW3ServiceSink = NULL;
  633. return NOERROR;
  634. }
  635. HRESULT CWamSetupManager::SetupInit( WamRegPackageConfig &refPackageConfig )
  636. {
  637. HRESULT hrReturn = NOERROR;
  638. HRESULT hrCurrent = NOERROR;
  639. DWORD dwCreateTime = 0;
  640. SETUP_TRACE(( DBG_CONTEXT, "CALL - SetupInit\n" ));
  641. hrCurrent = g_RegistryConfig.LoadWamDllPath();
  642. if( FAILED(hrCurrent) )
  643. {
  644. hrReturn = hrCurrent;
  645. SETUP_TRACE_ERROR(( DBG_CONTEXT,
  646. "FAIL - LoadWamDllPath - error=%08x",
  647. hrReturn
  648. ));
  649. }
  650. hrCurrent = DoGoryCoInitialize();
  651. if( FAILED(hrCurrent) )
  652. {
  653. hrReturn = hrCurrent;
  654. SETUP_TRACE_ERROR(( DBG_CONTEXT,
  655. "FAIL - DoGoryCoInitialize - error=%08x",
  656. hrReturn
  657. ));
  658. }
  659. do {
  660. hrCurrent = refPackageConfig.CreateCatalog();
  661. if ( hrCurrent == RETURNCODETOHRESULT( ERROR_SERVICE_DATABASE_LOCKED ) )
  662. {
  663. Sleep( CREATECATALOG_TRY_INTERVAL );
  664. }
  665. dwCreateTime += CREATECATALOG_TRY_INTERVAL;
  666. } while ( ( hrCurrent == RETURNCODETOHRESULT( ERROR_SERVICE_DATABASE_LOCKED ) ) &&
  667. ( dwCreateTime < CREATECATALOG_MAX_WAIT ) );
  668. if( FAILED(hrCurrent) )
  669. {
  670. // BUG 512023, trying to catch this error during setup to find out what is causing it
  671. DBG_ASSERT( hrCurrent != RETURNCODETOHRESULT( ERROR_SERVICE_DATABASE_LOCKED ) );
  672. hrReturn = hrCurrent;
  673. SETUP_TRACE_ERROR(( DBG_CONTEXT,
  674. "FAIL - CreateCatalog - error=%08x",
  675. hrReturn
  676. ));
  677. }
  678. hrCurrent = WamRegMetabaseConfig::MetabaseInit();
  679. if( FAILED(hrCurrent) )
  680. {
  681. hrReturn = hrCurrent;
  682. SETUP_TRACE_ERROR(( DBG_CONTEXT,
  683. "FAIL - MetabaseInit - error=%08x",
  684. hrReturn
  685. ));
  686. }
  687. SETUP_TRACE((
  688. DBG_CONTEXT,
  689. "RETURN - SetupInit. Error(%08x)\n",
  690. hrReturn
  691. ));
  692. return hrReturn;
  693. }
  694. /*===================================================================
  695. UpgradeInProcApplications
  696. From iis v4 to v5, UpgradeInProcApplications removes WAMCLSID from all
  697. inproc applications defined in IIS Version 4. So, after the upgrade,
  698. There is only one inproc WAMCLSID inside inproc package.
  699. Parameter:
  700. VOID
  701. Return: HRESULT
  702. ===================================================================*/
  703. HRESULT CWamSetupManager::UpgradeInProcApplications( VOID )
  704. {
  705. HRESULT hr = NOERROR;
  706. DWORD dwBufferSizeTemp= 0;
  707. WCHAR* pbBufferTemp = NULL;
  708. WamRegMetabaseConfig MDConfig;
  709. SETUP_TRACE((DBG_CONTEXT, "CALL - UpgradeInProcApplications\n"));
  710. DWORD dwSizePrefix = g_WamRegGlobal.g_cchMDW3SVCRoot;
  711. hr = MDConfig.MDGetPropPaths( g_WamRegGlobal.g_szMDW3SVCRoot,
  712. MD_APP_ISOLATED,
  713. &pbBufferTemp,
  714. &dwBufferSizeTemp
  715. );
  716. SETUP_TRACE_ASSERT(pbBufferTemp != NULL);
  717. if (SUCCEEDED(hr) && pbBufferTemp)
  718. {
  719. WCHAR* pszString = NULL;
  720. WCHAR* pszMetabasePath = NULL;
  721. for (pszString = (LPWSTR)pbBufferTemp;
  722. *pszString != (WCHAR)'\0' && SUCCEEDED(hr);
  723. pszString += (wcslen(pszString) + 1))
  724. {
  725. //
  726. // MDGetPropPaths returns patial paths relative to /LM/W3SVC/, therefore,
  727. // prepend the prefix string to the path
  728. //
  729. hr = g_WamRegGlobal.ConstructFullPath(
  730. g_WamRegGlobal.g_szMDW3SVCRoot,
  731. g_WamRegGlobal.g_cchMDW3SVCRoot,
  732. pszString,
  733. &pszMetabasePath
  734. );
  735. if (SUCCEEDED(hr))
  736. {
  737. //
  738. // The default application under /LM/W3SVC is created differently with
  739. // normal application. Therefore, it requires other code to remove the
  740. // the application.
  741. //
  742. if (!g_WamRegGlobal.FIsW3SVCRoot(pszMetabasePath))
  743. {
  744. hr = RemoveWAMCLSIDFromInProcApp(pszMetabasePath);
  745. if (FAILED(hr))
  746. {
  747. SETUP_TRACE_ERROR((
  748. DBG_CONTEXT,
  749. "Failed to upgrade application %S, hr = %08x\n",
  750. pszString,
  751. hr
  752. ));
  753. delete [] pszMetabasePath;
  754. pszMetabasePath = NULL;
  755. break;
  756. }
  757. }
  758. delete [] pszMetabasePath;
  759. pszMetabasePath = NULL;
  760. }
  761. else
  762. {
  763. SETUP_TRACE_ERROR((
  764. DBG_CONTEXT,
  765. "ConstructFullPath failed, partial path (%S), hr = %08x\n",
  766. pszString,
  767. hr
  768. ));
  769. }
  770. }
  771. }
  772. else
  773. {
  774. DBGPRINTF((
  775. DBG_CONTEXT,
  776. "MDGetPropPaths failed hr = %08x\n",
  777. hr
  778. ));
  779. }
  780. if (pbBufferTemp != NULL)
  781. {
  782. delete [] pbBufferTemp;
  783. pbBufferTemp = NULL;
  784. }
  785. SETUP_TRACE((
  786. DBG_CONTEXT,
  787. "RETURN - UpgradeInProcApplications. hr = %08x\n",
  788. hr
  789. ));
  790. return hr;
  791. }
  792. /*===================================================================
  793. RemoveWAMCLSIDFromInProcApp
  794. Remove a WAMCLSID from a inproc application.(called only during update from
  795. iis v4 to v5). Remove the WAM component from IIS inproc package, unregister
  796. the WAMCLSID and remove the WAMCLSID entry from the metabase.
  797. Parameter:
  798. Metabase path
  799. Return: HRESULT
  800. ===================================================================*/
  801. HRESULT CWamSetupManager::RemoveWAMCLSIDFromInProcApp
  802. (
  803. IN LPCWSTR szMetabasePath
  804. )
  805. {
  806. WCHAR szWAMCLSID[uSizeCLSID];
  807. WCHAR szPackageID[uSizeCLSID];
  808. DWORD dwAppMode = 0;
  809. HRESULT hr, hrRegistry;
  810. WamRegMetabaseConfig MDConfig;
  811. hr = MDConfig.MDGetDWORD(szMetabasePath, MD_APP_ISOLATED, &dwAppMode);
  812. // return immediately, no application is defined, nothing to delete.
  813. if (hr == MD_ERROR_DATA_NOT_FOUND || dwAppMode != 0)
  814. {
  815. return NOERROR;
  816. }
  817. if (FAILED(hr))
  818. {
  819. SETUP_TRACE_ERROR((
  820. DBG_CONTEXT,
  821. "Unexpected failure getting AppIsolated %0x\n",
  822. hr
  823. ));
  824. return hr;
  825. }
  826. // Get WAM_CLSID, and PackageID.
  827. hr = MDConfig.MDGetIDs(szMetabasePath, szWAMCLSID, szPackageID, dwAppMode);
  828. if( hr == MD_ERROR_DATA_NOT_FOUND )
  829. {
  830. SETUP_TRACE((
  831. DBG_CONTEXT,
  832. "Application (%S) is not an IIS4 IP application.\n",
  833. szMetabasePath
  834. ));
  835. return NOERROR;
  836. }
  837. // Unregister WAM
  838. hr = g_RegistryConfig.UnRegisterCLSID(szWAMCLSID, FALSE);
  839. if (FAILED(hr))
  840. {
  841. SETUP_TRACE((
  842. DBG_CONTEXT,
  843. "Failed to UnRegister WAMCLSID(%S), hr = %08x\n",
  844. szWAMCLSID,
  845. hr
  846. ));
  847. }
  848. // Delete WAMCLSID
  849. MDPropItem rgProp[IWMDP_MAX];
  850. MDConfig.InitPropItemData(&rgProp[0]);
  851. MDConfig.MDDeletePropItem(&rgProp[0], IWMDP_WAMCLSID);
  852. MDConfig.UpdateMD(rgProp, METADATA_NO_ATTRIBUTES, szMetabasePath, TRUE);
  853. return NOERROR;
  854. }
  855. /*===================================================================
  856. AppCleanupAll
  857. Parameter:
  858. VOID
  859. Return: HRESULT(DON'T CARE)
  860. ===================================================================*/
  861. HRESULT CWamSetupManager::AppCleanupAll(VOID)
  862. {
  863. HRESULT hr = NOERROR;
  864. DWORD dwBufferSizeTemp= 0;
  865. WCHAR* pbBufferTemp = NULL;
  866. WamRegMetabaseConfig MDConfig;
  867. SETUP_TRACE((DBG_CONTEXT, "CALL - AppCleanupAll\n"));
  868. DWORD dwSizePrefix = g_WamRegGlobal.g_cchMDW3SVCRoot;
  869. hr = MDConfig.MDGetPropPaths( g_WamRegGlobal.g_szMDW3SVCRoot,
  870. MD_APP_ISOLATED,
  871. &pbBufferTemp,
  872. &dwBufferSizeTemp
  873. );
  874. if (SUCCEEDED(hr))
  875. {
  876. WCHAR* pszString = NULL;
  877. WCHAR* pszMetabasePath = NULL;
  878. DBG_ASSERT(pbBufferTemp != NULL);
  879. //
  880. // PREfix has a problem with the below code. Specifically,
  881. // it has a problem with the fact that pbBufferTemp might be
  882. // NULL. There is no supporting information in the PREfix
  883. // report that confirms that there's a possible code path
  884. // where MDGetPropPaths might succeed and yet yield a NULL
  885. // pbBufferTemp. Further, we're asserting pbBufferTemp
  886. // immediately above, which is a sign that we don't expect
  887. // that pbBufferTemp can ever be NULL in this scenario.
  888. //
  889. /* INTRINSA suppress=null_pointers */
  890. for (pszString = (LPWSTR)pbBufferTemp;
  891. *pszString != (WCHAR)'\0' && SUCCEEDED(hr);
  892. pszString += (wcslen(pszString) + 1))
  893. {
  894. //
  895. // MDGetPropPaths returns patial paths relative to /LM/W3SVC/, therefore,
  896. // prepend the prefix string to the path
  897. //
  898. hr = g_WamRegGlobal.ConstructFullPath(
  899. g_WamRegGlobal.g_szMDW3SVCRoot,
  900. g_WamRegGlobal.g_cchMDW3SVCRoot,
  901. pszString,
  902. &pszMetabasePath
  903. );
  904. if (SUCCEEDED(hr))
  905. {
  906. //
  907. // The default application under /LM/W3SVC is created differently with
  908. // normal application. Therefore, it requires other code to remove the
  909. // the application.
  910. //
  911. if (!g_WamRegGlobal.FIsW3SVCRoot(pszMetabasePath))
  912. {
  913. hr = g_WamRegGlobal.DeleteApp(pszMetabasePath, FALSE, FALSE);
  914. SETUP_TRACE((
  915. DBG_CONTEXT,
  916. "AppCleanupAll, found application (%S).\n",
  917. pszMetabasePath
  918. ));
  919. if (FAILED(hr))
  920. {
  921. SETUP_TRACE_ERROR((
  922. DBG_CONTEXT,
  923. "AppCleanupAll, failed to delete application (%S), hr = %08x\n",
  924. pszString,
  925. hr
  926. ));
  927. delete [] pszMetabasePath;
  928. pszMetabasePath = NULL;
  929. break;
  930. }
  931. }
  932. delete [] pszMetabasePath;
  933. pszMetabasePath = NULL;
  934. }
  935. else
  936. {
  937. SETUP_TRACE_ERROR((
  938. DBG_CONTEXT,
  939. "AppCleanupAll, failed to construct full path, partial path (%S), hr = %08x\n",
  940. pszString,
  941. hr
  942. ));
  943. }
  944. }
  945. }
  946. else
  947. {
  948. SETUP_TRACE_ERROR((
  949. DBG_CONTEXT,
  950. "AppCleanupAll: GetPropPaths failed hr = %08x\n",
  951. hr
  952. ));
  953. }
  954. delete [] pbBufferTemp;
  955. pbBufferTemp = NULL;
  956. return hr;
  957. }
  958. /*===================================================================
  959. DoGoryCoInitialize
  960. Description:
  961. CoInitialize() of COM is extremely funny function. It can fail
  962. and respond with S_FALSE which is to be ignored by the callers!
  963. On other error conditions it is possible that there is a threading
  964. mismatch. Rather than replicate the code in multiple places, here
  965. we try to consolidate the functionality in some rational manner.
  966. Arguments:
  967. None
  968. Returns:
  969. HRESULT = NOERROR on (S_OK & S_FALSE)
  970. other errors if any failure
  971. Side effects:
  972. Create a Default IIS Package. This package will exist until
  973. IIS is de-installed.
  974. ===================================================================*/
  975. HRESULT
  976. CWamSetupManager::DoGoryCoInitialize( VOID )
  977. {
  978. // do the call to CoInitialize()
  979. m_hrCoInit = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  980. //
  981. // S_FALSE and S_OK are success. Everything else is a failure and you don't need to call CoUninitialize.
  982. //
  983. if ( S_FALSE == m_hrCoInit )
  984. {
  985. //
  986. // It is okay to have failure (S_FALSE) in CoInitialize()
  987. // This error is to be ignored and balanced with CoUninitialize()
  988. // We will reset the hr so that subsequent use is rational
  989. //
  990. SETUP_TRACE((
  991. DBG_CONTEXT,
  992. "DoGoryCoInitialize found duplicate CoInitialize.\n"
  993. ));
  994. m_hrCoInit = NOERROR;
  995. }
  996. else if( FAILED(m_hrCoInit) )
  997. {
  998. SETUP_TRACE_ERROR((
  999. DBG_CONTEXT,
  1000. "DoGoryCoInitialize() error %08x",
  1001. m_hrCoInit
  1002. ));
  1003. }
  1004. return m_hrCoInit;
  1005. } // DoGoryCoInitialize()