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.

1427 lines
47 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*--------------------------------------------------------------------------------------------------------
  3. *
  4. * Module Name:
  5. *
  6. * hydraoc.cpp
  7. *
  8. * Abstract:
  9. *
  10. * This file implements the optional component HydraOc for Terminal Server Installations.
  11. *
  12. *
  13. * Author:
  14. *
  15. * Makarand Patwardhan - March 6, 1998
  16. *
  17. * Environment:
  18. *
  19. * User Mode
  20. * -------------------------------------------------------------------------------------------------------*/
  21. #include "stdafx.h"
  22. #include "hydraoc.h"
  23. #include "pages.h"
  24. #include "subtoggle.h"
  25. #include "subcore.h"
  26. #include "ocmanage.h"
  27. #define INITGUID // must be before iadmw.h
  28. #include "iadmw.h" // Interface header
  29. #include "iiscnfg.h" // MD_ & IIS_MD_ defines
  30. #define REASONABLE_TIMEOUT 1000
  31. #define TRANS_ADD 0
  32. #define TRANS_DEL 1
  33. #define TRANS_PRINT_PATH 2
  34. #define STRING_TS_WEBCLIENT_INSTALL _T("TSWebClient.Install")
  35. #define STRING_TS_WEBCLIENT_UNINSTALL _T("TSWebClient.UnInstall")
  36. #define STRING_TS_WEBCLIENT _T("TSWebClient")
  37. #define STRING_TS_WEBCLIENT_DIR _T("\\web\\tsweb")
  38. /*--------------------------------------------------------------------------------------------------------
  39. * declarations.
  40. * -------------------------------------------------------------------------------------------------------*/
  41. EXTERN_C BOOL WINAPI LinkWindow_RegisterClass() ;
  42. EXTERN_C BOOL WINAPI LinkWindow_UnregisterClass( HINSTANCE ) ;
  43. //
  44. // component manager message handlers.
  45. //
  46. DWORD OnPreinitialize ();
  47. DWORD OnInitComponent (PSETUP_INIT_COMPONENT psc);
  48. DWORD OnExtraRoutines (PEXTRA_ROUTINES pExtraRoutines);
  49. DWORD OnSetLanguage ();
  50. DWORD OnQueryImage ();
  51. DWORD OnSetupRequestPages (WizardPagesType ePageType, SETUP_REQUEST_PAGES *pRequestPages);
  52. DWORD OnQuerySelStateChange (LPCTSTR SubcomponentId, UINT SelectionState, LONG Flag);
  53. DWORD OnCalcDiskSpace (LPCTSTR SubcomponentId, DWORD addComponent, HDSKSPC dspace);
  54. DWORD OnQueueFileOps (LPCTSTR SubcomponentId, HSPFILEQ queue);
  55. DWORD OnNotificationFromQueue ();
  56. DWORD OnQueryStepCount (LPCTSTR SubComponentId);
  57. DWORD OnCompleteInstallation (LPCTSTR SubcomponentId);
  58. DWORD OnCleanup ();
  59. DWORD OnQueryState (LPCTSTR SubComponentId, UINT whichstate);
  60. DWORD OnNeedMedia ();
  61. DWORD OnAboutToCommitQueue (LPCTSTR SubcomponentId);
  62. DWORD OnQuerySkipPage ();
  63. DWORD OnWizardCreated ();
  64. DWORD_PTR WebClientSetup (LPCTSTR, LPCTSTR, UINT, UINT_PTR, PVOID);
  65. //
  66. // private utility functions.
  67. //
  68. BOOL OpenMetabaseAndDoStuff(WCHAR *wszVDir, WCHAR *wszDir, int iTrans);
  69. BOOL GetVdirPhysicalPath(IMSAdminBase *pIMSAdminBase,WCHAR * wszVDir,WCHAR *wszStringPathToFill);
  70. BOOL AddVirtualDir(IMSAdminBase *pIMSAdminBase, WCHAR *wszVDir, WCHAR *wszDir);
  71. BOOL RemoveVirtualDir(IMSAdminBase *pIMSAdminBase, WCHAR *wszVDir);
  72. INT CheckifServiceExist(LPCTSTR lpServiceName);
  73. /*--------------------------------------------------------------------------------------------------------
  74. * defines
  75. * -------------------------------------------------------------------------------------------------------*/
  76. /*--------------------------------------------------------------------------------------------------------
  77. * constants
  78. -------------------------------------------------------------------------------------------------------*/
  79. //
  80. // global variables and functions to access them.
  81. //
  82. SubCompToggle *gpSubCompToggle = NULL;
  83. SubCompCoreTS *gpSubCompCoreTS = NULL;
  84. COCPageData *gpAppSrvUninstallPageData = NULL;
  85. DefSecPageData *gpSecPageData = NULL;
  86. COCPageData *gpPermPageData = NULL;
  87. COCPageData *gpAppPageData = NULL;
  88. /*--------------------------------------------------------------------------------------------------------
  89. * LPCTSTR GetOCFunctionName(UINT uiFunction)
  90. * utility function for logging the oc messages.
  91. * returns oc manager function name from funciton id.
  92. * returns _T("Unknown Function") if its unknown.
  93. * -------------------------------------------------------------------------------------------------------*/
  94. LPCTSTR GetOCFunctionName(UINT uiFunction)
  95. {
  96. struct
  97. {
  98. UINT msg;
  99. TCHAR *desc;
  100. } gMsgs[] =
  101. {
  102. {OC_PREINITIALIZE, TEXT("OC_PREINITIALIZE")},
  103. {OC_INIT_COMPONENT, TEXT("OC_INIT_COMPONENT")},
  104. {OC_SET_LANGUAGE, TEXT("OC_SET_LANGUAGE")},
  105. {OC_QUERY_IMAGE, TEXT("OC_QUERY_IMAGE")},
  106. {OC_REQUEST_PAGES, TEXT("OC_REQUEST_PAGES")},
  107. {OC_QUERY_CHANGE_SEL_STATE, TEXT("OC_QUERY_CHANGE_SEL_STATE")},
  108. {OC_CALC_DISK_SPACE, TEXT("OC_CALC_DISK_SPACE")},
  109. {OC_QUEUE_FILE_OPS, TEXT("OC_QUEUE_FILE_OPS")},
  110. {OC_NOTIFICATION_FROM_QUEUE,TEXT("OC_NOTIFICATION_FROM_QUEUE")},
  111. {OC_QUERY_STEP_COUNT, TEXT("OC_QUERY_STEP_COUNT")},
  112. {OC_COMPLETE_INSTALLATION, TEXT("OC_COMPLETE_INSTALLATION")},
  113. {OC_CLEANUP, TEXT("OC_CLEANUP")},
  114. {OC_QUERY_STATE, TEXT("OC_QUERY_STATE")},
  115. {OC_NEED_MEDIA, TEXT("OC_NEED_MEDIA")},
  116. {OC_ABOUT_TO_COMMIT_QUEUE, TEXT("OC_ABOUT_TO_COMMIT_QUEUE")},
  117. {OC_QUERY_SKIP_PAGE, TEXT("OC_QUERY_SKIP_PAGE")},
  118. {OC_WIZARD_CREATED, TEXT("OC_WIZARD_CREATED")},
  119. {OC_EXTRA_ROUTINES, TEXT("OC_EXTRA_ROUTINES")}
  120. };
  121. for (int i = 0; i < sizeof(gMsgs) / sizeof(gMsgs[0]); i++)
  122. {
  123. if (gMsgs[i].msg == uiFunction)
  124. return gMsgs[i].desc;
  125. }
  126. return _T("Unknown Function");
  127. }
  128. /*--------------------------------------------------------------------------------------------------------
  129. * called by CRT when _DllMainCRTStartup is the DLL entry point
  130. * -------------------------------------------------------------------------------------------------------*/
  131. BOOL WINAPI DllMain(IN HINSTANCE hinstance, IN DWORD reason, IN LPVOID /*reserved*/ )
  132. {
  133. SetInstance( hinstance );
  134. switch(reason)
  135. {
  136. case DLL_PROCESS_ATTACH:
  137. TCHAR szLogFile[MAX_PATH];
  138. ExpandEnvironmentStrings(LOGFILE, szLogFile, MAX_PATH);
  139. LOGMESSAGEINIT(szLogFile, MODULENAME);
  140. break;
  141. case DLL_THREAD_ATTACH:
  142. case DLL_PROCESS_DETACH:
  143. case DLL_THREAD_DETACH:
  144. break;
  145. }
  146. return(TRUE); // for successful process_attach
  147. }
  148. /*--------------------------------------------------------------------------------------------------------
  149. * This is our export function which will be called by OC Manager
  150. * -------------------------------------------------------------------------------------------------------*/
  151. DWORD_PTR HydraOc(
  152. IN LPCTSTR ComponentId,
  153. IN LPCTSTR SubcomponentId,
  154. IN UINT Function,
  155. IN UINT_PTR Param1,
  156. IN OUT PVOID Param2
  157. )
  158. {
  159. // we use this variable to track if we receive OnCompleteInstallation or not.
  160. // there is a problem with ocm which aborts all the components if any of them
  161. // does something wrong with file queue.
  162. static BOOL sbGotCompleteMessage = FALSE;
  163. LOGMESSAGE1(_T("Entering %s"), GetOCFunctionName(Function));
  164. if ((OC_PREINITIALIZE != Function) && SubcomponentId)
  165. LOGMESSAGE2(_T("Component=%s, SubComponent=%s"), ComponentId, SubcomponentId);
  166. else
  167. LOGMESSAGE2(_T("Component=%s, SubComponent=%s"), ComponentId, _T("(null)"));
  168. DWORD_PTR rc;
  169. if (SubcomponentId && _tcsicmp(SubcomponentId, _T("tswebClient")) == 0)
  170. {
  171. rc = WebClientSetup(ComponentId, SubcomponentId, Function, Param1, Param2);
  172. LOGMESSAGE2(_T("%s Done. Returning %lu\r\n\r\n"), GetOCFunctionName(Function), rc);
  173. return rc;
  174. }
  175. // since we are supporting only one component.
  176. ASSERT(_tcsicmp(APPSRV_COMPONENT_NAME, ComponentId) == 0);
  177. switch(Function)
  178. {
  179. case OC_PREINITIALIZE:
  180. rc = OnPreinitialize();
  181. break;
  182. case OC_INIT_COMPONENT:
  183. rc = OnInitComponent((PSETUP_INIT_COMPONENT)Param2);
  184. break;
  185. case OC_EXTRA_ROUTINES:
  186. rc = OnExtraRoutines((PEXTRA_ROUTINES)Param2);
  187. break;
  188. case OC_SET_LANGUAGE:
  189. rc = OnSetLanguage();
  190. break;
  191. case OC_QUERY_IMAGE:
  192. rc = OnQueryImage();
  193. break;
  194. case OC_REQUEST_PAGES:
  195. rc = OnSetupRequestPages(WizardPagesType(Param1), PSETUP_REQUEST_PAGES (Param2));
  196. break;
  197. case OC_QUERY_CHANGE_SEL_STATE:
  198. rc = OnQuerySelStateChange(SubcomponentId, (UINT)Param1, LONG(ULONG_PTR(Param2)));
  199. break;
  200. case OC_CALC_DISK_SPACE:
  201. rc = OnCalcDiskSpace(SubcomponentId, (DWORD)Param1, Param2);
  202. break;
  203. case OC_QUEUE_FILE_OPS:
  204. rc = OnQueueFileOps(SubcomponentId, (HSPFILEQ)Param2);
  205. break;
  206. case OC_NOTIFICATION_FROM_QUEUE:
  207. rc = OnNotificationFromQueue();
  208. break;
  209. case OC_QUERY_STEP_COUNT:
  210. rc = OnQueryStepCount(SubcomponentId);
  211. break;
  212. case OC_COMPLETE_INSTALLATION:
  213. sbGotCompleteMessage = TRUE;
  214. rc = OnCompleteInstallation(SubcomponentId);
  215. break;
  216. case OC_CLEANUP:
  217. rc = OnCleanup();
  218. if (!sbGotCompleteMessage)
  219. {
  220. if (StateObject.IsStandAlone())
  221. {
  222. LOGMESSAGE0(_T("Error:StandAlone:TSOC Did not get OC_COMPLETE_INSTALLATION."));
  223. }
  224. else
  225. {
  226. LOGMESSAGE0(_T("Error:TSOC Did not get OC_COMPLETE_INSTALLATION."));
  227. }
  228. }
  229. break;
  230. case OC_QUERY_STATE:
  231. rc = OnQueryState(SubcomponentId, (UINT)Param1);
  232. break;
  233. case OC_NEED_MEDIA:
  234. rc = OnNeedMedia();
  235. break;
  236. case OC_ABOUT_TO_COMMIT_QUEUE:
  237. rc = OnAboutToCommitQueue(SubcomponentId);
  238. break;
  239. case OC_QUERY_SKIP_PAGE:
  240. rc = OnQuerySkipPage();
  241. break;
  242. case OC_WIZARD_CREATED:
  243. rc = OnWizardCreated();
  244. break;
  245. default:
  246. rc = 0; // it means we do not recognize this command.
  247. break;
  248. }
  249. LOGMESSAGE2(_T("%s Done. Returning %lu\r\n\r\n"), GetOCFunctionName(Function), rc);
  250. return rc;
  251. }
  252. /*--------------------------------------------------------------------------------------------------------
  253. * OC Manager message handlers
  254. * -------------------------------------------------------------------------------------------------------*/
  255. DWORD OnPreinitialize(VOID)
  256. {
  257. #ifdef ANSI
  258. return OCFLAG_ANSI;
  259. #else
  260. return OCFLAG_UNICODE;
  261. #endif
  262. }
  263. /*--------------------------------------------------------------------------------------------------------
  264. * OnInitComponent()
  265. *
  266. * handler for OC_INIT_COMPONENT
  267. * -------------------------------------------------------------------------------------------------------*/
  268. DWORD OnInitComponent(PSETUP_INIT_COMPONENT psc)
  269. {
  270. ASSERT(psc);
  271. //
  272. // let the ocmanager know our version
  273. //
  274. psc->ComponentVersion = COMPONENT_VERSION;
  275. //
  276. // Is this component written for newer version than the oc manager ?
  277. //
  278. if (COMPONENT_VERSION > psc->OCManagerVersion)
  279. {
  280. LOGMESSAGE2(_T("ERROR:OnInitComponent: COMPONENT_VERSION(%x) > psc->OCManagerVersion(%x)"), COMPONENT_VERSION, psc->OCManagerVersion);
  281. return ERROR_CALL_NOT_IMPLEMENTED;
  282. }
  283. if (!StateObject.Initialize(psc))
  284. {
  285. return ERROR_CANCELLED; // due to ERROR_OUTOFMEMORY;
  286. }
  287. // if its standalone (!guimode) setup, We must have Hydra in product suite by now.
  288. // ASSERT( StateObject.IsGuiModeSetup() || DoesHydraKeysExists() );
  289. //
  290. // now create our subcomponents
  291. //
  292. gpSubCompToggle = new SubCompToggle;
  293. gpSubCompCoreTS = new SubCompCoreTS;
  294. if (!gpSubCompToggle || !gpSubCompCoreTS)
  295. return ERROR_CANCELLED;
  296. //
  297. // if initialization of any of the sub component fails
  298. // fail the setup
  299. //
  300. if (!gpSubCompToggle->Initialize() ||
  301. !gpSubCompCoreTS->Initialize())
  302. return ERROR_CANCELLED;
  303. return NO_ERROR;
  304. }
  305. DWORD
  306. OnExtraRoutines(
  307. PEXTRA_ROUTINES pExtraRoutines
  308. )
  309. {
  310. ASSERT(pExtraRoutines);
  311. return(SetExtraRoutines(pExtraRoutines) ? ERROR_SUCCESS : ERROR_CANCELLED);
  312. }
  313. /*--------------------------------------------------------------------------------------------------------
  314. * OnCalcDiskSpace()
  315. *
  316. * handler for OC_ON_CALC_DISK_SPACE
  317. * -------------------------------------------------------------------------------------------------------*/
  318. DWORD OnCalcDiskSpace(
  319. LPCTSTR /* SubcomponentId */,
  320. DWORD addComponent,
  321. HDSKSPC dspace
  322. )
  323. {
  324. return gpSubCompCoreTS->OnCalcDiskSpace(addComponent, dspace);
  325. }
  326. /*--------------------------------------------------------------------------------------------------------
  327. * OnQueueFileOps()
  328. *
  329. * handler for OC_QUEUE_FILE_OPS
  330. * -------------------------------------------------------------------------------------------------------*/
  331. DWORD OnQueueFileOps(LPCTSTR SubcomponentId, HSPFILEQ queue)
  332. {
  333. if (SubcomponentId == NULL)
  334. {
  335. return gpSubCompCoreTS->OnQueueFiles( queue );
  336. }
  337. else if (_tcsicmp(SubcomponentId, APPSRV_COMPONENT_NAME) == 0)
  338. {
  339. return gpSubCompToggle->OnQueueFiles( queue );
  340. }
  341. else
  342. {
  343. ASSERT(FALSE);
  344. LOGMESSAGE1(_T("ERROR, Got a OnQueueFileOps with unknown SubComp(%s)"), SubcomponentId);
  345. return 0;
  346. }
  347. }
  348. /*--------------------------------------------------------------------------------------------------------
  349. * OnCompleteInstallation
  350. *
  351. * handler for OC_COMPLETE_INSTALLATION
  352. * -------------------------------------------------------------------------------------------------------*/
  353. DWORD OnCompleteInstallation(LPCTSTR SubcomponentId)
  354. {
  355. static BOOL sbStateUpdated = FALSE;
  356. if (!sbStateUpdated)
  357. {
  358. StateObject.UpdateState();
  359. sbStateUpdated = TRUE;
  360. }
  361. if (SubcomponentId == NULL)
  362. {
  363. return gpSubCompCoreTS->OnCompleteInstall();
  364. }
  365. else if (_tcsicmp(SubcomponentId, APPSRV_COMPONENT_NAME) == 0)
  366. {
  367. return gpSubCompToggle->OnCompleteInstall();
  368. }
  369. else
  370. {
  371. ASSERT(FALSE);
  372. LOGMESSAGE1(_T("ERROR, Got a Complete Installation with unknown SubComp(%s)"), SubcomponentId);
  373. return 0;
  374. }
  375. }
  376. /*--------------------------------------------------------------------------------------------------------
  377. * OnSetLanguage()
  378. *
  379. * handler for OC_SET_LANGUAGE
  380. * -------------------------------------------------------------------------------------------------------*/
  381. DWORD OnSetLanguage()
  382. {
  383. return false;
  384. }
  385. /*--------------------------------------------------------------------------------------------------------
  386. * OnSetLanguage()
  387. *
  388. * handler for OC_SET_LANGUAGE
  389. * -------------------------------------------------------------------------------------------------------*/
  390. DWORD OnQueryImage()
  391. {
  392. return NULL;
  393. }
  394. /*--------------------------------------------------------------------------------------------------------
  395. * OnSetupRequestPages
  396. *
  397. * Prepares wizard pages and returns them to the OC Manager
  398. * -------------------------------------------------------------------------------------------------------*/
  399. DWORD OnSetupRequestPages (WizardPagesType ePageType, SETUP_REQUEST_PAGES *pRequestPages)
  400. {
  401. if (ePageType == WizPagesEarly)
  402. {
  403. ASSERT(pRequestPages);
  404. const UINT uiPages = 4;
  405. // if we are provided sufficient space for our pages
  406. if (pRequestPages->MaxPages >= uiPages )
  407. {
  408. //
  409. // Pages will be deleted in PSPCB_RELEASE in OCPage::PropSheetPageProc
  410. //
  411. LinkWindow_RegisterClass();
  412. gpAppPageData = new COCPageData;
  413. AppSrvWarningPage *pAppSrvWarnPage = new AppSrvWarningPage(gpAppPageData);
  414. gpSecPageData = new DefSecPageData;
  415. DefaultSecurityPage *pSecPage = new DefaultSecurityPage(gpSecPageData);
  416. gpPermPageData = new COCPageData;
  417. PermPage *pPermPage = new PermPage(gpPermPageData);
  418. gpAppSrvUninstallPageData = new COCPageData;
  419. AppSrvUninstallpage *pAppSrvUninstallPage = new AppSrvUninstallpage(gpAppSrvUninstallPageData);
  420. if (pAppSrvWarnPage && pAppSrvWarnPage->Initialize() &&
  421. pSecPage && pSecPage->Initialize() &&
  422. pPermPage && pPermPage->Initialize() &&
  423. pAppSrvUninstallPage && pAppSrvUninstallPage->Initialize()
  424. )
  425. {
  426. ASSERT(pRequestPages->Pages);
  427. pRequestPages->Pages[0] = CreatePropertySheetPage((PROPSHEETPAGE *) pAppSrvWarnPage);
  428. pRequestPages->Pages[1] = CreatePropertySheetPage((PROPSHEETPAGE *) pSecPage);
  429. pRequestPages->Pages[2] = CreatePropertySheetPage((PROPSHEETPAGE *) pPermPage);
  430. pRequestPages->Pages[3] = CreatePropertySheetPage((PROPSHEETPAGE *) pAppSrvUninstallPage);
  431. ASSERT(pRequestPages->Pages[0]);
  432. ASSERT(pRequestPages->Pages[1]);
  433. ASSERT(pRequestPages->Pages[2]);
  434. ASSERT(pRequestPages->Pages[3]);
  435. }
  436. else
  437. {
  438. //
  439. // failed to allocate memory
  440. //
  441. if (gpAppPageData)
  442. delete gpAppPageData;
  443. gpAppPageData = NULL;
  444. if (pAppSrvWarnPage)
  445. delete pAppSrvWarnPage;
  446. pAppSrvWarnPage = NULL;
  447. if (gpSecPageData)
  448. delete gpSecPageData;
  449. gpSecPageData = NULL;
  450. if (pSecPage)
  451. delete pSecPage;
  452. pSecPage = NULL;
  453. if (gpPermPageData)
  454. delete gpPermPageData;
  455. gpPermPageData = NULL;
  456. if (pPermPage)
  457. delete pPermPage;
  458. pPermPage =NULL;
  459. if (gpAppSrvUninstallPageData)
  460. delete gpAppSrvUninstallPageData;
  461. gpAppSrvUninstallPageData = NULL;
  462. if (pAppSrvUninstallPage)
  463. delete pAppSrvUninstallPage;
  464. pAppSrvUninstallPage = NULL;
  465. SetLastError(ERROR_OUTOFMEMORY);
  466. return DWORD(-1);
  467. }
  468. }
  469. return uiPages;
  470. }
  471. return 0;
  472. }
  473. /*--------------------------------------------------------------------------------------------------------
  474. * OnWizardCreated()
  475. * -------------------------------------------------------------------------------------------------------*/
  476. DWORD OnWizardCreated()
  477. {
  478. return NO_ERROR;
  479. }
  480. /*--------------------------------------------------------------------------------------------------------
  481. * OnQuerySkipPage()
  482. *
  483. * don't let the user deselect the sam component
  484. * -------------------------------------------------------------------------------------------------------*/
  485. DWORD OnQuerySkipPage()
  486. {
  487. return false;
  488. }
  489. /*--------------------------------------------------------------------------------------------------------
  490. * OnQuerySelStateChange(LPCTSTR SubcomponentId, UINT SelectionState, LONG Flag);
  491. *
  492. * informs that user has changed the state of the component/subcomponent and asks approval
  493. * -------------------------------------------------------------------------------------------------------*/
  494. DWORD OnQuerySelStateChange(LPCTSTR SubcomponentId, UINT SelectionState, LONG Flag)
  495. {
  496. BOOL bNewState = SelectionState;
  497. BOOL bDirectSelection = Flag & OCQ_ACTUAL_SELECTION;
  498. LOGMESSAGE3(_T("OnQuerySelStateChange for %s, NewState = %d, DirectSelect = %s"), SubcomponentId, SelectionState, bDirectSelection ? _T("True") : _T("False"));
  499. return gpSubCompToggle->OnQuerySelStateChange(bNewState, bDirectSelection);
  500. }
  501. /*--------------------------------------------------------------------------------------------------------
  502. * OnCleanup()
  503. *
  504. * handler for OC_CLEANUP
  505. * -------------------------------------------------------------------------------------------------------*/
  506. DWORD OnCleanup()
  507. {
  508. if (gpAppPageData)
  509. delete gpAppPageData;
  510. if (gpSecPageData)
  511. delete gpSecPageData;
  512. if (gpPermPageData)
  513. delete gpPermPageData;
  514. if (gpAppSrvUninstallPageData)
  515. delete gpAppSrvUninstallPageData;
  516. if (gpSubCompToggle)
  517. delete gpSubCompToggle;
  518. if (gpSubCompCoreTS)
  519. delete gpSubCompCoreTS;
  520. // DestroySetupData();
  521. DestroyExtraRoutines();
  522. return NO_ERROR;
  523. }
  524. /*--------------------------------------------------------------------------------------------------------
  525. * OnQueryState()
  526. *
  527. * handler for OC_QUERY_STATE
  528. * -------------------------------------------------------------------------------------------------------*/
  529. DWORD OnQueryState(LPCTSTR SubComponentId, UINT whichstate)
  530. {
  531. ASSERT(OCSELSTATETYPE_ORIGINAL == whichstate ||
  532. OCSELSTATETYPE_CURRENT == whichstate ||
  533. OCSELSTATETYPE_FINAL == whichstate);
  534. TCHAR szState[256];
  535. switch (whichstate)
  536. {
  537. case OCSELSTATETYPE_ORIGINAL:
  538. _tcscpy(szState, _T("Original"));
  539. break;
  540. case OCSELSTATETYPE_CURRENT:
  541. _tcscpy(szState, _T("Current"));
  542. break;
  543. case OCSELSTATETYPE_FINAL:
  544. _tcscpy(szState, _T("Final"));
  545. break;
  546. default:
  547. ASSERT(FALSE);
  548. return ERROR_BAD_ARGUMENTS;
  549. }
  550. DWORD dwReturn = gpSubCompToggle->OnQueryState(whichstate);
  551. TCHAR szReturn[] = _T("SubcompUseOcManagerUknownState");
  552. switch (dwReturn)
  553. {
  554. case SubcompOn:
  555. _tcscpy(szReturn, _T("SubcompOn"));
  556. break;
  557. case SubcompUseOcManagerDefault:
  558. _tcscpy(szReturn, _T("SubcompUseOcManagerDefault"));
  559. break;
  560. case SubcompOff:
  561. _tcscpy(szReturn, _T("SubcompOff"));
  562. break;
  563. default:
  564. ASSERT(FALSE);
  565. }
  566. LOGMESSAGE3(_T("Query State Asked For %s, %s. Returning %s"), SubComponentId, szState, szReturn);
  567. return dwReturn;
  568. }
  569. /*--------------------------------------------------------------------------------------------------------
  570. * OnNotificationFromQueue()
  571. *
  572. * handler for OC_NOTIFICATION_FROM_QUEUE
  573. *
  574. * NOTE: although this notification is defined,
  575. * it is currently unimplemented in oc manager
  576. * -------------------------------------------------------------------------------------------------------*/
  577. DWORD OnNotificationFromQueue()
  578. {
  579. return NO_ERROR;
  580. }
  581. /*--------------------------------------------------------------------------------------------------------
  582. * OnQueryStepCount
  583. *
  584. * handler for OC_QUERY_STEP_COUNT
  585. * -------------------------------------------------------------------------------------------------------*/
  586. DWORD OnQueryStepCount(LPCTSTR /* SubcomponentId */)
  587. {
  588. //
  589. // now return the ticks for the component
  590. //
  591. return gpSubCompCoreTS->OnQueryStepCount() + gpSubCompToggle->OnQueryStepCount();
  592. }
  593. /*--------------------------------------------------------------------------------------------------------
  594. * OnNeedMedia()
  595. *
  596. * handler for OC_NEED_MEDIA
  597. * -------------------------------------------------------------------------------------------------------*/
  598. DWORD OnNeedMedia()
  599. {
  600. return false;
  601. }
  602. /*--------------------------------------------------------------------------------------------------------
  603. * OnAboutToCommitQueue()
  604. *
  605. * handler for OC_ABOUT_TO_COMMIT_QUEUE
  606. * -------------------------------------------------------------------------------------------------------*/
  607. DWORD OnAboutToCommitQueue(LPCTSTR /* SubcomponentId */)
  608. {
  609. return NO_ERROR;
  610. }
  611. /*--------------------------------------------------------------------------------------------------------
  612. * BOOL DoesHydraKeysExists()
  613. *
  614. * checks if Teminal server string exists in the product suite key.
  615. * -------------------------------------------------------------------------------------------------------*/
  616. BOOL DoesHydraKeysExists()
  617. {
  618. BOOL bStringExists = FALSE;
  619. DWORD dw = IsStringInMultiString(
  620. HKEY_LOCAL_MACHINE,
  621. PRODUCT_SUITE_KEY,
  622. PRODUCT_SUITE_VALUE,
  623. TS_PRODUCT_SUITE_STRING,
  624. &bStringExists);
  625. return (dw == ERROR_SUCCESS) && bStringExists;
  626. }
  627. /*--------------------------------------------------------------------------------------------------------
  628. * DWORD IsStringInMultiString(HKEY hkey, LPCTSTR szkey, LPCTSTR szvalue, LPCTSTR szCheckForString, BOOL *pbFound)
  629. * checks if parameter string exists in given multistring.
  630. * returns error code.
  631. * -------------------------------------------------------------------------------------------------------*/
  632. DWORD IsStringInMultiString(HKEY hkey, LPCTSTR szkey, LPCTSTR szvalue, LPCTSTR szCheckForString, BOOL *pbFound)
  633. {
  634. ASSERT(szkey && *szkey);
  635. ASSERT(szvalue && *szvalue);
  636. ASSERT(szCheckForString&& *szCheckForString);
  637. ASSERT(*szkey != '\\');
  638. ASSERT(pbFound);
  639. // not yet found.
  640. *pbFound = FALSE;
  641. CRegistry reg;
  642. DWORD dwError = reg.OpenKey(hkey, szkey, KEY_READ); // open up the required key.
  643. if (dwError == NO_ERROR)
  644. {
  645. LPTSTR szSuiteValue;
  646. DWORD dwSize;
  647. dwError = reg.ReadRegMultiString(szvalue, &szSuiteValue, &dwSize);
  648. if (dwError == NO_ERROR)
  649. {
  650. LPCTSTR pTemp = szSuiteValue;
  651. while(_tcslen(pTemp) > 0 )
  652. {
  653. if (_tcscmp(pTemp, szCheckForString) == 0)
  654. {
  655. *pbFound = TRUE;
  656. break;
  657. }
  658. pTemp += _tcslen(pTemp) + 1; // point to the next string within the multistring.
  659. if ( DWORD(pTemp - szSuiteValue) > (dwSize / sizeof(TCHAR)))
  660. break; // temporary pointer passes the size of the szSuiteValue something is wrong with szSuiteValue.
  661. }
  662. }
  663. }
  664. return dwError;
  665. }
  666. /*--------------------------------------------------------------------------------------------------------
  667. * DWORD AppendStringToMultiString(HKEY hkey, LPCTSTR szSuitekey, LPCTSTR szSuitevalue, LPCTSTR szAppend)
  668. * appends given string to the given multi_sz value
  669. * the given key / value must exist.
  670. * returns error code.
  671. * -------------------------------------------------------------------------------------------------------*/
  672. DWORD AppendStringToMultiString(HKEY hkey, LPCTSTR szSuitekey, LPCTSTR szSuitevalue, LPCTSTR szAppend)
  673. {
  674. ASSERT(szSuitekey && *szSuitekey);
  675. ASSERT(szSuitevalue && *szSuitevalue);
  676. ASSERT(szAppend && *szAppend);
  677. ASSERT(*szSuitekey != '\\');
  678. CRegistry reg;
  679. // open the registry key.
  680. DWORD dwResult = reg.OpenKey(hkey, szSuitekey, KEY_READ | KEY_WRITE);
  681. if (dwResult == ERROR_SUCCESS)
  682. {
  683. DWORD dwSize = 0;
  684. LPTSTR strOriginalString = 0;
  685. // read our multi string
  686. dwResult = reg.ReadRegMultiString(szSuitevalue, &strOriginalString, &dwSize);
  687. if (dwResult == ERROR_SUCCESS)
  688. {
  689. // now calculate the Memory required for appending the string.
  690. // as dwOldSize is in bytes and we are using TCHARs
  691. DWORD dwMemReq = dwSize + ((_tcslen(szAppend) + 2) * sizeof(TCHAR) / sizeof(BYTE));
  692. // NOTE: if dwSize is >= 1 we just require
  693. // dwSize + ((_tcslen(szAppend) + 1) * sizeof(TCHAR) / sizeof(BYTE));
  694. // But in case its 0 we provide space for an additional terminating null
  695. LPTSTR szProductSuite = (LPTSTR ) new BYTE [dwMemReq];
  696. if (!szProductSuite)
  697. {
  698. return ERROR_OUTOFMEMORY;
  699. }
  700. CopyMemory(szProductSuite, strOriginalString, dwSize);
  701. // convert the size into TCHARs
  702. dwSize = dwSize * sizeof(BYTE) / sizeof(TCHAR);
  703. if (dwSize <= 2)
  704. {
  705. // there are no strings out there.
  706. _tcscpy(szProductSuite, szAppend);
  707. // new size including terminating null in tchar
  708. dwSize = _tcslen(szAppend) + 2;
  709. }
  710. else
  711. {
  712. // there are strings in its. so append our string before the terminating null.
  713. // for example for this string "A\0B\0\0" dwSize == 5 and we are doing tcscat at "A\0B\0\0" + 4
  714. _tcscpy(szProductSuite + dwSize - 1, szAppend);
  715. // new size including terminating null in tchar
  716. dwSize += _tcslen(szAppend) + 1;
  717. }
  718. // now append a final terminating null character.
  719. *(szProductSuite + dwSize-1) = NULL;
  720. // reconvert size into bytes.
  721. dwSize *= sizeof(TCHAR) / sizeof(BYTE);
  722. // and finally write the final string.
  723. dwResult = reg.WriteRegMultiString(szSuitevalue, szProductSuite, dwSize);
  724. delete [] szProductSuite;
  725. }
  726. }
  727. return dwResult;
  728. }
  729. /*--------------------------------------------------------------------------------------------------------
  730. * BOOL GetStringValue(HINF hinf, LPCTSTR section, LPCTSTR key, LPTSTR outputbuffer, DWORD dwSize)
  731. * returns the given string value under given section.
  732. * returns success
  733. * -------------------------------------------------------------------------------------------------------*/
  734. DWORD GetStringValue(HINF hinf, LPCTSTR section, LPCTSTR key, LPTSTR outputbuffer, DWORD dwSize)
  735. {
  736. INFCONTEXT context;
  737. BOOL rc = SetupFindFirstLine(
  738. hinf,
  739. section,
  740. key,
  741. &context
  742. );
  743. if (rc)
  744. {
  745. rc = SetupGetStringField(
  746. &context,
  747. 1,
  748. outputbuffer,
  749. dwSize,
  750. &dwSize
  751. );
  752. }
  753. if (!rc)
  754. return GetLastError();
  755. else
  756. return ERROR_SUCCESS;
  757. }
  758. DWORD_PTR WebClientSetup(LPCTSTR ComponentId,
  759. LPCTSTR SubcomponentId,
  760. UINT Function,
  761. UINT_PTR Param1,
  762. PVOID Param2)
  763. {
  764. DWORD_PTR rc = NO_ERROR;
  765. BOOL bCurrentState, bOriginalState;
  766. LOGMESSAGE1(_T("Entering %s"), _T("WebClient Setup"));
  767. switch(Function)
  768. {
  769. case OC_INIT_COMPONENT:
  770. return NO_ERROR;
  771. case OC_QUERY_STATE:
  772. return SubcompUseOcManagerDefault;
  773. break;
  774. case OC_SET_LANGUAGE:
  775. return FALSE;
  776. case OC_QUERY_IMAGE:
  777. rc = (DWORD_PTR)LoadImage(GetInstance(), MAKEINTRESOURCE(IDB_WEBCLIENT), IMAGE_BITMAP,
  778. 0, 0, LR_DEFAULTCOLOR);
  779. LOGMESSAGE1(_T("Bitmap is: %d"), rc);
  780. return rc;
  781. case OC_QUERY_CHANGE_SEL_STATE:
  782. {
  783. BOOL rc = TRUE;
  784. BOOL fDependentSelection = (BOOL)((INT_PTR)Param2 & OCQ_DEPENDENT_SELECTION);
  785. BOOL fProposedState = (BOOL)Param1;
  786. //
  787. // Don't allow an indirect selection (e.g. don't allow clicking on
  788. // the parent to enable the child)
  789. //
  790. if (fDependentSelection && fProposedState) {
  791. rc = FALSE;
  792. }
  793. return rc;
  794. }
  795. break;
  796. case OC_CALC_DISK_SPACE:
  797. //rc = OnCalcDiskSpace(SubcomponentId, (DWORD)Param1, Param2);
  798. //_tcscpy(section, SubcomponentId);
  799. if ((DWORD)Param1)
  800. {
  801. rc = SetupAddInstallSectionToDiskSpaceList((HDSKSPC)Param2, GetComponentInfHandle(), NULL,
  802. STRING_TS_WEBCLIENT_INSTALL, 0, 0);
  803. }
  804. else
  805. {
  806. rc = SetupRemoveInstallSectionFromDiskSpaceList((HDSKSPC)Param2, GetComponentInfHandle(), NULL,
  807. STRING_TS_WEBCLIENT_INSTALL, 0, 0);
  808. }
  809. LOGMESSAGE1(_T("Query Disk Space return: %d"), rc);
  810. if (!rc)
  811. rc = GetLastError();
  812. else
  813. rc = NO_ERROR;
  814. break;
  815. case OC_QUEUE_FILE_OPS:
  816. rc = NO_ERROR;
  817. bOriginalState = GetHelperRoutines().QuerySelectionState(GetHelperRoutines().OcManagerContext,
  818. STRING_TS_WEBCLIENT, OCSELSTATETYPE_ORIGINAL);
  819. bCurrentState = GetHelperRoutines().QuerySelectionState(GetHelperRoutines().OcManagerContext,
  820. STRING_TS_WEBCLIENT, OCSELSTATETYPE_CURRENT);
  821. LOGMESSAGE2(_T("Original=%d, Current=%d"), bOriginalState, bCurrentState);
  822. if(bCurrentState) {
  823. // Only copy files if it's machine upgrade or
  824. // the component is not previously installed
  825. if (!StateObject.IsStandAlone() || !bOriginalState) {
  826. if (!SetupInstallFilesFromInfSection(GetComponentInfHandle(), NULL, (HSPFILEQ)Param2,
  827. STRING_TS_WEBCLIENT_INSTALL, NULL, 0)) {
  828. rc = GetLastError();
  829. LOGMESSAGE2(_T("ERROR:OnQueueFileOps::SetupInstallFilesFromInfSection <%s> failed.GetLastError() = <%ul)"), SubcomponentId, rc);
  830. }
  831. }
  832. LOGMESSAGE1(_T("Copy files return: %d"), rc);
  833. break;
  834. }
  835. else {
  836. if (!bOriginalState) {
  837. // Not installed before, do nothing
  838. return NO_ERROR;
  839. }
  840. if (!SetupInstallFilesFromInfSection(GetComponentInfHandle(), NULL, (HSPFILEQ)Param2,
  841. STRING_TS_WEBCLIENT_UNINSTALL, NULL, 0))
  842. {
  843. rc = GetLastError();
  844. LOGMESSAGE2(_T("ERROR:OnQueueFileOps::SetupInstallFilesFromInfSection <%s> failed.GetLastError() = <%ul)"), SubcomponentId, rc);
  845. }
  846. LOGMESSAGE1(_T("Remove files return: %d"), rc);
  847. break;
  848. }
  849. case OC_COMPLETE_INSTALLATION:
  850. bOriginalState = GetHelperRoutines().QuerySelectionState(GetHelperRoutines().OcManagerContext, _T("TSWebClient"), OCSELSTATETYPE_ORIGINAL);
  851. bCurrentState = GetHelperRoutines().QuerySelectionState(GetHelperRoutines().OcManagerContext, _T("TSWebClient"), OCSELSTATETYPE_CURRENT);
  852. LOGMESSAGE2(_T("Orinal=%d, Current=%d"), bOriginalState, bCurrentState);
  853. if(bOriginalState==bCurrentState) //state does not change
  854. return NO_ERROR;
  855. int iTrans; //mark removing or adding tsweb dir
  856. int nLength;
  857. iTrans = 0;
  858. WCHAR wszVDirName[MAX_PATH];
  859. WCHAR wszDirPath[MAX_PATH];
  860. TCHAR szDirPath[MAX_PATH];
  861. TCHAR szVDirName[MAX_PATH];
  862. if (GetWindowsDirectory(szDirPath, MAX_PATH) == 0) {
  863. rc = GetLastError();
  864. return rc;
  865. }
  866. nLength = _tcsclen(szDirPath);
  867. if(_T('\\')==szDirPath[nLength-1])
  868. szDirPath[nLength-1]=_T('\0');
  869. _tcscat(szDirPath, STRING_TS_WEBCLIENT_DIR);
  870. if (LoadString(GetInstance(), IDS_STRING_TSWEBCLIENT_VIRTUALPATH, szVDirName, MAX_PATH) == 0) {
  871. LOGMESSAGE0(_T("Can't load string IDS_STRING_TSWEBCLIENT_VIRTUALPATH"));
  872. rc = GetLastError();;
  873. }
  874. LOGMESSAGE2(_T("Dir Path is: %s, Virtual Name is: %s"), szDirPath, szVDirName);
  875. if(bCurrentState) //enable IIS directory
  876. iTrans = TRANS_ADD;
  877. else
  878. iTrans = TRANS_DEL;
  879. #ifndef _UNICODE
  880. MultiByteToWideChar(CP_ACP, 0, szDirPath, -1, (LPWSTR) wszDirPath, MAX_PATH);
  881. MultiByteToWideChar(CP_ACP, 0, szVDirName, -1, (LPWSTR) wszVDirName, MAX_PATH);
  882. #else
  883. _tcscpy(wszDirPath, szDirPath);
  884. _tcscpy(wszVDirName, szVDirName);
  885. #endif
  886. rc = OpenMetabaseAndDoStuff(wszVDirName, wszDirPath, iTrans)?0:1;
  887. LOGMESSAGE1(_T("Websetup complete, return is: %d"), rc);
  888. return rc;
  889. default:
  890. rc = NO_ERROR; // it means we do not recognize this command.
  891. break;
  892. }
  893. return rc;
  894. }
  895. BOOL
  896. OpenMetabaseAndDoStuff(
  897. WCHAR * wszVDir,
  898. WCHAR * wszDir,
  899. int iTrans)
  900. {
  901. BOOL fRet = FALSE;
  902. HRESULT hr;
  903. IMSAdminBase *pIMSAdminBase = NULL; // Metabase interface pointer
  904. WCHAR wszPrintString[MAX_PATH + MAX_PATH];
  905. // Make sure that IISADMIN service exists
  906. if (CheckifServiceExist(_T("IISADMIN")) != 0)
  907. {
  908. LOGMESSAGE0(_T("IISADMIN service does not exist"));
  909. // We have to return TRUE here if IIS service does not exist
  910. return TRUE;
  911. }
  912. if( FAILED (hr = CoInitializeEx( NULL, COINIT_MULTITHREADED )) ||
  913. FAILED (hr = ::CoCreateInstance(CLSID_MSAdminBase,
  914. NULL,
  915. CLSCTX_ALL,
  916. IID_IMSAdminBase,
  917. (void **)&pIMSAdminBase)))
  918. {
  919. LOGMESSAGE1(_T("CoCreateInstance failed with error code %u"), hr);
  920. return FALSE;
  921. }
  922. switch (iTrans) {
  923. case TRANS_DEL:
  924. if(RemoveVirtualDir( pIMSAdminBase, wszVDir)) {
  925. hr = pIMSAdminBase->SaveData();
  926. if( SUCCEEDED( hr )) {
  927. fRet = TRUE;
  928. }
  929. }
  930. break;
  931. case TRANS_ADD:
  932. if(AddVirtualDir( pIMSAdminBase, wszVDir, wszDir)) {
  933. hr = pIMSAdminBase->SaveData();
  934. if( SUCCEEDED( hr )) {
  935. fRet = TRUE;
  936. }
  937. }
  938. break;
  939. default:
  940. break;
  941. }
  942. if (pIMSAdminBase) {
  943. pIMSAdminBase->Release();
  944. pIMSAdminBase = NULL;
  945. }
  946. CoUninitialize();
  947. return fRet;
  948. }
  949. BOOL
  950. GetVdirPhysicalPath(
  951. IMSAdminBase *pIMSAdminBase,
  952. WCHAR * wszVDir,
  953. WCHAR *wszStringPathToFill)
  954. {
  955. HRESULT hr;
  956. BOOL fRet = FALSE;
  957. METADATA_HANDLE hMetabase = NULL; // handle to metabase
  958. METADATA_RECORD mr;
  959. WCHAR szTmpData[MAX_PATH];
  960. DWORD dwMDRequiredDataLen;
  961. // open key to ROOT on website #1 (default)
  962. hr = pIMSAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  963. L"/LM/W3SVC/1",
  964. METADATA_PERMISSION_READ,
  965. REASONABLE_TIMEOUT,
  966. &hMetabase);
  967. if( FAILED( hr )) {
  968. return FALSE;
  969. }
  970. // Get the physical path for the WWWROOT
  971. mr.dwMDIdentifier = MD_VR_PATH;
  972. mr.dwMDAttributes = 0;
  973. mr.dwMDUserType = IIS_MD_UT_FILE;
  974. mr.dwMDDataType = STRING_METADATA;
  975. mr.dwMDDataLen = sizeof( szTmpData );
  976. mr.pbMDData = reinterpret_cast<unsigned char *>(szTmpData);
  977. //if nothing specified get the root.
  978. if (_wcsicmp(wszVDir, L"") == 0) {
  979. WCHAR wszTempDir[MAX_PATH];
  980. swprintf(wszTempDir,L"/ROOT/%s", wszVDir);
  981. hr = pIMSAdminBase->GetData( hMetabase, wszTempDir, &mr, &dwMDRequiredDataLen );
  982. } else {
  983. hr = pIMSAdminBase->GetData( hMetabase, L"/ROOT", &mr, &dwMDRequiredDataLen );
  984. }
  985. pIMSAdminBase->CloseKey( hMetabase );
  986. if( SUCCEEDED( hr )) {
  987. wcscpy(wszStringPathToFill,szTmpData);
  988. fRet = TRUE;
  989. }
  990. pIMSAdminBase->CloseKey( hMetabase );
  991. return fRet;
  992. }
  993. BOOL
  994. AddVirtualDir(
  995. IMSAdminBase *pIMSAdminBase,
  996. WCHAR * wszVDir,
  997. WCHAR * wszDir)
  998. {
  999. HRESULT hr;
  1000. BOOL fRet = FALSE;
  1001. METADATA_HANDLE hMetabase = NULL; // handle to metabase
  1002. WCHAR szTempPath[MAX_PATH];
  1003. DWORD dwMDRequiredDataLen = 0;
  1004. DWORD dwAccessPerm = 0;
  1005. METADATA_RECORD mr;
  1006. // Attempt to open the virtual dir set on Web server #1 (default server)
  1007. hr = pIMSAdminBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  1008. L"/LM/W3SVC/1/ROOT",
  1009. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  1010. REASONABLE_TIMEOUT,
  1011. &hMetabase );
  1012. // Create the key if it does not exist.
  1013. if( FAILED( hr )) {
  1014. return FALSE;
  1015. }
  1016. fRet = TRUE;
  1017. mr.dwMDIdentifier = MD_VR_PATH;
  1018. mr.dwMDAttributes = 0;
  1019. mr.dwMDUserType = IIS_MD_UT_FILE;
  1020. mr.dwMDDataType = STRING_METADATA;
  1021. mr.dwMDDataLen = sizeof( szTempPath );
  1022. mr.pbMDData = reinterpret_cast<unsigned char *>(szTempPath);
  1023. // see if MD_VR_PATH exists.
  1024. hr = pIMSAdminBase->GetData( hMetabase, wszVDir, &mr, &dwMDRequiredDataLen );
  1025. if( FAILED( hr )) {
  1026. fRet = FALSE;
  1027. if( hr == MD_ERROR_DATA_NOT_FOUND ||
  1028. HRESULT_CODE(hr) == ERROR_PATH_NOT_FOUND ) {
  1029. // Write both the key and the values if GetData() failed with any of the two errors.
  1030. pIMSAdminBase->AddKey( hMetabase, wszVDir );
  1031. mr.dwMDIdentifier = MD_VR_PATH;
  1032. mr.dwMDAttributes = METADATA_INHERIT;
  1033. mr.dwMDUserType = IIS_MD_UT_FILE;
  1034. mr.dwMDDataType = STRING_METADATA;
  1035. mr.dwMDDataLen = (wcslen(wszDir) + 1) * sizeof(WCHAR);
  1036. mr.pbMDData = reinterpret_cast<unsigned char *>(wszDir);
  1037. // Write MD_VR_PATH value
  1038. hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
  1039. fRet = SUCCEEDED( hr );
  1040. // Set the default authentication method
  1041. if( fRet ) {
  1042. DWORD dwAuthorization = MD_AUTH_ANONYMOUS; // NTLM only.
  1043. mr.dwMDIdentifier = MD_AUTHORIZATION;
  1044. mr.dwMDAttributes = METADATA_INHERIT; // need to inherit so that all subdirs are also protected.
  1045. mr.dwMDUserType = IIS_MD_UT_FILE;
  1046. mr.dwMDDataType = DWORD_METADATA;
  1047. mr.dwMDDataLen = sizeof(DWORD);
  1048. mr.pbMDData = reinterpret_cast<unsigned char *>(&dwAuthorization);
  1049. // Write MD_AUTHORIZATION value
  1050. hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
  1051. fRet = SUCCEEDED( hr );
  1052. }
  1053. }
  1054. }
  1055. // In the following, do the stuff that we always want to do to the virtual dir, regardless of Admin's setting.
  1056. if( fRet ) {
  1057. dwAccessPerm = MD_ACCESS_READ;
  1058. mr.dwMDIdentifier = MD_ACCESS_PERM;
  1059. mr.dwMDAttributes = METADATA_INHERIT; // Make it inheritable so all subdirectories will have the same rights.
  1060. mr.dwMDUserType = IIS_MD_UT_FILE;
  1061. mr.dwMDDataType = DWORD_METADATA;
  1062. mr.dwMDDataLen = sizeof(DWORD);
  1063. mr.pbMDData = reinterpret_cast<unsigned char *>(&dwAccessPerm);
  1064. // Write MD_ACCESS_PERM value
  1065. hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
  1066. fRet = SUCCEEDED( hr );
  1067. }
  1068. if( fRet ) {
  1069. PWCHAR szDefLoadFile = L"Default.htm,Default.asp";
  1070. mr.dwMDIdentifier = MD_DEFAULT_LOAD_FILE;
  1071. mr.dwMDAttributes = 0; // no need for inheritence
  1072. mr.dwMDUserType = IIS_MD_UT_FILE;
  1073. mr.dwMDDataType = STRING_METADATA;
  1074. mr.dwMDDataLen = (wcslen(szDefLoadFile) + 1) * sizeof(WCHAR);
  1075. mr.pbMDData = reinterpret_cast<unsigned char *>(szDefLoadFile);
  1076. // Write MD_DEFAULT_LOAD_FILE value
  1077. hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
  1078. fRet = SUCCEEDED( hr );
  1079. }
  1080. if( fRet ) {
  1081. PWCHAR szKeyType = IIS_CLASS_WEB_VDIR_W;
  1082. mr.dwMDIdentifier = MD_KEY_TYPE;
  1083. mr.dwMDAttributes = 0; // no need for inheritence
  1084. mr.dwMDUserType = IIS_MD_UT_SERVER;
  1085. mr.dwMDDataType = STRING_METADATA;
  1086. mr.dwMDDataLen = (wcslen(szKeyType) + 1) * sizeof(WCHAR);
  1087. mr.pbMDData = reinterpret_cast<unsigned char *>(szKeyType);
  1088. // Write MD_DEFAULT_LOAD_FILE value
  1089. hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
  1090. fRet = SUCCEEDED( hr );
  1091. }
  1092. pIMSAdminBase->CloseKey( hMetabase );
  1093. return fRet;
  1094. }
  1095. BOOL
  1096. RemoveVirtualDir(
  1097. IMSAdminBase *pIMSAdminBase,
  1098. WCHAR * wszVDir)
  1099. {
  1100. METADATA_HANDLE hMetabase = NULL; // handle to metabase
  1101. HRESULT hr;
  1102. // Attempt to open the virtual dir set on Web server #1 (default server)
  1103. hr = pIMSAdminBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  1104. L"/LM/W3SVC/1/ROOT",
  1105. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  1106. REASONABLE_TIMEOUT,
  1107. &hMetabase );
  1108. if( FAILED( hr )) {
  1109. return FALSE;
  1110. }
  1111. // We don't check the return value since the key may already
  1112. // not exist and we could get an error for that reason.
  1113. pIMSAdminBase->DeleteKey( hMetabase, wszVDir );
  1114. pIMSAdminBase->CloseKey( hMetabase );
  1115. return TRUE;
  1116. }
  1117. //Check if the service "lpServiceName" exist or not
  1118. // if exist, return 0
  1119. // if not, return error code
  1120. INT CheckifServiceExist(LPCTSTR lpServiceName)
  1121. {
  1122. INT err = 0;
  1123. SC_HANDLE hScManager = NULL;
  1124. SC_HANDLE hService = NULL;
  1125. if ((hScManager = OpenSCManager(NULL, NULL, GENERIC_ALL)) == NULL
  1126. || (hService = OpenService(hScManager, lpServiceName, GENERIC_ALL)) == NULL)
  1127. {
  1128. err = GetLastError();
  1129. }
  1130. if (hService)
  1131. CloseServiceHandle(hService);
  1132. if (hScManager)
  1133. CloseServiceHandle(hScManager);
  1134. return (err);
  1135. }
  1136. // EOF