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.

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