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.

565 lines
13 KiB

  1. // Copyright (c) 1997-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 "state.h"
  14. #include "InstallationUnitProvider.h"
  15. #define INITGUIDS // This has to be present so the the GUIDs defined
  16. // in dskquota.h can be linked
  17. #include <dskquota.h>
  18. // REVIEW_JEFFJON : are there equivalents that could just be included???
  19. #define CYS_KB 1024
  20. #define CYS_MB 1048576
  21. #define CYS_GB 1073741824
  22. // Finish page help
  23. static PCWSTR CYS_FILE_FINISH_PAGE_HELP = L"cys.chm::/cys_configuring_file_server.htm";
  24. FileInstallationUnit::FileInstallationUnit() :
  25. spaceQuotaSize(QUOTA_SIZE_KB),
  26. levelQuotaSize(QUOTA_SIZE_KB),
  27. spaceQuotaValue(1),
  28. levelQuotaValue(1),
  29. setDefaultQuotas(false),
  30. denyUsersOverQuota(false),
  31. eventDiskSpaceLimit(false),
  32. eventWarningLevel(false),
  33. InstallationUnit(
  34. IDS_FILE_SERVER_TYPE,
  35. IDS_FILE_SERVER_DESCRIPTION,
  36. CYS_FILE_FINISH_PAGE_HELP,
  37. FILESERVER_INSTALL)
  38. {
  39. LOG_CTOR(FileInstallationUnit);
  40. }
  41. FileInstallationUnit::~FileInstallationUnit()
  42. {
  43. LOG_DTOR(FileInstallationUnit);
  44. }
  45. InstallationReturnType
  46. FileInstallationUnit::InstallService(HANDLE logfileHandle, HWND /*hwnd*/)
  47. {
  48. LOG_FUNCTION(FileInstallationUnit::InstallService);
  49. CYS_APPEND_LOG(String::load(IDS_LOG_FILE_SERVER));
  50. InstallationReturnType result = INSTALL_SUCCESS;
  51. bool bChangeMade = false;
  52. // Set the default disk quotas if chosen by the user
  53. if (setDefaultQuotas)
  54. {
  55. LOG(L"Setting default disk quotas");
  56. CYS_APPEND_LOG(String::load(IDS_LOG_FILE_SERVER_SET_QUOTAS));
  57. WriteDiskQuotas(logfileHandle);
  58. bChangeMade = true;
  59. }
  60. // Turn on or off the indexing service as chosen by the user
  61. HRESULT indexingResult = S_OK;
  62. if (IsIndexingServiceOn() &&
  63. !GetInstallIndexingService())
  64. {
  65. indexingResult = StopIndexingService();
  66. if (SUCCEEDED(indexingResult))
  67. {
  68. LOG(L"Stop indexing service succeeded");
  69. CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_STOP_SUCCEEDED));
  70. }
  71. else
  72. {
  73. LOG(L"Stop indexing server failed");
  74. CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_STOP_FAILED));
  75. // REVIEW_JEFFJON : need to log error values
  76. }
  77. bChangeMade = true;
  78. }
  79. else if (!IsIndexingServiceOn() &&
  80. GetInstallIndexingService())
  81. {
  82. indexingResult = StartIndexingService();
  83. if (SUCCEEDED(indexingResult))
  84. {
  85. LOG(L"Start indexing service succeeded");
  86. CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_START_SUCCEEDED));
  87. }
  88. else
  89. {
  90. LOG(L"Start indexing server failed");
  91. CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_START_FAILED));
  92. // REVIEW_JEFFJON : need to log error values
  93. }
  94. bChangeMade = true;
  95. }
  96. if (!bChangeMade)
  97. {
  98. result = INSTALL_NO_CHANGES;
  99. }
  100. else
  101. {
  102. if (FAILED(indexingResult))
  103. {
  104. result = INSTALL_FAILURE;
  105. }
  106. }
  107. LOG_INSTALL_RETURN(result);
  108. return result;
  109. }
  110. bool
  111. FileInstallationUnit::IsServiceInstalled()
  112. {
  113. LOG_FUNCTION(FileInstallationUnit::IsServiceInstalled);
  114. bool result = false;
  115. if (!State::GetInstance().HasNTFSDrive() &&
  116. InstallationUnitProvider::GetInstance().GetSharePointInstallationUnit().IsServiceInstalled())
  117. {
  118. // There are no NTFS partitions and SharePoint is installed
  119. // so we can't set disk quotas or turn off the indexing service
  120. result = true;
  121. }
  122. LOG_BOOL(result);
  123. return result;
  124. }
  125. bool
  126. FileInstallationUnit::GetFinishText(String& message)
  127. {
  128. LOG_FUNCTION(FileInstallationUnit::GetFinishText);
  129. bool result = true;
  130. bool quotasTextSet = false;
  131. if (GetDefaultQuotas())
  132. {
  133. message += String::load(IDS_FILE_FINISH_DISK_QUOTAS);
  134. quotasTextSet = true;
  135. }
  136. bool indexingTextSet = false;
  137. if (IsIndexingServiceOn() &&
  138. !GetInstallIndexingService())
  139. {
  140. message += String::load(IDS_FILE_FINISH_INDEXING_OFF);
  141. indexingTextSet = true;
  142. }
  143. else if (!IsIndexingServiceOn() &&
  144. GetInstallIndexingService())
  145. {
  146. message += String::load(IDS_FILE_FINISH_INDEXING_ON);
  147. indexingTextSet = true;
  148. }
  149. else
  150. {
  151. // nothing needs to be done since they are leaving it in the same state
  152. indexingTextSet = false;
  153. }
  154. if (!quotasTextSet &&
  155. !indexingTextSet)
  156. {
  157. message += String::load(IDS_FINISH_NO_CHANGES);
  158. result = false;
  159. }
  160. LOG_BOOL(result);
  161. return result;
  162. }
  163. String
  164. FileInstallationUnit::GetServiceDescription()
  165. {
  166. LOG_FUNCTION(FileInstallationUnit::GetServiceDescription);
  167. // Dynamically determine the string based on the availability
  168. // of services
  169. bool isSharePointInstalled =
  170. InstallationUnitProvider::GetInstance().GetSharePointInstallationUnit().IsServiceInstalled();
  171. unsigned int resourceID = static_cast<unsigned int>(-1);
  172. if (State::GetInstance().HasNTFSDrive())
  173. {
  174. if (isSharePointInstalled)
  175. {
  176. resourceID = IDS_FILESERVER_QUOTAS_SHAREPOINT;
  177. }
  178. else
  179. {
  180. resourceID = IDS_FILESERVER_QUOTAS_NO_SHAREPOINT;
  181. }
  182. }
  183. else
  184. {
  185. if (isSharePointInstalled)
  186. {
  187. resourceID = IDS_FILESERVER_NO_QUOTAS_SHAREPOINT;
  188. }
  189. else
  190. {
  191. resourceID = IDS_FILESERVER_NO_QUOTAS_NO_SHAREPOINT;
  192. }
  193. }
  194. ASSERT(resourceID != static_cast<unsigned int>(-1));
  195. description = String::load(resourceID);
  196. return description;
  197. }
  198. void
  199. FileInstallationUnit::SetSpaceQuotaSize(QuotaSizeType size)
  200. {
  201. LOG_FUNCTION2(
  202. FileInstallationUnit::SetSpaceQuotaSize,
  203. String::format(L"%1!d!", size));
  204. spaceQuotaSize = size;
  205. }
  206. void
  207. FileInstallationUnit::SetLevelQuotaSize(QuotaSizeType size)
  208. {
  209. LOG_FUNCTION2(
  210. FileInstallationUnit::SetLevelQuotaSize,
  211. String::format(L"%1!d!", size));
  212. levelQuotaSize = size;
  213. }
  214. void
  215. FileInstallationUnit::SetSpaceQuotaValue(LONGLONG value)
  216. {
  217. LOG_FUNCTION2(
  218. FileInstallationUnit::SetSpaceQuotaValue,
  219. String::format(L"%1!I64d!", value));
  220. spaceQuotaValue = value;
  221. }
  222. void
  223. FileInstallationUnit::SetLevelQuotaValue(LONGLONG value)
  224. {
  225. LOG_FUNCTION2(
  226. FileInstallationUnit::SetLevelQuotaValue,
  227. String::format(L"%1!I64d!", value));
  228. levelQuotaValue = value;
  229. }
  230. void
  231. FileInstallationUnit::SetDefaultQuotas(bool value)
  232. {
  233. LOG_FUNCTION2(
  234. FileInstallationUnit::SetDefaultQuotas,
  235. value ? L"true" : L"false");
  236. setDefaultQuotas = value;
  237. }
  238. void
  239. FileInstallationUnit::SetDenyUsersOverQuota(bool value)
  240. {
  241. LOG_FUNCTION2(
  242. FileInstallationUnit::SetDenyUsersOverQuota,
  243. value ? L"true" : L"false");
  244. denyUsersOverQuota = value;
  245. }
  246. void
  247. FileInstallationUnit::SetEventDiskSpaceLimit(bool value)
  248. {
  249. LOG_FUNCTION2(
  250. FileInstallationUnit::SetEventDiskSpaceLimit,
  251. value ? L"true" : L"false");
  252. eventDiskSpaceLimit = value;
  253. }
  254. void
  255. FileInstallationUnit::SetEventWarningLevel(bool value)
  256. {
  257. LOG_FUNCTION2(
  258. FileInstallationUnit::SetEventWarningLevel,
  259. value ? L"true" : L"false");
  260. eventWarningLevel = value;
  261. }
  262. void
  263. FileInstallationUnit::SetInstallIndexingService(bool value)
  264. {
  265. LOG_FUNCTION2(
  266. FileInstallationUnit::SetInstallIndexingService,
  267. value ? L"true" : L"false");
  268. installIndexingService = value;
  269. }
  270. void
  271. FileInstallationUnit::WriteDiskQuotas(HANDLE logfileHandle)
  272. {
  273. LOG_FUNCTION(FileInstallationUnit::WriteDiskQuotas);
  274. HRESULT hr = S_OK;
  275. bool wasSomethingSet = false;
  276. do
  277. {
  278. // Calculate the new values
  279. LONGLONG newSpaceQuota = 0;
  280. ConvertValueBySizeType(spaceQuotaValue, spaceQuotaSize, newSpaceQuota);
  281. LONGLONG newLevelQuota = 0;
  282. ConvertValueBySizeType(levelQuotaValue, levelQuotaSize, newLevelQuota);
  283. DWORD logFlags = 0;
  284. logFlags |= eventDiskSpaceLimit ? DISKQUOTA_LOGFLAG_USER_LIMIT : 0;
  285. logFlags |= eventWarningLevel ? DISKQUOTA_LOGFLAG_USER_THRESHOLD : 0;
  286. DWORD quotaState = denyUsersOverQuota ? DISKQUOTA_STATE_ENFORCE : DISKQUOTA_STATE_TRACK;
  287. // Get a list of the valid drives
  288. StringVector dl;
  289. hr = FS::GetValidDrives(std::back_inserter(dl));
  290. if (FAILED(hr))
  291. {
  292. LOG(String::format(L"Failed to GetValidDrives: hr = %1!x!", hr));
  293. break;
  294. }
  295. // Loop through the list
  296. ASSERT(dl.size());
  297. for (
  298. StringVector::iterator i = dl.begin();
  299. i != dl.end();
  300. ++i)
  301. {
  302. // For each drive that supports disk quotas set the new values
  303. // Create a Disk Quota Control
  304. // Multiple initializations of this object are not allowed so
  305. // I have to create a new instance each time through the loop
  306. SmartInterface<IDiskQuotaControl> diskQuotaControl;
  307. hr = diskQuotaControl.AcquireViaCreateInstance(
  308. CLSID_DiskQuotaControl,
  309. 0,
  310. CLSCTX_INPROC_SERVER,
  311. IID_IDiskQuotaControl);
  312. if (FAILED(hr))
  313. {
  314. LOG(String::format(
  315. L"Failed to create a disk quota control: hr = %1!x!",
  316. hr));
  317. break;
  318. }
  319. hr = diskQuotaControl->Initialize(
  320. i->c_str(),
  321. TRUE);
  322. if (FAILED(hr))
  323. {
  324. continue;
  325. }
  326. LOG(String::format(
  327. L"Setting quotas on drive %1",
  328. i->c_str()));
  329. // Turn on the disk quotas
  330. hr = diskQuotaControl->SetQuotaState(quotaState);
  331. if (SUCCEEDED(hr))
  332. {
  333. LOG(String::format(
  334. L"Disk quota set on drive %1",
  335. i->c_str()));
  336. CYS_APPEND_LOG(
  337. String::format(
  338. String::load(IDS_LOG_DISK_QUOTA_DRIVE_FORMAT),
  339. i->c_str()));
  340. if(denyUsersOverQuota)
  341. {
  342. LOG(L"Disk space denied to users exceeding limit");
  343. CYS_APPEND_LOG(
  344. String::format(
  345. String::load(IDS_LOG_DISK_QUOTA_DENY_FORMAT),
  346. newSpaceQuota));
  347. }
  348. else
  349. {
  350. LOG(L"Disk space is not denied to users exceeding limit");
  351. CYS_APPEND_LOG(
  352. String::format(
  353. String::load(IDS_LOG_DISK_QUOTA_NOT_DENY_FORMAT),
  354. newSpaceQuota));
  355. }
  356. wasSomethingSet = true;
  357. }
  358. // Set the default quota limit
  359. hr = diskQuotaControl->SetDefaultQuotaLimit(newSpaceQuota);
  360. if (SUCCEEDED(hr))
  361. {
  362. LOG(String::format(
  363. L"Disk space limited to %1!I64d!",
  364. newSpaceQuota));
  365. CYS_APPEND_LOG(
  366. String::format(
  367. String::load(IDS_LOG_DISK_QUOTA_LIMIT_FORMAT),
  368. newSpaceQuota));
  369. wasSomethingSet = true;
  370. }
  371. // Set the warning level threshold
  372. hr = diskQuotaControl->SetDefaultQuotaThreshold(newLevelQuota);
  373. if (SUCCEEDED(hr))
  374. {
  375. LOG(String::format(
  376. L"Disk threshold set to %1!I64d!",
  377. newLevelQuota));
  378. CYS_APPEND_LOG(
  379. String::format(
  380. String::load(IDS_LOG_DISK_QUOTA_THRESHOLD_FORMAT),
  381. newLevelQuota));
  382. wasSomethingSet = true;
  383. }
  384. // Set the event flags
  385. hr = diskQuotaControl->SetQuotaLogFlags(logFlags);
  386. if (SUCCEEDED(hr))
  387. {
  388. if (eventDiskSpaceLimit)
  389. {
  390. LOG(L"An event is logged when a user exceeds disk space limit");
  391. CYS_APPEND_LOG(
  392. String::load(IDS_LOG_DISK_QUOTA_LOG_LIMIT));
  393. }
  394. if (eventWarningLevel)
  395. {
  396. LOG(L"An event is logged when a user exceeds the warning limit");
  397. CYS_APPEND_LOG(
  398. String::load(IDS_LOG_DISK_QUOTA_LOG_WARNING));
  399. }
  400. wasSomethingSet = true;
  401. }
  402. }
  403. } while (false);
  404. if (FAILED(hr) && !wasSomethingSet)
  405. {
  406. CYS_APPEND_LOG(
  407. String::format(
  408. String::load(IDS_LOG_DISK_QUOTA_FAILED),
  409. hr));
  410. }
  411. LOG(String::format(
  412. L"hr = %1!x!",
  413. hr));
  414. }
  415. void
  416. FileInstallationUnit::ConvertValueBySizeType(
  417. LONGLONG value,
  418. QuotaSizeType sizeType,
  419. LONGLONG& newValue)
  420. {
  421. int multiplier = 0;
  422. switch (sizeType)
  423. {
  424. case QUOTA_SIZE_KB :
  425. multiplier = CYS_KB;
  426. break;
  427. case QUOTA_SIZE_MB :
  428. multiplier = CYS_MB;
  429. break;
  430. case QUOTA_SIZE_GB :
  431. multiplier = CYS_GB;
  432. break;
  433. default :
  434. ASSERT(false);
  435. break;
  436. }
  437. newValue = value * multiplier;
  438. }