windows-nt/Source/XPSP1/NT/admin/cys/win32/fileinstallationunit.cpp
2020-09-26 16:20:57 +08:00

566 lines
13 KiB
C++

// Copyright (c) 1997-2001 Microsoft Corporation
//
// File: FileInstallationUnit.cpp
//
// Synopsis: Defines a FileInstallationUnit
// This object has the knowledge for installing the
// quotas on disk usage and such
//
// History: 02/06/2001 JeffJon Created
#include "pch.h"
#include "resource.h"
#include "FileInstallationUnit.h"
#include "state.h"
#include "InstallationUnitProvider.h"
#define INITGUIDS // This has to be present so the the GUIDs defined
// in dskquota.h can be linked
#include <dskquota.h>
// REVIEW_JEFFJON : are there equivalents that could just be included???
#define CYS_KB 1024
#define CYS_MB 1048576
#define CYS_GB 1073741824
// Finish page help
static PCWSTR CYS_FILE_FINISH_PAGE_HELP = L"cys.chm::/cys_configuring_file_server.htm";
FileInstallationUnit::FileInstallationUnit() :
spaceQuotaSize(QUOTA_SIZE_KB),
levelQuotaSize(QUOTA_SIZE_KB),
spaceQuotaValue(1),
levelQuotaValue(1),
setDefaultQuotas(false),
denyUsersOverQuota(false),
eventDiskSpaceLimit(false),
eventWarningLevel(false),
InstallationUnit(
IDS_FILE_SERVER_TYPE,
IDS_FILE_SERVER_DESCRIPTION,
CYS_FILE_FINISH_PAGE_HELP,
FILESERVER_INSTALL)
{
LOG_CTOR(FileInstallationUnit);
}
FileInstallationUnit::~FileInstallationUnit()
{
LOG_DTOR(FileInstallationUnit);
}
InstallationReturnType
FileInstallationUnit::InstallService(HANDLE logfileHandle, HWND /*hwnd*/)
{
LOG_FUNCTION(FileInstallationUnit::InstallService);
CYS_APPEND_LOG(String::load(IDS_LOG_FILE_SERVER));
InstallationReturnType result = INSTALL_SUCCESS;
bool bChangeMade = false;
// Set the default disk quotas if chosen by the user
if (setDefaultQuotas)
{
LOG(L"Setting default disk quotas");
CYS_APPEND_LOG(String::load(IDS_LOG_FILE_SERVER_SET_QUOTAS));
WriteDiskQuotas(logfileHandle);
bChangeMade = true;
}
// Turn on or off the indexing service as chosen by the user
HRESULT indexingResult = S_OK;
if (IsIndexingServiceOn() &&
!GetInstallIndexingService())
{
indexingResult = StopIndexingService();
if (SUCCEEDED(indexingResult))
{
LOG(L"Stop indexing service succeeded");
CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_STOP_SUCCEEDED));
}
else
{
LOG(L"Stop indexing server failed");
CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_STOP_FAILED));
// REVIEW_JEFFJON : need to log error values
}
bChangeMade = true;
}
else if (!IsIndexingServiceOn() &&
GetInstallIndexingService())
{
indexingResult = StartIndexingService();
if (SUCCEEDED(indexingResult))
{
LOG(L"Start indexing service succeeded");
CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_START_SUCCEEDED));
}
else
{
LOG(L"Start indexing server failed");
CYS_APPEND_LOG(String::load(IDS_LOG_INDEXING_START_FAILED));
// REVIEW_JEFFJON : need to log error values
}
bChangeMade = true;
}
if (!bChangeMade)
{
result = INSTALL_NO_CHANGES;
}
else
{
if (FAILED(indexingResult))
{
result = INSTALL_FAILURE;
}
}
LOG_INSTALL_RETURN(result);
return result;
}
bool
FileInstallationUnit::IsServiceInstalled()
{
LOG_FUNCTION(FileInstallationUnit::IsServiceInstalled);
bool result = false;
if (!State::GetInstance().HasNTFSDrive() &&
InstallationUnitProvider::GetInstance().GetSharePointInstallationUnit().IsServiceInstalled())
{
// There are no NTFS partitions and SharePoint is installed
// so we can't set disk quotas or turn off the indexing service
result = true;
}
LOG_BOOL(result);
return result;
}
bool
FileInstallationUnit::GetFinishText(String& message)
{
LOG_FUNCTION(FileInstallationUnit::GetFinishText);
bool result = true;
bool quotasTextSet = false;
if (GetDefaultQuotas())
{
message += String::load(IDS_FILE_FINISH_DISK_QUOTAS);
quotasTextSet = true;
}
bool indexingTextSet = false;
if (IsIndexingServiceOn() &&
!GetInstallIndexingService())
{
message += String::load(IDS_FILE_FINISH_INDEXING_OFF);
indexingTextSet = true;
}
else if (!IsIndexingServiceOn() &&
GetInstallIndexingService())
{
message += String::load(IDS_FILE_FINISH_INDEXING_ON);
indexingTextSet = true;
}
else
{
// nothing needs to be done since they are leaving it in the same state
indexingTextSet = false;
}
if (!quotasTextSet &&
!indexingTextSet)
{
message += String::load(IDS_FINISH_NO_CHANGES);
result = false;
}
LOG_BOOL(result);
return result;
}
String
FileInstallationUnit::GetServiceDescription()
{
LOG_FUNCTION(FileInstallationUnit::GetServiceDescription);
// Dynamically determine the string based on the availability
// of services
bool isSharePointInstalled =
InstallationUnitProvider::GetInstance().GetSharePointInstallationUnit().IsServiceInstalled();
unsigned int resourceID = static_cast<unsigned int>(-1);
if (State::GetInstance().HasNTFSDrive())
{
if (isSharePointInstalled)
{
resourceID = IDS_FILESERVER_QUOTAS_SHAREPOINT;
}
else
{
resourceID = IDS_FILESERVER_QUOTAS_NO_SHAREPOINT;
}
}
else
{
if (isSharePointInstalled)
{
resourceID = IDS_FILESERVER_NO_QUOTAS_SHAREPOINT;
}
else
{
resourceID = IDS_FILESERVER_NO_QUOTAS_NO_SHAREPOINT;
}
}
ASSERT(resourceID != static_cast<unsigned int>(-1));
description = String::load(resourceID);
return description;
}
void
FileInstallationUnit::SetSpaceQuotaSize(QuotaSizeType size)
{
LOG_FUNCTION2(
FileInstallationUnit::SetSpaceQuotaSize,
String::format(L"%1!d!", size));
spaceQuotaSize = size;
}
void
FileInstallationUnit::SetLevelQuotaSize(QuotaSizeType size)
{
LOG_FUNCTION2(
FileInstallationUnit::SetLevelQuotaSize,
String::format(L"%1!d!", size));
levelQuotaSize = size;
}
void
FileInstallationUnit::SetSpaceQuotaValue(LONGLONG value)
{
LOG_FUNCTION2(
FileInstallationUnit::SetSpaceQuotaValue,
String::format(L"%1!I64d!", value));
spaceQuotaValue = value;
}
void
FileInstallationUnit::SetLevelQuotaValue(LONGLONG value)
{
LOG_FUNCTION2(
FileInstallationUnit::SetLevelQuotaValue,
String::format(L"%1!I64d!", value));
levelQuotaValue = value;
}
void
FileInstallationUnit::SetDefaultQuotas(bool value)
{
LOG_FUNCTION2(
FileInstallationUnit::SetDefaultQuotas,
value ? L"true" : L"false");
setDefaultQuotas = value;
}
void
FileInstallationUnit::SetDenyUsersOverQuota(bool value)
{
LOG_FUNCTION2(
FileInstallationUnit::SetDenyUsersOverQuota,
value ? L"true" : L"false");
denyUsersOverQuota = value;
}
void
FileInstallationUnit::SetEventDiskSpaceLimit(bool value)
{
LOG_FUNCTION2(
FileInstallationUnit::SetEventDiskSpaceLimit,
value ? L"true" : L"false");
eventDiskSpaceLimit = value;
}
void
FileInstallationUnit::SetEventWarningLevel(bool value)
{
LOG_FUNCTION2(
FileInstallationUnit::SetEventWarningLevel,
value ? L"true" : L"false");
eventWarningLevel = value;
}
void
FileInstallationUnit::SetInstallIndexingService(bool value)
{
LOG_FUNCTION2(
FileInstallationUnit::SetInstallIndexingService,
value ? L"true" : L"false");
installIndexingService = value;
}
void
FileInstallationUnit::WriteDiskQuotas(HANDLE logfileHandle)
{
LOG_FUNCTION(FileInstallationUnit::WriteDiskQuotas);
HRESULT hr = S_OK;
bool wasSomethingSet = false;
do
{
// Calculate the new values
LONGLONG newSpaceQuota = 0;
ConvertValueBySizeType(spaceQuotaValue, spaceQuotaSize, newSpaceQuota);
LONGLONG newLevelQuota = 0;
ConvertValueBySizeType(levelQuotaValue, levelQuotaSize, newLevelQuota);
DWORD logFlags = 0;
logFlags |= eventDiskSpaceLimit ? DISKQUOTA_LOGFLAG_USER_LIMIT : 0;
logFlags |= eventWarningLevel ? DISKQUOTA_LOGFLAG_USER_THRESHOLD : 0;
DWORD quotaState = denyUsersOverQuota ? DISKQUOTA_STATE_ENFORCE : DISKQUOTA_STATE_TRACK;
// Get a list of the valid drives
StringVector dl;
hr = FS::GetValidDrives(std::back_inserter(dl));
if (FAILED(hr))
{
LOG(String::format(L"Failed to GetValidDrives: hr = %1!x!", hr));
break;
}
// Loop through the list
ASSERT(dl.size());
for (
StringVector::iterator i = dl.begin();
i != dl.end();
++i)
{
// For each drive that supports disk quotas set the new values
// Create a Disk Quota Control
// Multiple initializations of this object are not allowed so
// I have to create a new instance each time through the loop
SmartInterface<IDiskQuotaControl> diskQuotaControl;
hr = diskQuotaControl.AcquireViaCreateInstance(
CLSID_DiskQuotaControl,
0,
CLSCTX_INPROC_SERVER,
IID_IDiskQuotaControl);
if (FAILED(hr))
{
LOG(String::format(
L"Failed to create a disk quota control: hr = %1!x!",
hr));
break;
}
hr = diskQuotaControl->Initialize(
i->c_str(),
TRUE);
if (FAILED(hr))
{
continue;
}
LOG(String::format(
L"Setting quotas on drive %1",
i->c_str()));
// Turn on the disk quotas
hr = diskQuotaControl->SetQuotaState(quotaState);
if (SUCCEEDED(hr))
{
LOG(String::format(
L"Disk quota set on drive %1",
i->c_str()));
CYS_APPEND_LOG(
String::format(
String::load(IDS_LOG_DISK_QUOTA_DRIVE_FORMAT),
i->c_str()));
if(denyUsersOverQuota)
{
LOG(L"Disk space denied to users exceeding limit");
CYS_APPEND_LOG(
String::format(
String::load(IDS_LOG_DISK_QUOTA_DENY_FORMAT),
newSpaceQuota));
}
else
{
LOG(L"Disk space is not denied to users exceeding limit");
CYS_APPEND_LOG(
String::format(
String::load(IDS_LOG_DISK_QUOTA_NOT_DENY_FORMAT),
newSpaceQuota));
}
wasSomethingSet = true;
}
// Set the default quota limit
hr = diskQuotaControl->SetDefaultQuotaLimit(newSpaceQuota);
if (SUCCEEDED(hr))
{
LOG(String::format(
L"Disk space limited to %1!I64d!",
newSpaceQuota));
CYS_APPEND_LOG(
String::format(
String::load(IDS_LOG_DISK_QUOTA_LIMIT_FORMAT),
newSpaceQuota));
wasSomethingSet = true;
}
// Set the warning level threshold
hr = diskQuotaControl->SetDefaultQuotaThreshold(newLevelQuota);
if (SUCCEEDED(hr))
{
LOG(String::format(
L"Disk threshold set to %1!I64d!",
newLevelQuota));
CYS_APPEND_LOG(
String::format(
String::load(IDS_LOG_DISK_QUOTA_THRESHOLD_FORMAT),
newLevelQuota));
wasSomethingSet = true;
}
// Set the event flags
hr = diskQuotaControl->SetQuotaLogFlags(logFlags);
if (SUCCEEDED(hr))
{
if (eventDiskSpaceLimit)
{
LOG(L"An event is logged when a user exceeds disk space limit");
CYS_APPEND_LOG(
String::load(IDS_LOG_DISK_QUOTA_LOG_LIMIT));
}
if (eventWarningLevel)
{
LOG(L"An event is logged when a user exceeds the warning limit");
CYS_APPEND_LOG(
String::load(IDS_LOG_DISK_QUOTA_LOG_WARNING));
}
wasSomethingSet = true;
}
}
} while (false);
if (FAILED(hr) && !wasSomethingSet)
{
CYS_APPEND_LOG(
String::format(
String::load(IDS_LOG_DISK_QUOTA_FAILED),
hr));
}
LOG(String::format(
L"hr = %1!x!",
hr));
}
void
FileInstallationUnit::ConvertValueBySizeType(
LONGLONG value,
QuotaSizeType sizeType,
LONGLONG& newValue)
{
int multiplier = 0;
switch (sizeType)
{
case QUOTA_SIZE_KB :
multiplier = CYS_KB;
break;
case QUOTA_SIZE_MB :
multiplier = CYS_MB;
break;
case QUOTA_SIZE_GB :
multiplier = CYS_GB;
break;
default :
ASSERT(false);
break;
}
newValue = value * multiplier;
}