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.

1306 lines
33 KiB

  1. // Copyright (c) 2001 Microsoft Corporation
  2. //
  3. // File: FileInstallationUnit.cpp
  4. //
  5. // Synopsis: Defines a FileInstallationUnit
  6. // This object has the knowledge for installing the
  7. // quotas on disk usage and such
  8. //
  9. // History: 02/06/2001 JeffJon Created
  10. #include "pch.h"
  11. #include "resource.h"
  12. #include "FileInstallationUnit.h"
  13. #include "InstallationUnitProvider.h"
  14. #define INITGUIDS // This has to be present so the the GUIDs defined
  15. // in dskquota.h can be linked
  16. #include <dskquota.h>
  17. // Finish page help
  18. static PCWSTR CYS_FILE_FINISH_PAGE_HELP = L"cys.chm::/file_server_role.htm";
  19. static PCWSTR CYS_FILE_MILESTONE_HELP = L"cys.chm::/file_server_role.htm#filesrvsummary";
  20. static PCWSTR CYS_FILE_AFTER_FINISH_HELP = L"cys.chm::/file_server_role.htm#filesrvcompletion";
  21. FileInstallationUnit::FileInstallationUnit() :
  22. spaceQuotaValue(0),
  23. levelQuotaValue(0),
  24. setDefaultQuotas(false),
  25. denyUsersOverQuota(false),
  26. eventDiskSpaceLimit(false),
  27. eventWarningLevel(false),
  28. fileRoleResult(FILE_SUCCESS),
  29. InstallationUnit(
  30. IDS_FILE_SERVER_TYPE,
  31. IDS_FILE_SERVER_DESCRIPTION,
  32. IDS_FILE_FINISH_TITLE,
  33. IDS_FILE_FINISH_UNINSTALL_TITLE,
  34. IDS_FILE_FINISH_MESSAGE,
  35. IDS_FILE_INSTALL_FAILED,
  36. IDS_FILE_UNINSTALL_MESSAGE,
  37. IDS_FILE_UNINSTALL_FAILED,
  38. IDS_FILE_UNINSTALL_WARNING,
  39. IDS_FILE_UNINSTALL_CHECKBOX,
  40. CYS_FILE_FINISH_PAGE_HELP,
  41. CYS_FILE_MILESTONE_HELP,
  42. CYS_FILE_AFTER_FINISH_HELP,
  43. FILESERVER_SERVER)
  44. {
  45. LOG_CTOR(FileInstallationUnit);
  46. }
  47. FileInstallationUnit::~FileInstallationUnit()
  48. {
  49. LOG_DTOR(FileInstallationUnit);
  50. }
  51. HRESULT
  52. FileInstallationUnit::GetStartMenuShortcutPath(String& startMenuShortcutPath) const
  53. {
  54. LOG_FUNCTION(FileInstallationUnit::GetStartMenuShortcutPath);
  55. HRESULT hr = S_OK;
  56. String startMenuPath;
  57. hr = GetAllUsersStartMenu(startMenuPath);
  58. if (SUCCEEDED(hr))
  59. {
  60. startMenuShortcutPath =
  61. FS::AppendPath(
  62. startMenuPath,
  63. String::load(IDS_FILESERVER_ADMINTOOLS_LINK));
  64. LOG(String::format(
  65. L"Start Menu Link = %1",
  66. startMenuShortcutPath.c_str()));
  67. }
  68. LOG_HRESULT(hr);
  69. return hr;
  70. }
  71. bool
  72. FileInstallationUnit::AddFileServerConsoleToStartMenu(HANDLE logfileHandle)
  73. {
  74. LOG_FUNCTION(FileInstallationUnit::AddFileServerConsoleToStartMenu);
  75. bool result = false;
  76. // This actually adds the shortcut to both the start menu and
  77. // the Administrative Tools menu
  78. String target =
  79. Win::GetSystemDirectory() + L"\\filesvr.msc";
  80. HRESULT hr =
  81. AddShortcutToAdminTools(
  82. target,
  83. IDS_FILE_CONSOLE_SHORTCUT_DESCRIPTION,
  84. IDS_FILESERVER_ADMINTOOLS_LINK);
  85. if (SUCCEEDED(hr))
  86. {
  87. result = true;
  88. CYS_APPEND_LOG(String::load(IDS_FILE_LOG_ADMIN_TOOLS));
  89. }
  90. LOG_BOOL(result);
  91. return result;
  92. }
  93. InstallationReturnType
  94. FileInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
  95. {
  96. LOG_FUNCTION(FileInstallationUnit::InstallService);
  97. CYS_APPEND_LOG(String::load(IDS_LOG_FILE_SERVER));
  98. InstallationReturnType result = INSTALL_SUCCESS;
  99. // Set the default disk quotas if chosen by the user
  100. if (setDefaultQuotas)
  101. {
  102. LOG(L"Setting default disk quotas");
  103. CYS_APPEND_LOG(String::load(IDS_LOG_FILE_SERVER_SET_QUOTAS));
  104. // Update the status text on the progress page
  105. UpdateInstallationProgressText(hwnd, IDS_FILE_MILESTONE_QUOTAS);
  106. // Now check to be sure the warning level is less than the
  107. // quota level. If its not, then log a warning
  108. LONGLONG quotaValue = GetSpaceQuotaValue();
  109. LONGLONG warningValue = GetLevelQuotaValue();
  110. if (warningValue > quotaValue)
  111. {
  112. CYS_APPEND_LOG(String::load(IDS_FILE_WARNING_LARGER_THAN_QUOTA));
  113. }
  114. HRESULT quotasResult = WriteDiskQuotas(logfileHandle);
  115. if (FAILED(quotasResult))
  116. {
  117. result = INSTALL_FAILURE;
  118. }
  119. }
  120. IndexingInstallationUnit& indexingInstallationUnit =
  121. InstallationUnitProvider::GetInstance().GetIndexingInstallationUnit();
  122. HRESULT indexingResult = S_OK;
  123. if (indexingInstallationUnit.IsServiceOn() &&
  124. !GetInstallIndexingService())
  125. {
  126. UpdateInstallationProgressText(hwnd, IDS_FILE_MILESTONE_INDEX_OFF);
  127. indexingResult = indexingInstallationUnit.StopService();
  128. if (SUCCEEDED(indexingResult))
  129. {
  130. LOG(L"Stop indexing service succeeded");
  131. CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_STOP_SUCCEEDED));
  132. }
  133. else
  134. {
  135. LOG(L"Stop indexing server failed");
  136. CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_STOP_FAILED));
  137. fileRoleResult |= FILE_INDEXING_STOP_FAILURE;
  138. result = INSTALL_FAILURE;
  139. }
  140. }
  141. else if (!indexingInstallationUnit.IsServiceOn() &&
  142. GetInstallIndexingService())
  143. {
  144. UpdateInstallationProgressText(hwnd, IDS_FILE_MILESTONE_INDEX_ON);
  145. indexingResult = indexingInstallationUnit.StartService(logfileHandle);
  146. if (SUCCEEDED(indexingResult))
  147. {
  148. LOG(L"Start indexing service succeeded");
  149. CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_START_SUCCEEDED));
  150. }
  151. else
  152. {
  153. LOG(L"Start indexing server failed");
  154. CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_START_FAILED));
  155. fileRoleResult |= FILE_INDEXING_START_FAILURE;
  156. result = INSTALL_FAILURE;
  157. }
  158. }
  159. // If not already present, add the filesvr.msc shortcut to
  160. // the start menu
  161. if (!IsFileServerConsolePresent())
  162. {
  163. UpdateInstallationProgressText(hwnd, IDS_FILE_MILESTONE_INSTALL_FILE_CONSOLE);
  164. AddFileServerConsoleToStartMenu(logfileHandle);
  165. }
  166. // Run the shared folders wizard
  167. UpdateInstallationProgressText(hwnd, IDS_FILE_MILESTONE_RUN_SHARE_WIZARD);
  168. RunSharedFoldersWizard(true);
  169. // This checks to see if there was actually folder shared
  170. if (!IsServiceInstalled())
  171. {
  172. fileRoleResult |= FILE_NO_SHARES_FAILURE;
  173. result = INSTALL_FAILURE;
  174. CYS_APPEND_LOG(String::load(IDS_FILE_LOG_INSTALL_FAILURE));
  175. }
  176. else
  177. {
  178. // This overwrites the other failures because we are
  179. // a file server if there is a share
  180. result = INSTALL_SUCCESS;
  181. CYS_APPEND_LOG(String::load(IDS_FILE_LOG_INSTALL_SUCCESS));
  182. }
  183. LOG_INSTALL_RETURN(result);
  184. return result;
  185. }
  186. UnInstallReturnType
  187. FileInstallationUnit::UnInstallService(HANDLE logfileHandle, HWND hwnd)
  188. {
  189. LOG_FUNCTION(FileInstallationUnit::UnInstallService);
  190. UnInstallReturnType result = UNINSTALL_SUCCESS;
  191. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_FILE_HEADER));
  192. do
  193. {
  194. UpdateInstallationProgressText(hwnd, IDS_UNINSTALL_SHARED_FOLDERS);
  195. if (!RemoveSharedPublicFolders())
  196. {
  197. LOG(L"Failed to remove shared folders");
  198. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_FILE_SHARES_FAILURE));
  199. result = UNINSTALL_FAILURE;
  200. break;
  201. }
  202. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_FILE_SHARES));
  203. if (!RemoveFileManagementConsole())
  204. {
  205. // This should be a silent failure. Most likely the
  206. // shortcut wasn't there to remove
  207. LOG(L"Failed to remove file management console");
  208. }
  209. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_FILE_CONSOLE));
  210. } while (false);
  211. LOG_UNINSTALL_RETURN(result);
  212. return result;
  213. }
  214. bool
  215. FileInstallationUnit::RemoveFileManagementConsole()
  216. {
  217. LOG_FUNCTION(FileInstallationUnit::RemoveFileManagementConsole);
  218. bool result = true;
  219. do
  220. {
  221. String adminToolsLinkPath;
  222. HRESULT hr = GetAdminToolsShortcutPath(
  223. adminToolsLinkPath,
  224. String::load(IDS_FILESERVER_ADMINTOOLS_LINK));
  225. if (FAILED(hr))
  226. {
  227. LOG(String::format(
  228. L"Failed to get the shortcut path for the file management console: hr = 0x%1!x!",
  229. hr));
  230. result = false;
  231. break;
  232. }
  233. ASSERT(!adminToolsLinkPath.empty());
  234. hr = Win::DeleteFile(adminToolsLinkPath);
  235. if (FAILED(hr))
  236. {
  237. LOG(String::format(
  238. L"Failed to delete the link: hr = 0x%1!x!",
  239. hr));
  240. result = false;
  241. break;
  242. }
  243. } while (false);
  244. LOG_BOOL(result);
  245. return result;
  246. }
  247. bool
  248. FileInstallationUnit::RemoveSharedPublicFolders()
  249. {
  250. LOG_FUNCTION(FileInstallationUnit::RemoveSharedPublicFolders);
  251. bool result = true;
  252. SHARE_INFO_1* shareInfoArray = 0;
  253. NET_API_STATUS shareResult = 0;
  254. do
  255. {
  256. DWORD entriesRead = 0;
  257. DWORD totalEntries = 0;
  258. DWORD resumeHandle = 0;
  259. shareResult = NetShareEnum(
  260. 0,
  261. 1,
  262. reinterpret_cast<BYTE**>(&shareInfoArray),
  263. static_cast<DWORD>(-1),
  264. &entriesRead,
  265. &totalEntries,
  266. &resumeHandle);
  267. if ((shareResult == ERROR_SUCCESS ||
  268. shareResult == ERROR_MORE_DATA) &&
  269. shareInfoArray)
  270. {
  271. for (
  272. DWORD index = 0;
  273. index < entriesRead;
  274. ++index)
  275. {
  276. // Look for only normal shares and ignore special shares
  277. // like C$, ADMIN$, and IPC$
  278. if (!IsSpecialShare(shareInfoArray[index]))
  279. {
  280. LOG(String::format(
  281. L"Share found: %1",
  282. shareInfoArray[index].shi1_netname));
  283. // Remove the share
  284. NET_API_STATUS shareRemovalStatus =
  285. NetShareDel(
  286. 0,
  287. shareInfoArray[index].shi1_netname,
  288. 0);
  289. if (shareRemovalStatus != NERR_Success)
  290. {
  291. LOG(String::format(
  292. L"Failed to remove the share %1 because 0x%2!x!",
  293. shareInfoArray[index].shi1_netname,
  294. shareRemovalStatus));
  295. result = false;
  296. break;
  297. }
  298. }
  299. }
  300. }
  301. else
  302. {
  303. LOG(String::format(
  304. L"NetShareEnum failed: result = %1!x!",
  305. shareResult));
  306. result = false;
  307. }
  308. if (shareInfoArray)
  309. {
  310. NetApiBufferFree(shareInfoArray);
  311. shareInfoArray = 0;
  312. }
  313. if (!result)
  314. {
  315. break;
  316. }
  317. } while(shareResult == ERROR_MORE_DATA);
  318. LOG_BOOL(result);
  319. return result;
  320. }
  321. InstallationReturnType
  322. FileInstallationUnit::CompletePath(
  323. HANDLE logfileHandle,
  324. HWND hwnd)
  325. {
  326. LOG_FUNCTION(FileInstallationUnit::CompletePath);
  327. InstallationReturnType result = InstallService(logfileHandle, hwnd);
  328. LOG_INSTALL_RETURN(result);
  329. return result;
  330. }
  331. bool
  332. FileInstallationUnit::AreQuotasSet() const
  333. {
  334. LOG_FUNCTION(FileInstallationUnit::AreQuotasSet);
  335. bool result = false;
  336. // Check all NTFS partitions to see if quotas have been
  337. // turned on
  338. do
  339. {
  340. StringVector dl;
  341. HRESULT hr = FS::GetValidDrives(std::back_inserter(dl));
  342. if (FAILED(hr))
  343. {
  344. LOG(String::format(L"Failed to GetValidDrives: hr = %1!x!", hr));
  345. break;
  346. }
  347. // Loop through the list
  348. ASSERT(dl.size());
  349. for (
  350. StringVector::iterator i = dl.begin();
  351. i != dl.end();
  352. ++i)
  353. {
  354. // For each fixed drive that supports disk quotas read the state
  355. // and quota settings
  356. if (FS::GetFileSystemType(*i) == FS::NTFS5 &&
  357. Win::GetDriveType(*i) == DRIVE_FIXED )
  358. {
  359. // Create a Disk Quota Control
  360. // Multiple initializations of this object are not allowed so
  361. // I have to create a new instance each time through the loop
  362. SmartInterface<IDiskQuotaControl> diskQuotaControl;
  363. hr = diskQuotaControl.AcquireViaCreateInstance(
  364. CLSID_DiskQuotaControl,
  365. 0,
  366. CLSCTX_INPROC_SERVER,
  367. IID_IDiskQuotaControl);
  368. if (FAILED(hr))
  369. {
  370. LOG(String::format(
  371. L"Failed to create a disk quota control: hr = %1!x!",
  372. hr));
  373. break;
  374. }
  375. hr = diskQuotaControl->Initialize(
  376. i->c_str(),
  377. TRUE);
  378. if (FAILED(hr))
  379. {
  380. LOG(String::format(
  381. L"Failed to initialize disk quota COM object: hr = %1!x!",
  382. hr));
  383. continue;
  384. }
  385. LOG(String::format(
  386. L"Getting quota state on drive %1",
  387. i->c_str()));
  388. // Check the quota state
  389. DWORD quotaState = 0;
  390. hr = diskQuotaControl->GetQuotaState(&quotaState);
  391. if (FAILED(hr))
  392. {
  393. LOG(String::format(
  394. L"Failed to get quota state: hr = %1!x!",
  395. hr));
  396. continue;
  397. }
  398. LOG(String::format(
  399. L"Quota state = %1!x!",
  400. quotaState));
  401. if (quotaState & DISKQUOTA_STATE_MASK)
  402. {
  403. // One of the state bits have been set which
  404. // means that it has been configured
  405. // Check to see if there is a value for the limit
  406. LONGLONG diskQuotaLimit;
  407. ZeroMemory(&diskQuotaLimit, sizeof(LONGLONG));
  408. hr = diskQuotaControl->GetDefaultQuotaLimit(&diskQuotaLimit);
  409. if (FAILED(hr))
  410. {
  411. LOG(String::format(
  412. L"Failed to get default quota limit: hr = %1!x!",
  413. hr));
  414. continue;
  415. }
  416. if (diskQuotaLimit > 0)
  417. {
  418. LOG(L"Disk quota limit is greater than 0");
  419. result = true;
  420. break;
  421. }
  422. }
  423. }
  424. }
  425. } while (false);
  426. LOG_BOOL(result);
  427. return result;
  428. }
  429. bool
  430. FileInstallationUnit::AppendDiskQuotaText(String& message)
  431. {
  432. LOG_FUNCTION(FileInstallationUnit::AppendDiskQuotaText);
  433. bool result = false;
  434. if (GetDefaultQuotas())
  435. {
  436. message += String::load(IDS_FILE_FINISH_DISK_QUOTAS);
  437. result = true;
  438. }
  439. LOG_BOOL(result);
  440. return result;
  441. }
  442. bool
  443. FileInstallationUnit::AppendIndexingText(String& message)
  444. {
  445. LOG_FUNCTION(FileInstallationUnit::AppendIndexingText);
  446. bool result = false;
  447. IndexingInstallationUnit& indexingInstallationUnit =
  448. InstallationUnitProvider::GetInstance().GetIndexingInstallationUnit();
  449. if (indexingInstallationUnit.IsServiceOn() &&
  450. !GetInstallIndexingService())
  451. {
  452. message += String::load(IDS_FILE_FINISH_INDEXING_OFF);
  453. result = true;
  454. }
  455. else if (!indexingInstallationUnit.IsServiceOn() &&
  456. GetInstallIndexingService())
  457. {
  458. message += String::load(IDS_FILE_FINISH_INDEXING_ON);
  459. result = true;
  460. }
  461. else
  462. {
  463. // nothing needs to be done since they are leaving it in the same state
  464. result = false;
  465. }
  466. LOG_BOOL(result);
  467. return result;
  468. }
  469. bool
  470. FileInstallationUnit::AppendAdminText(String& message)
  471. {
  472. LOG_FUNCTION(FileInstallationUnit::AppendAdminText);
  473. bool result = false;
  474. if (!IsServerManagementConsolePresent() &&
  475. !IsFileServerConsolePresent())
  476. {
  477. message += String::load(IDS_FILE_FINISH_SERVER_FSC);
  478. result = true;
  479. }
  480. LOG(message);
  481. LOG_BOOL(result);
  482. return result;
  483. }
  484. bool
  485. FileInstallationUnit::GetMilestoneText(String& message)
  486. {
  487. LOG_FUNCTION(FileInstallationUnit::GetMilestoneText);
  488. bool result = true;
  489. AppendDiskQuotaText(message);
  490. AppendIndexingText(message);
  491. AppendAdminText(message);
  492. message += String::load(IDS_FILE_SERVER_RUN_SHARE_WIZARD);
  493. LOG_BOOL(result);
  494. return result;
  495. }
  496. bool
  497. FileInstallationUnit::GetUninstallMilestoneText(String& message)
  498. {
  499. LOG_FUNCTION(FileInstallationUnit::GetUninstallMilestoneText);
  500. message = String::load(IDS_FILE_UNINSTALL_TEXT);
  501. LOG_BOOL(true);
  502. return true;
  503. }
  504. String
  505. FileInstallationUnit::GetServiceDescription()
  506. {
  507. LOG_FUNCTION(FileInstallationUnit::GetServiceDescription);
  508. // Dynamically determine the string based on the availability
  509. // of services
  510. unsigned int resourceID = descriptionID;
  511. if (GetStatus() == STATUS_CONFIGURED)
  512. {
  513. resourceID = IDS_FILE_SERVER_DESCRIPTION_CONFIGURED;
  514. }
  515. description = String::load(resourceID);
  516. return description;
  517. }
  518. bool
  519. FileInstallationUnit::IsFileServerConsolePresent() const
  520. {
  521. LOG_FUNCTION(FileInstallationUnit::IsFileServerConsolePresent);
  522. bool result = false;
  523. String shortcutPath;
  524. HRESULT hr = GetAdminToolsShortcutPath(
  525. shortcutPath,
  526. String::load(IDS_FILESERVER_ADMINTOOLS_LINK));
  527. if (SUCCEEDED(hr))
  528. {
  529. result = FS::FileExists(shortcutPath);
  530. }
  531. LOG_BOOL(result);
  532. return result;
  533. }
  534. bool
  535. FileInstallationUnit::IsServerManagementConsolePresent() const
  536. {
  537. LOG_FUNCTION(FileInstallationUnit::IsServerManagementConsolePresent);
  538. bool result = false;
  539. String serverManagementConsole =
  540. Win::GetSystemDirectory() + L"\\administration\\servmgmt.msc";
  541. LOG(String::format(
  542. L"Server Management Console = %1",
  543. serverManagementConsole.c_str()));
  544. result = FS::FileExists(serverManagementConsole);
  545. LOG_BOOL(result);
  546. return result;
  547. }
  548. void
  549. FileInstallationUnit::SetSpaceQuotaValue(LONGLONG value)
  550. {
  551. LOG_FUNCTION2(
  552. FileInstallationUnit::SetSpaceQuotaValue,
  553. String::format(L"%1!I64d!", value));
  554. spaceQuotaValue = value;
  555. }
  556. void
  557. FileInstallationUnit::SetLevelQuotaValue(LONGLONG value)
  558. {
  559. LOG_FUNCTION2(
  560. FileInstallationUnit::SetLevelQuotaValue,
  561. String::format(L"%1!I64d!", value));
  562. levelQuotaValue = value;
  563. }
  564. void
  565. FileInstallationUnit::SetDefaultQuotas(bool value)
  566. {
  567. LOG_FUNCTION2(
  568. FileInstallationUnit::SetDefaultQuotas,
  569. value ? L"true" : L"false");
  570. setDefaultQuotas = value;
  571. }
  572. void
  573. FileInstallationUnit::SetDenyUsersOverQuota(bool value)
  574. {
  575. LOG_FUNCTION2(
  576. FileInstallationUnit::SetDenyUsersOverQuota,
  577. value ? L"true" : L"false");
  578. denyUsersOverQuota = value;
  579. }
  580. void
  581. FileInstallationUnit::SetEventDiskSpaceLimit(bool value)
  582. {
  583. LOG_FUNCTION2(
  584. FileInstallationUnit::SetEventDiskSpaceLimit,
  585. value ? L"true" : L"false");
  586. eventDiskSpaceLimit = value;
  587. }
  588. void
  589. FileInstallationUnit::SetEventWarningLevel(bool value)
  590. {
  591. LOG_FUNCTION2(
  592. FileInstallationUnit::SetEventWarningLevel,
  593. value ? L"true" : L"false");
  594. eventWarningLevel = value;
  595. }
  596. void
  597. FileInstallationUnit::SetInstallIndexingService(bool value)
  598. {
  599. LOG_FUNCTION2(
  600. FileInstallationUnit::SetInstallIndexingService,
  601. value ? L"true" : L"false");
  602. installIndexingService = value;
  603. }
  604. HRESULT
  605. FileInstallationUnit::WriteDiskQuotas(HANDLE logfileHandle)
  606. {
  607. LOG_FUNCTION(FileInstallationUnit::WriteDiskQuotas);
  608. HRESULT hr = S_OK;
  609. bool wasSomethingSet = false;
  610. do
  611. {
  612. DWORD logFlags = 0;
  613. logFlags |= eventDiskSpaceLimit ? DISKQUOTA_LOGFLAG_USER_LIMIT : 0;
  614. logFlags |= eventWarningLevel ? DISKQUOTA_LOGFLAG_USER_THRESHOLD : 0;
  615. DWORD quotaState = denyUsersOverQuota ? DISKQUOTA_STATE_ENFORCE : DISKQUOTA_STATE_TRACK;
  616. // Get a list of the valid drives
  617. StringVector dl;
  618. hr = FS::GetValidDrives(std::back_inserter(dl));
  619. if (FAILED(hr))
  620. {
  621. LOG(String::format(L"Failed to GetValidDrives: hr = %1!x!", hr));
  622. break;
  623. }
  624. // Loop through the list
  625. ASSERT(dl.size());
  626. for (
  627. StringVector::iterator i = dl.begin();
  628. i != dl.end();
  629. ++i)
  630. {
  631. // For each fixed drive that supports disk quotas set the new values
  632. if (FS::GetFileSystemType(*i) == FS::NTFS5 &&
  633. Win::GetDriveType(*i) == DRIVE_FIXED )
  634. {
  635. // Create a Disk Quota Control
  636. // Multiple initializations of this object are not allowed so
  637. // I have to create a new instance each time through the loop
  638. SmartInterface<IDiskQuotaControl> diskQuotaControl;
  639. hr = diskQuotaControl.AcquireViaCreateInstance(
  640. CLSID_DiskQuotaControl,
  641. 0,
  642. CLSCTX_INPROC_SERVER,
  643. IID_IDiskQuotaControl);
  644. if (FAILED(hr))
  645. {
  646. LOG(String::format(
  647. L"Failed to create a disk quota control: hr = %1!x!",
  648. hr));
  649. break;
  650. }
  651. hr = diskQuotaControl->Initialize(
  652. i->c_str(),
  653. TRUE);
  654. if (FAILED(hr))
  655. {
  656. continue;
  657. }
  658. LOG(String::format(
  659. L"Setting quotas on drive %1",
  660. i->c_str()));
  661. // Turn on the disk quotas
  662. hr = diskQuotaControl->SetQuotaState(quotaState);
  663. if (SUCCEEDED(hr))
  664. {
  665. LOG(String::format(
  666. L"Disk quota set on drive %1",
  667. i->c_str()));
  668. CYS_APPEND_LOG(
  669. String::format(
  670. String::load(IDS_LOG_DISK_QUOTA_DRIVE_FORMAT),
  671. i->c_str()));
  672. if(denyUsersOverQuota)
  673. {
  674. LOG(L"Disk space denied to users exceeding limit");
  675. CYS_APPEND_LOG(
  676. String::format(
  677. String::load(IDS_LOG_DISK_QUOTA_DENY_FORMAT),
  678. spaceQuotaValue));
  679. }
  680. else
  681. {
  682. LOG(L"Disk space is not denied to users exceeding limit");
  683. CYS_APPEND_LOG(
  684. String::format(
  685. String::load(IDS_LOG_DISK_QUOTA_NOT_DENY_FORMAT),
  686. spaceQuotaValue));
  687. }
  688. wasSomethingSet = true;
  689. }
  690. // Set the default quota limit
  691. hr = diskQuotaControl->SetDefaultQuotaLimit(spaceQuotaValue);
  692. if (SUCCEEDED(hr))
  693. {
  694. LOG(String::format(
  695. L"Disk space limited to %1!I64d!",
  696. spaceQuotaValue));
  697. CYS_APPEND_LOG(
  698. String::format(
  699. String::load(IDS_LOG_DISK_QUOTA_LIMIT_FORMAT),
  700. spaceQuotaValue));
  701. wasSomethingSet = true;
  702. }
  703. // Set the warning level threshold
  704. hr = diskQuotaControl->SetDefaultQuotaThreshold(levelQuotaValue);
  705. if (SUCCEEDED(hr))
  706. {
  707. LOG(String::format(
  708. L"Disk threshold set to %1!I64d!",
  709. levelQuotaValue));
  710. CYS_APPEND_LOG(
  711. String::format(
  712. String::load(IDS_LOG_DISK_QUOTA_THRESHOLD_FORMAT),
  713. levelQuotaValue));
  714. wasSomethingSet = true;
  715. }
  716. // Set the event flags
  717. hr = diskQuotaControl->SetQuotaLogFlags(logFlags);
  718. if (SUCCEEDED(hr))
  719. {
  720. if (eventDiskSpaceLimit)
  721. {
  722. LOG(L"An event is logged when a user exceeds disk space limit");
  723. CYS_APPEND_LOG(
  724. String::load(IDS_LOG_DISK_QUOTA_LOG_LIMIT));
  725. }
  726. if (eventWarningLevel)
  727. {
  728. LOG(L"An event is logged when a user exceeds the warning limit");
  729. CYS_APPEND_LOG(
  730. String::load(IDS_LOG_DISK_QUOTA_LOG_WARNING));
  731. }
  732. wasSomethingSet = true;
  733. }
  734. }
  735. }
  736. } while (false);
  737. if (FAILED(hr) && !wasSomethingSet)
  738. {
  739. CYS_APPEND_LOG(
  740. String::format(
  741. String::load(IDS_LOG_DISK_QUOTA_FAILED),
  742. hr));
  743. fileRoleResult |= FILE_QUOTA_FAILURE;
  744. }
  745. LOG(String::format(
  746. L"hr = %1!x!",
  747. hr));
  748. return hr;
  749. }
  750. int
  751. FileInstallationUnit::GetWizardStart()
  752. {
  753. LOG_FUNCTION(FileInstallationUnit::GetWizardStart);
  754. int nextPage = -1;
  755. bool installingRole = true;
  756. if (IsServiceInstalled())
  757. {
  758. nextPage = IDD_UNINSTALL_MILESTONE_PAGE;
  759. installingRole = false;
  760. }
  761. else
  762. {
  763. if (State::GetInstance().HasNTFSDrive() &&
  764. !AreQuotasSet())
  765. {
  766. nextPage = IDD_FILE_SERVER_PAGE;
  767. }
  768. else
  769. {
  770. nextPage = IDD_INDEXING_PAGE;
  771. }
  772. }
  773. SetInstalling(installingRole);
  774. LOG(String::format(
  775. L"nextPage = %1!d!",
  776. nextPage));
  777. return nextPage;
  778. }
  779. void
  780. FileInstallationUnit::ServerRoleLinkSelected(int linkIndex, HWND /*hwnd*/)
  781. {
  782. LOG_FUNCTION2(
  783. FileInstallationUnit::ServerRoleLinkSelected,
  784. String::format(
  785. L"linkIndex = %1!d!",
  786. linkIndex));
  787. if (IsServiceInstalled())
  788. {
  789. ASSERT(linkIndex == 0);
  790. LaunchMYS();
  791. }
  792. else
  793. {
  794. ASSERT(linkIndex == 0);
  795. LOG(L"Showing configuration help");
  796. ShowHelp(CYS_FILE_FINISH_PAGE_HELP);
  797. }
  798. }
  799. void
  800. FileInstallationUnit::FinishLinkSelected(int linkIndex, HWND /*hwnd*/)
  801. {
  802. LOG_FUNCTION2(
  803. FileInstallationUnit::FinishLinkSelected,
  804. String::format(
  805. L"linkIndex = %1!d!",
  806. linkIndex));
  807. if (installing)
  808. {
  809. if (fileRoleResult & FILE_NO_SHARES_FAILURE)
  810. {
  811. if (fileRoleResult & FILE_QUOTA_FAILURE)
  812. {
  813. if (fileRoleResult & FILE_INDEXING_STOP_FAILURE ||
  814. fileRoleResult & FILE_INDEXING_START_FAILURE)
  815. {
  816. switch (linkIndex)
  817. {
  818. case 0:
  819. RunSharedFoldersWizard();
  820. break;
  821. case 1:
  822. LOG(L"Launch the file server management console");
  823. LaunchMMCConsole(L"filesvr.msc");
  824. break;
  825. case 2:
  826. LOG(L"Launch services snapin");
  827. LaunchMMCConsole(L"services.msc");
  828. break;
  829. default:
  830. ASSERT(false);
  831. break;
  832. }
  833. }
  834. else
  835. {
  836. switch (linkIndex)
  837. {
  838. case 0:
  839. RunSharedFoldersWizard();
  840. break;
  841. case 1:
  842. LOG(L"Launch the file server management console");
  843. LaunchMMCConsole(L"filesvr.msc");
  844. break;
  845. default:
  846. ASSERT(false);
  847. break;
  848. }
  849. }
  850. }
  851. else
  852. {
  853. if (fileRoleResult & FILE_INDEXING_STOP_FAILURE ||
  854. fileRoleResult & FILE_INDEXING_START_FAILURE)
  855. {
  856. switch (linkIndex)
  857. {
  858. case 0:
  859. RunSharedFoldersWizard();
  860. break;
  861. case 1:
  862. LOG(L"Launch services snapin");
  863. LaunchMMCConsole(L"services.msc");
  864. break;
  865. default:
  866. ASSERT(false);
  867. break;
  868. }
  869. }
  870. else
  871. {
  872. ASSERT(linkIndex == 0);
  873. RunSharedFoldersWizard();
  874. }
  875. }
  876. }
  877. else
  878. {
  879. if (fileRoleResult & FILE_QUOTA_FAILURE)
  880. {
  881. if (fileRoleResult & FILE_INDEXING_STOP_FAILURE ||
  882. fileRoleResult & FILE_INDEXING_START_FAILURE)
  883. {
  884. switch (linkIndex)
  885. {
  886. case 0:
  887. LOG(L"Launch the file server management console");
  888. LaunchMMCConsole(L"filesvr.msc");
  889. break;
  890. case 1:
  891. LOG(L"Launch services snapin");
  892. LaunchMMCConsole(L"services.msc");
  893. break;
  894. default:
  895. ASSERT(false);
  896. break;
  897. }
  898. }
  899. else
  900. {
  901. ASSERT(linkIndex == 0);
  902. LaunchMMCConsole(L"filesvr.msc");
  903. }
  904. }
  905. else
  906. {
  907. if (fileRoleResult & FILE_INDEXING_STOP_FAILURE ||
  908. fileRoleResult & FILE_INDEXING_START_FAILURE)
  909. {
  910. ASSERT(linkIndex == 0);
  911. LaunchMMCConsole(L"services.msc");
  912. }
  913. else
  914. {
  915. ASSERT(linkIndex == 0);
  916. LOG(L"Showing configuration help");
  917. ShowHelp(CYS_FILE_AFTER_FINISH_HELP);
  918. }
  919. }
  920. }
  921. }
  922. else
  923. {
  924. ASSERT(linkIndex == 0);
  925. LaunchMMCConsole(L"compmgmt.msc");
  926. }
  927. }
  928. String
  929. FileInstallationUnit::GetFinishText()
  930. {
  931. LOG_FUNCTION(FileInstallationUnit::GetFinishText);
  932. unsigned int messageID = finishMessageID;
  933. if (installing)
  934. {
  935. InstallationReturnType result = GetInstallResult();
  936. if (result != INSTALL_SUCCESS &&
  937. result != INSTALL_SUCCESS_REBOOT &&
  938. result != INSTALL_SUCCESS_PROMPT_REBOOT)
  939. {
  940. if (fileRoleResult & FILE_NO_SHARES_FAILURE)
  941. {
  942. if (fileRoleResult & FILE_QUOTA_FAILURE)
  943. {
  944. if (fileRoleResult & FILE_INDEXING_STOP_FAILURE)
  945. {
  946. messageID = IDS_FILE_FINISH_NOSHARES_NOQUOTA_NOINDEXSTOP;
  947. }
  948. else if (fileRoleResult & FILE_INDEXING_START_FAILURE)
  949. {
  950. messageID = IDS_FILE_FINISH_NOSHARES_NOQUOTA_NOINDEXSTART;
  951. }
  952. else
  953. {
  954. messageID = IDS_FILE_FINISH_NOSHARES_NOQUOTA;
  955. }
  956. }
  957. else
  958. {
  959. if (fileRoleResult & FILE_INDEXING_STOP_FAILURE)
  960. {
  961. messageID = IDS_FILE_FINISH_NOSHARES_NOINDEXSTOP;
  962. }
  963. else if (fileRoleResult & FILE_INDEXING_START_FAILURE)
  964. {
  965. messageID = IDS_FILE_FINISH_NOSHARES_NOINDEXSTART;
  966. }
  967. else
  968. {
  969. messageID = IDS_FILE_FINISH_NOSHARES;
  970. }
  971. }
  972. }
  973. else
  974. {
  975. if (fileRoleResult & FILE_QUOTA_FAILURE)
  976. {
  977. if (fileRoleResult & FILE_INDEXING_STOP_FAILURE)
  978. {
  979. messageID = IDS_FILE_FINISH_NOQUOTA_NOINDEXSTOP;
  980. }
  981. else if (fileRoleResult & FILE_INDEXING_START_FAILURE)
  982. {
  983. messageID = IDS_FILE_FINISH_NOQUOTA_NOINDEXSTART;
  984. }
  985. else
  986. {
  987. messageID = IDS_FILE_FINISH_NOQUOTA;
  988. }
  989. }
  990. else
  991. {
  992. if (fileRoleResult & FILE_INDEXING_STOP_FAILURE)
  993. {
  994. messageID = IDS_FILE_FINISH_NOINDEXSTOP;
  995. }
  996. else if (fileRoleResult & FILE_INDEXING_START_FAILURE)
  997. {
  998. messageID = IDS_FILE_FINISH_NOINDEXSTART;
  999. }
  1000. else
  1001. {
  1002. messageID = IDS_FILE_INSTALL_FAILED;
  1003. }
  1004. }
  1005. }
  1006. }
  1007. }
  1008. else
  1009. {
  1010. messageID = finishUninstallMessageID;
  1011. UnInstallReturnType result = GetUnInstallResult();
  1012. if (result != UNINSTALL_SUCCESS &&
  1013. result != UNINSTALL_SUCCESS_REBOOT &&
  1014. result != UNINSTALL_SUCCESS_PROMPT_REBOOT)
  1015. {
  1016. messageID = finishUninstallFailedMessageID;
  1017. }
  1018. }
  1019. return String::load(messageID);
  1020. }
  1021. void
  1022. FileInstallationUnit::RunSharedFoldersWizard(bool wait) const
  1023. {
  1024. LOG_FUNCTION(FileInstallationUnit::RunSharedFoldersWizard);
  1025. String fullPath =
  1026. FS::AppendPath(
  1027. Win::GetSystemDirectory(),
  1028. L"shrpubw.exe");
  1029. if (wait)
  1030. {
  1031. DWORD exitCode = 0;
  1032. CreateAndWaitForProcess(
  1033. fullPath,
  1034. String(),
  1035. exitCode);
  1036. }
  1037. else
  1038. {
  1039. MyCreateProcess(
  1040. fullPath,
  1041. String());
  1042. }
  1043. }