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.
1887 lines
59 KiB
1887 lines
59 KiB
///////////////////////////////////////////////////////////////////////////////
|
|
/* File: volprop.cpp
|
|
|
|
Description: Provides implementations for quota property pages.
|
|
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
08/01/97 Removed IDC_CBX_WARN_THRESHOLD from UI. BrianAu
|
|
11/27/98 Added logging checkboxes back in. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
#include "dskquota.h"
|
|
#include "volprop.h"
|
|
#include "uihelp.h"
|
|
#include "registry.h"
|
|
#include "guidsp.h"
|
|
#include "uiutils.h"
|
|
|
|
//
|
|
// Context help IDs.
|
|
//
|
|
#pragma data_seg(".text", "CODE")
|
|
const static DWORD rgVolumePropPageHelpIDs[] =
|
|
{
|
|
IDC_TRAFFIC_LIGHT, IDH_TRAFFIC_LIGHT,
|
|
IDC_TXT_QUOTA_STATUS, IDH_TXT_QUOTA_STATUS,
|
|
IDC_TXT_QUOTA_STATUS_LABEL, DWORD(-1),
|
|
IDC_CBX_ENABLE_QUOTA, IDH_CBX_ENABLE_QUOTA,
|
|
IDC_CBX_DENY_LIMIT, IDH_CBX_DENY_LIMIT,
|
|
IDC_RBN_DEF_NOLIMIT, IDH_RBN_DEF_NO_LIMIT,
|
|
IDC_RBN_DEF_LIMIT, IDH_RBN_DEF_LIMIT,
|
|
IDC_EDIT_DEF_LIMIT, IDH_EDIT_DEF_LIMIT,
|
|
IDC_EDIT_DEF_THRESHOLD, IDH_EDIT_DEF_THRESHOLD,
|
|
IDC_CMB_DEF_LIMIT, IDH_CMB_DEF_LIMIT,
|
|
IDC_CMB_DEF_THRESHOLD, IDH_CMB_DEF_THRESHOLD,
|
|
IDC_BTN_DETAILS, IDH_BTN_DETAILS,
|
|
IDC_BTN_EVENTLOG, IDH_BTN_EVENTLOG,
|
|
IDC_CBX_LOG_OVERWARNING, IDH_CBX_LOG_OVERWARNING,
|
|
IDC_CBX_LOG_OVERLIMIT, IDH_CBX_LOG_OVERLIMIT,
|
|
IDC_TXT_DEFAULTS, IDH_GRP_DEFAULTS,
|
|
IDC_TXT_LOGGING, DWORD(-1),
|
|
IDC_TXT_WARN_LEVEL, DWORD(-1),
|
|
0,0
|
|
};
|
|
|
|
|
|
#pragma data_seg()
|
|
|
|
extern TCHAR c_szWndClassDetailsView[]; // defined in details.cpp
|
|
|
|
/*
|
|
// NOTE: This code has been disabled.
|
|
// I've left in case we decide to launch the event viewer from
|
|
// the volume prop page again. [brianau - 3/23/98]
|
|
//
|
|
const TCHAR c_szVerbOpen[] = TEXT("Open");
|
|
const TCHAR c_szManagementConsole[] = TEXT("MMC.EXE");
|
|
const TCHAR c_szMMCInitFile[] = TEXT("%SystemRoot%\\System32\\EVENTVWR.MSC");
|
|
*/
|
|
|
|
|
|
#define VPPM_FOCUS_ON_THRESHOLDEDIT (WM_USER + 1)
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::VolumePropPage
|
|
|
|
Description: Constructor for a volume property page object.
|
|
Initializes the members that hold volume quota data.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: Nothing.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
VolumePropPage::VolumePropPage(VOID)
|
|
: m_dwQuotaState(0),
|
|
m_dwQuotaLogFlags(0),
|
|
m_idStatusUpdateTimer(0),
|
|
m_dwLastStatusMsgID(0),
|
|
m_cVolumeMaxBytes(NOLIMIT),
|
|
m_pxbDefaultLimit(NULL),
|
|
m_pxbDefaultThreshold(NULL),
|
|
m_llDefaultQuotaThreshold(0),
|
|
m_llDefaultQuotaLimit(0),
|
|
m_idCtlNextFocus(-1)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::~VolumePropPage
|
|
|
|
Description: Destructor for a volume property page object.
|
|
|
|
Arguments: None.
|
|
|
|
Returns: Nothing.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
VolumePropPage::~VolumePropPage(
|
|
VOID
|
|
)
|
|
{
|
|
delete m_pxbDefaultLimit;
|
|
delete m_pxbDefaultThreshold;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::DlgProc
|
|
|
|
Description: Static method called by windows to process messages for the
|
|
property page dialog. Since it's static, we have to save the "this"
|
|
pointer in the window's USERDATA.
|
|
|
|
Arguments: Standard WndProc-type arguments.
|
|
|
|
Returns: Standard WndProc-type return values.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR APIENTRY
|
|
VolumePropPage::DlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
INT_PTR bResult = FALSE;
|
|
|
|
//
|
|
// Retrieve the "this" pointer from the dialog's userdata.
|
|
// It was placed there in OnInitDialog().
|
|
//
|
|
VolumePropPage *pThis = (VolumePropPage *)GetWindowLongPtr(hDlg, DWLP_USER);
|
|
|
|
try
|
|
{
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_INITDIALOG")));
|
|
PROPSHEETPAGE *pPage = (PROPSHEETPAGE *)lParam;
|
|
pThis = (VolumePropPage *)pPage->lParam;
|
|
|
|
DBGASSERT((NULL != pThis));
|
|
//
|
|
// pThis pointer AddRef'd in AddPages().
|
|
// Save it in the window's userdata.
|
|
//
|
|
SetWindowLongPtr(hDlg, DWLP_USER, (INT_PTR)pThis);
|
|
bResult = pThis->OnInitDialog(hDlg, wParam, lParam);
|
|
break;
|
|
}
|
|
|
|
case WM_SYSCOLORCHANGE:
|
|
bResult = pThis->m_TrafficLight.ForwardMessage(message, wParam, lParam);
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_NOTIFY")));
|
|
bResult = pThis->OnNotify(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_COMMAND")));
|
|
bResult = pThis->OnCommand(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
case WM_HELP:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_HELP")));
|
|
bResult = pThis->OnHelp(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
bResult = pThis->OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_DESTROY")));
|
|
pThis->KillStatusUpdateTimer(hDlg);
|
|
//
|
|
// Nothing to do.
|
|
//
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_TIMER")));
|
|
bResult = pThis->OnTimer(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
case VPPM_FOCUS_ON_THRESHOLDEDIT:
|
|
//
|
|
// This is sort of a hack because of the way the prop sheet
|
|
// code in comctl32 sets focus after a page has returned
|
|
// PSNRET_INVALID. It automatically activates the problem
|
|
// page and sets focus to the FIRST control in the tab order.
|
|
// Since the only failure we generate is from the threshold
|
|
// exceeding the limit, I want to return focus to the threshold
|
|
// edit control so that the user can directly change the offending
|
|
// value. Posting this custom message was the only way I
|
|
// could get this to work. [brianau].
|
|
//
|
|
SetFocus((HWND)lParam);
|
|
SendMessage((HWND)lParam, EM_SETSEL, 0, -1);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
catch(CAllocException& me)
|
|
{
|
|
//
|
|
// Announce any out-of-memory errors associated with running the
|
|
// volume Quota property page.
|
|
//
|
|
DiskQuotaMsgBox(GetDesktopWindow(),
|
|
IDS_OUTOFMEMORY,
|
|
IDS_TITLE_DISK_QUOTA,
|
|
MB_ICONERROR | MB_OK);
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnInitDialog
|
|
|
|
Description: Handler for WM_INITDIALOG.
|
|
|
|
Arguments:
|
|
hDlg - Dialog window handle.
|
|
|
|
wParam - Handle of control to receive focus if we return FALSE.
|
|
|
|
lParam - Pointer to PROPSHEETPAGE structure for the property page.
|
|
|
|
Returns:
|
|
TRUE = Tells windows to assign focus to the control in wParam.
|
|
|
|
Exceptions: OutOfMemory.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
02/10/98 Converted from static to a virtual function to BrianAu
|
|
support addition of SnapInVolPropPage class.
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnInitDialog(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
HRESULT hResult = NO_ERROR;
|
|
DWORD dwSectorsPerCluster = 0;
|
|
DWORD dwBytesPerSector = 0;
|
|
DWORD dwFreeClusters = 0;
|
|
DWORD dwTotalClusters = 0;
|
|
|
|
//
|
|
// Load the volume's quota information into member variables.
|
|
//
|
|
hResult = RefreshCachedVolumeQuotaInfo();
|
|
|
|
//
|
|
// Calculate the volume's size.
|
|
// We'll use this to limit user threshold and quota limit entries.
|
|
//
|
|
if (GetDiskFreeSpace(m_idVolume.ForParsing(),
|
|
&dwSectorsPerCluster,
|
|
&dwBytesPerSector,
|
|
&dwFreeClusters,
|
|
&dwTotalClusters))
|
|
{
|
|
m_cVolumeMaxBytes = (UINT64)dwSectorsPerCluster *
|
|
(UINT64)dwBytesPerSector *
|
|
(UINT64)dwTotalClusters;
|
|
}
|
|
|
|
//
|
|
// Create the XBytes objects to manage the relationship between the
|
|
// limit/threshold edit controls and their combo boxes.
|
|
//
|
|
m_pxbDefaultLimit = new XBytes(hDlg,
|
|
IDC_EDIT_DEF_LIMIT,
|
|
IDC_CMB_DEF_LIMIT,
|
|
m_llDefaultQuotaLimit);
|
|
m_pxbDefaultThreshold = new XBytes(hDlg,
|
|
IDC_EDIT_DEF_THRESHOLD,
|
|
IDC_CMB_DEF_THRESHOLD,
|
|
m_llDefaultQuotaThreshold);
|
|
|
|
m_TrafficLight.Initialize(GetDlgItem(hDlg, IDC_TRAFFIC_LIGHT), IDR_AVI_TRAFFIC);
|
|
|
|
InitializeControls(hDlg);
|
|
|
|
return TRUE; // Set focus to default control.
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnCommand
|
|
|
|
Description: Handler for WM_COMMAND.
|
|
|
|
Arguments:
|
|
hDlg - Dialog window handle.
|
|
|
|
wParam - ID of selected control and notification code.
|
|
|
|
lParam - HWND of selected control.
|
|
|
|
Returns:
|
|
TRUE = Message wasn't handled.
|
|
FALSE = Message was handled.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
08/01/97 Removed IDC_CBX_WARN_THRESHOLD from UI. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnCommand(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
INT_PTR bResult = TRUE;
|
|
DWORD dwCtlId = LOWORD(wParam);
|
|
HWND hWndCtl = (HWND)lParam;
|
|
DWORD dwNotifyCode = HIWORD(wParam);
|
|
BOOL bIsChecked = FALSE;
|
|
BOOL bEnableApplyBtn = FALSE;
|
|
|
|
switch(dwCtlId)
|
|
{
|
|
case IDC_CBX_ENABLE_QUOTA:
|
|
{
|
|
//
|
|
// This is executed when the user checks or unchecks the
|
|
// "Enable quota management checkbox.
|
|
//
|
|
bIsChecked = IsDlgButtonChecked(hDlg, IDC_CBX_ENABLE_QUOTA);
|
|
//
|
|
// Remember: Limit/Threshold Edit and combo boxes are enabled/disabled
|
|
// through XBytes::SetBytes().
|
|
//
|
|
m_pxbDefaultLimit->SetBytes(m_llDefaultQuotaLimit);
|
|
m_pxbDefaultThreshold->SetBytes(m_llDefaultQuotaThreshold);
|
|
|
|
CheckDlgButton(hDlg, IDC_RBN_DEF_NOLIMIT, NOLIMIT == m_pxbDefaultLimit->GetBytes());
|
|
CheckDlgButton(hDlg, IDC_RBN_DEF_LIMIT, BST_CHECKED != IsDlgButtonChecked(hDlg, IDC_RBN_DEF_NOLIMIT));
|
|
CheckDlgButton(hDlg, IDC_CBX_DENY_LIMIT, bIsChecked && DISKQUOTA_IS_ENFORCED(m_dwQuotaState));
|
|
CheckDlgButton(hDlg,
|
|
IDC_CBX_LOG_OVERWARNING,
|
|
bIsChecked &&
|
|
DISKQUOTA_IS_LOGGED_USER_THRESHOLD(m_dwQuotaLogFlags));
|
|
CheckDlgButton(hDlg,
|
|
IDC_CBX_LOG_OVERLIMIT,
|
|
bIsChecked &&
|
|
DISKQUOTA_IS_LOGGED_USER_LIMIT(m_dwQuotaLogFlags));
|
|
|
|
EnableControls(hDlg);
|
|
|
|
bEnableApplyBtn = TRUE;
|
|
bResult = FALSE;
|
|
break;
|
|
}
|
|
|
|
case IDC_CBX_DENY_LIMIT:
|
|
bResult = FALSE;
|
|
bEnableApplyBtn = TRUE;
|
|
break;
|
|
|
|
case IDC_RBN_DEF_NOLIMIT:
|
|
DBGASSERT((IsDlgButtonChecked(hDlg, IDC_CBX_ENABLE_QUOTA)));
|
|
|
|
if (m_pxbDefaultLimit->IsEnabled())
|
|
{
|
|
m_pxbDefaultThreshold->SetBytes(NOLIMIT);
|
|
m_pxbDefaultLimit->SetBytes(NOLIMIT);
|
|
bEnableApplyBtn = TRUE;
|
|
}
|
|
bResult = FALSE;
|
|
break;
|
|
|
|
case IDC_RBN_DEF_LIMIT:
|
|
//
|
|
// If the original threshold was -1 (no limit), set to 0.
|
|
// Otherwise, set to the original value.
|
|
//
|
|
DBGASSERT((IsDlgButtonChecked(hDlg, IDC_CBX_ENABLE_QUOTA)));
|
|
if (!m_pxbDefaultLimit->IsEnabled())
|
|
{
|
|
m_pxbDefaultLimit->SetBytes(NOLIMIT == m_llDefaultQuotaLimit ?
|
|
0 : m_llDefaultQuotaLimit);
|
|
m_pxbDefaultThreshold->SetBytes(NOLIMIT == m_llDefaultQuotaThreshold ?
|
|
0 : m_llDefaultQuotaThreshold);
|
|
|
|
|
|
EnableControls(hDlg);
|
|
bEnableApplyBtn = TRUE;
|
|
}
|
|
bResult = FALSE;
|
|
break;
|
|
|
|
case IDC_EDIT_DEF_LIMIT:
|
|
case IDC_EDIT_DEF_THRESHOLD:
|
|
switch(dwNotifyCode)
|
|
{
|
|
case EN_UPDATE:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc; WM_COMMAND, EN_CHANGE")));
|
|
bResult = OnEditNotifyUpdate(hDlg, wParam, lParam);
|
|
bEnableApplyBtn = TRUE;
|
|
break;
|
|
|
|
case EN_KILLFOCUS:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc; WM_COMMAND, EN_KILLFOCUS")));
|
|
bResult = OnEditNotifyKillFocus(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
case EN_SETFOCUS:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc; WM_COMMAND, EN_SETFOCUS")));
|
|
bResult = OnEditNotifySetFocus(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case IDC_CMB_DEF_LIMIT:
|
|
case IDC_CMB_DEF_THRESHOLD:
|
|
switch(dwNotifyCode)
|
|
{
|
|
case CBN_SELCHANGE:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_COMMAND, CBN_CHANGE")));
|
|
bResult = OnComboNotifySelChange(hDlg, wParam, lParam);
|
|
bEnableApplyBtn = TRUE;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case IDC_BTN_DETAILS:
|
|
bResult = OnButtonDetails(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
case IDC_CBX_LOG_OVERLIMIT:
|
|
case IDC_CBX_LOG_OVERWARNING:
|
|
bEnableApplyBtn = TRUE;
|
|
break;
|
|
|
|
/*
|
|
//
|
|
// NOTE: This code disabled until we decide to launch the event viewer
|
|
// from the volume prop page. Probably won't happen because we
|
|
// can't define a quota-specific error type for NT events.
|
|
// If we can't filter an event viewer list on quota-only events,
|
|
// there's not much use in getting to the event viewer from here.
|
|
// [brianau - 3/23/98]
|
|
//
|
|
case IDC_BTN_EVENTLOG:
|
|
bResult = OnButtonEventLog(hDlg, wParam, lParam);
|
|
break;
|
|
*/
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (bEnableApplyBtn)
|
|
PropSheet_Changed(GetParent(hDlg), hDlg);
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnNotify
|
|
|
|
Description: Handler for WM_NOTIFY.
|
|
|
|
Arguments:
|
|
hDlg - Dialog window handle.
|
|
|
|
wParam - ID of selected control and notification code.
|
|
|
|
lParam - HWND of selected control.
|
|
|
|
Returns:
|
|
TRUE = Message wasn't handled.
|
|
FALSE = Message was handled.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnNotify(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
DBGTRACE((DM_VPROP, DL_MID, TEXT("VolumePropPage::OnNotify")));
|
|
INT_PTR bResult = TRUE;
|
|
|
|
switch(((NMHDR *)lParam)->code)
|
|
{
|
|
case PSN_SETACTIVE:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_NOTIFY, PSN_SETACTIVE")));
|
|
bResult = OnSheetNotifySetActive(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
case PSN_APPLY:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_NOTIFY, PSN_APPLY")));
|
|
bResult = OnSheetNotifyApply(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_NOTIFY, PSN_KILLACTIVE")));
|
|
bResult = OnSheetNotifyKillActive(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
DBGPRINT((DM_WND, DL_MID, TEXT("DlgProc: WM_NOTIFY, PSN_RESET")));
|
|
bResult = OnSheetNotifyReset(hDlg, wParam, lParam);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnSheetNotifySetActive
|
|
|
|
Description: Handler for WM_NOTIFY - PSN_SETACTIVE.
|
|
|
|
Arguments:
|
|
hDlg - Dialog window handle.
|
|
|
|
wParam - ID of control.
|
|
|
|
lParam - Address of NMHDR structure.
|
|
|
|
Returns:
|
|
FALSE = Accept activation.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnSheetNotifySetActive(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
DBGTRACE((DM_VPROP, DL_HIGH, TEXT("VolumePropPage::OnSheetNotifySetActive")));
|
|
|
|
//
|
|
// Update the status text and set the status update timer.
|
|
//
|
|
UpdateStatusIndicators(hDlg);
|
|
SetStatusUpdateTimer(hDlg);
|
|
|
|
if (IDC_EDIT_DEF_THRESHOLD == m_idCtlNextFocus)
|
|
{
|
|
//
|
|
// Focus is being set as a result of an invalid entry
|
|
// in the warning level field. Force input focus to the
|
|
// field and select the entire contents. User can then just
|
|
// enter a new value.
|
|
//
|
|
PostMessage(hDlg,
|
|
VPPM_FOCUS_ON_THRESHOLDEDIT,
|
|
0,
|
|
(LPARAM)GetDlgItem(hDlg, IDC_EDIT_DEF_THRESHOLD));
|
|
|
|
m_idCtlNextFocus = -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnSheetNotifyApply
|
|
|
|
Description: Handler for WM_NOTIFY - PSN_APPLY.
|
|
|
|
Arguments:
|
|
hDlg - Dialog window handle.
|
|
|
|
wParam - ID of control.
|
|
|
|
lParam - Address of NMHDR structure.
|
|
|
|
Returns:
|
|
TRUE = PSN return value set using SetWindowLong.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnSheetNotifyApply(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
DBGTRACE((DM_VPROP, DL_HIGH, TEXT("VolumePropPage::OnSheetNotifyApply")));
|
|
HRESULT hResult = NO_ERROR;
|
|
LONG dwPSNReturn = PSNRET_NOERROR;
|
|
INT idMsg = -1;
|
|
|
|
if (!IsDlgButtonChecked(hDlg, IDC_CBX_ENABLE_QUOTA) &&
|
|
!DISKQUOTA_IS_DISABLED(m_dwQuotaState))
|
|
{
|
|
idMsg = IDS_DISABLE_QUOTA_WARNING;
|
|
}
|
|
else if (IsDlgButtonChecked(hDlg, IDC_CBX_ENABLE_QUOTA) &&
|
|
DISKQUOTA_IS_DISABLED(m_dwQuotaState))
|
|
{
|
|
idMsg = IDS_ENABLE_QUOTA_WARNING;
|
|
}
|
|
|
|
if (-1 != idMsg)
|
|
{
|
|
//
|
|
// User wants to disable or enable quotas.
|
|
// Warn about what this means and let them know that
|
|
// re-activation of quotas requires a quota file rebuild.
|
|
//
|
|
if (IDCANCEL == DiskQuotaMsgBox(hDlg,
|
|
idMsg,
|
|
IDS_TITLE_DISK_QUOTA,
|
|
MB_ICONWARNING | MB_OKCANCEL))
|
|
{
|
|
//
|
|
// User decided to not continue the action.
|
|
// Restore the checkbox to it's previous setting and abort the
|
|
// settings change.
|
|
// Sending the message to our DlgProc resets the dependent controls
|
|
// to their proper states.
|
|
//
|
|
CheckDlgButton(hDlg,
|
|
IDC_CBX_ENABLE_QUOTA,
|
|
!IsDlgButtonChecked(hDlg, IDC_CBX_ENABLE_QUOTA));
|
|
|
|
SendMessage(hDlg,
|
|
WM_COMMAND,
|
|
(WPARAM)MAKELONG((WORD)IDC_CBX_ENABLE_QUOTA, (WORD)0),
|
|
(LPARAM)GetDlgItem(hDlg, IDC_CBX_ENABLE_QUOTA));
|
|
|
|
dwPSNReturn = PSNRET_INVALID;
|
|
}
|
|
}
|
|
|
|
if (PSNRET_NOERROR == dwPSNReturn)
|
|
{
|
|
//
|
|
// We need to do this because if you activate the apply button
|
|
// with Alt-A we receive PSN_APPLY before EN_KILLFOCUS.
|
|
//
|
|
m_pxbDefaultThreshold->OnEditKillFocus((LPARAM)GetDlgItem(hDlg, IDC_EDIT_DEF_THRESHOLD));
|
|
m_pxbDefaultLimit->OnEditKillFocus((LPARAM)GetDlgItem(hDlg, IDC_EDIT_DEF_LIMIT));
|
|
|
|
//
|
|
// Ensure warning threshold is not above limit.
|
|
//
|
|
INT64 iThreshold = m_pxbDefaultThreshold->GetBytes();
|
|
INT64 iLimit = m_pxbDefaultLimit->GetBytes();
|
|
|
|
if (iThreshold > iLimit)
|
|
{
|
|
TCHAR szLimit[40], szThreshold[40];
|
|
XBytes::FormatByteCountForDisplay(iLimit, szLimit, ARRAYSIZE(szLimit));
|
|
XBytes::FormatByteCountForDisplay(iThreshold, szThreshold, ARRAYSIZE(szThreshold));
|
|
|
|
CString s(g_hInstDll, IDS_FMT_ERR_WARNOVERLIMIT, szThreshold, szLimit, szLimit);
|
|
switch(DiskQuotaMsgBox(hDlg, s, IDS_TITLE_DISK_QUOTA, MB_ICONWARNING | MB_YESNO))
|
|
{
|
|
case IDYES:
|
|
m_pxbDefaultThreshold->SetBytes(iLimit);
|
|
break;
|
|
|
|
case IDNO:
|
|
m_idCtlNextFocus = IDC_EDIT_DEF_THRESHOLD;
|
|
dwPSNReturn = PSNRET_INVALID;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (PSNRET_NOERROR == dwPSNReturn)
|
|
{
|
|
hResult = ApplySettings(hDlg);
|
|
if (FAILED(hResult))
|
|
{
|
|
DiskQuotaMsgBox(hDlg,
|
|
IDS_APPLY_SETTINGS_ERROR,
|
|
IDS_TITLE_DISK_QUOTA,
|
|
MB_ICONERROR | MB_OK);
|
|
dwPSNReturn = PSNRET_INVALID;
|
|
InitializeControls(hDlg);
|
|
}
|
|
}
|
|
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, dwPSNReturn);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnSheetNotifyKillActive
|
|
|
|
Description: Handler for WM_NOTIFY - PSN_KILLACTIVE.
|
|
|
|
Arguments:
|
|
hDlg - Dialog window handle.
|
|
|
|
wParam - ID of control.
|
|
|
|
lParam - Address of NMHDR structure.
|
|
|
|
Returns:
|
|
TRUE = Invalid data entered. Don't kill page.
|
|
FALSE = All data is valid. Ok to kill page.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnSheetNotifyKillActive(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
DBGTRACE((DM_VPROP, DL_HIGH, TEXT("VolumePropPage::OnSheetNotifyKillActive")));
|
|
BOOL bAllDataIsValid = TRUE;
|
|
|
|
if (bAllDataIsValid)
|
|
{
|
|
KillStatusUpdateTimer(hDlg);
|
|
}
|
|
|
|
SetWindowLongPtr(hDlg, DWLP_MSGRESULT, !bAllDataIsValid);
|
|
|
|
//
|
|
// Must release quota controller whenever the sheet is deactivated.
|
|
// Without this we were holding open a handle to the volume. This prevented
|
|
// the disk check utility ("Tools" page) from accessing the volume.
|
|
// Whenever we need an IDiskQuotaControl ptr we call GetQuotaController which
|
|
// will create a new controller if necessary.
|
|
//
|
|
if (NULL != m_pQuotaControl)
|
|
{
|
|
m_pQuotaControl->Release();
|
|
m_pQuotaControl = NULL;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnSheetNotifyReset
|
|
|
|
Description: Handler for WM_NOTIFY - PSN_RESET.
|
|
|
|
Arguments:
|
|
hDlg - Dialog window handle.
|
|
|
|
wParam - ID of control.
|
|
|
|
lParam - Address of NMHDR structure.
|
|
|
|
Returns:
|
|
No return value.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnSheetNotifyReset(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
DBGTRACE((DM_VPROP, DL_HIGH, TEXT("VolumePropPage::OnSheetNotifyReset")));
|
|
HRESULT hResult = NO_ERROR;
|
|
|
|
//
|
|
// Nothing to do right now.
|
|
//
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnHelp
|
|
|
|
Description: Handler for WM_HELP. Displays context sensitive help.
|
|
|
|
Arguments:
|
|
lParam - Pointer to a HELPINFO structure.
|
|
|
|
Returns: TRUE;
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/17/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnHelp(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, STR_DSKQUOUI_HELPFILE,
|
|
HELP_WM_HELP, (DWORD_PTR)(LPTSTR) rgVolumePropPageHelpIDs);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
INT_PTR
|
|
VolumePropPage::OnContextMenu(
|
|
HWND hwndItem,
|
|
int xPos,
|
|
int yPos
|
|
)
|
|
{
|
|
int idCtl = GetDlgCtrlID(hwndItem);
|
|
WinHelp(hwndItem,
|
|
UseWindowsHelp(idCtl) ? NULL : STR_DSKQUOUI_HELPFILE,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)((LPTSTR)rgVolumePropPageHelpIDs));
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnTimer
|
|
|
|
Description: Handler for WM_TIMER. Updates the quota status text and
|
|
traffic light.
|
|
|
|
Arguments:
|
|
wParam - Timer ID.
|
|
|
|
Returns: FALSE (0);
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/17/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnTimer(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
if (wParam == m_idStatusUpdateTimer)
|
|
{
|
|
UpdateStatusIndicators(hDlg);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnEditNotifyUpdate
|
|
|
|
Description: Handler for WM_COMMAND, EN_UPDATE.
|
|
Called whenever a character is entered in an edit control.
|
|
|
|
Arguments:
|
|
|
|
Returns: FALSE;
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/17/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnEditNotifyUpdate(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
XBytes *rgpxb[2] = { m_pxbDefaultLimit, m_pxbDefaultThreshold };
|
|
const int iLIMIT = 0;
|
|
const int iTHRESHOLD = 1;
|
|
int iCurrent = iLIMIT;
|
|
|
|
if (IDC_EDIT_DEF_THRESHOLD == LOWORD(wParam))
|
|
iCurrent = iTHRESHOLD;
|
|
|
|
if (NULL != rgpxb[iCurrent])
|
|
rgpxb[iCurrent]->OnEditNotifyUpdate(lParam);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnEditNotifyKillFocus
|
|
|
|
Description: Handler for WM_COMMAND, EN_KILLFOCUS.
|
|
Called whenever focus leaves an edit control.
|
|
Validates the value in the edit control and adjusts it if necessary.
|
|
|
|
Arguments:
|
|
|
|
Returns: FALSE;
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/17/96 Initial creation. BrianAu
|
|
11/12/98 Added code to call XBytes::OnEditKillFocus. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnEditNotifyKillFocus(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
XBytes *rgpxb[2] = { m_pxbDefaultLimit, m_pxbDefaultThreshold };
|
|
const int iLIMIT = 0;
|
|
const int iTHRESHOLD = 1;
|
|
int iCurrent = iLIMIT;
|
|
|
|
if (IDC_EDIT_DEF_THRESHOLD == LOWORD(wParam))
|
|
iCurrent = iTHRESHOLD;
|
|
|
|
if (NULL != rgpxb[iCurrent])
|
|
rgpxb[iCurrent]->OnEditKillFocus(lParam);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
INT_PTR
|
|
VolumePropPage::OnEditNotifySetFocus(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
//
|
|
// Nothing to do.
|
|
// FEATURE: Delete this method?
|
|
//
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnComboNotifySelChange
|
|
|
|
Description: Handler for WM_COMMAND, CBN_SELCHANGE.
|
|
Called whenever the user selects the combo box.
|
|
|
|
Arguments: Std DlgProc args.
|
|
|
|
Returns: FALSE;
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/17/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnComboNotifySelChange(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
XBytes *rgpxb[2] = { m_pxbDefaultLimit, m_pxbDefaultThreshold };
|
|
const int iLIMIT = 0;
|
|
const int iTHRESHOLD = 1;
|
|
int iCurrent = iLIMIT;
|
|
|
|
if (IDC_CMB_DEF_THRESHOLD == LOWORD(wParam))
|
|
iCurrent = iTHRESHOLD;
|
|
|
|
if (NULL != rgpxb[iCurrent])
|
|
rgpxb[iCurrent]->OnComboNotifySelChange(lParam);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::OnButtonDetails
|
|
|
|
Description: Called when the user selects the "Details" button.
|
|
If a details view is already active for this prop page, it is brought
|
|
to the foreground. If no details view is already active, a new one
|
|
is created.
|
|
|
|
Arguments: Standard DlgProc arguments.
|
|
|
|
Returns:
|
|
|
|
Exceptions: OutOfMemory.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
INT_PTR
|
|
VolumePropPage::OnButtonDetails(
|
|
HWND hDlg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
if (!ActivateExistingDetailsView())
|
|
{
|
|
//
|
|
// This property page doesn't have an active details view.
|
|
// Create one. Note: If something fails in the details view
|
|
// creation, it isn't displayed. The DetailsView code is
|
|
// responsible for reporting any errors to the user.
|
|
//
|
|
// NOTE: The VolumePropPage object never calls "delete"
|
|
// on the pDetailsView pointer. The details view
|
|
// object must live on it's own (modeless) after it is created.
|
|
// If the VolumePropPage object (this object) is still alive
|
|
// when the details view object is destroyed, it will receive a
|
|
// WM_DETAILS_VIEW_DESTROYED message from the view object. That's
|
|
// why we pass the hDlg in this constructor. When this message
|
|
// is received, we set m_pDetailsView to NULL so that OnButtonDetails
|
|
// will know to create a new view object.
|
|
//
|
|
DetailsView *pDetailsView = new DetailsView;
|
|
|
|
if (!pDetailsView->Initialize(m_idVolume))
|
|
{
|
|
//
|
|
// Something failed. Either out of memory or the view's thread
|
|
// couldn't start. Either way, the view won't run.
|
|
// Need to call delete to clean up any partially-completed initialization.
|
|
//
|
|
delete pDetailsView;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::ActivateExistingDetailsView
|
|
|
|
Description: Called by OnButtonDetails to see if there's already a details
|
|
view active for this volume. If there is, open it.
|
|
|
|
Arguments: None.
|
|
|
|
Returns:
|
|
TRUE = Existing details view was found and promoted to the foreground.
|
|
FALSE = Either no existing view was found or an existing one could
|
|
not be promoted to the foreground.
|
|
|
|
Exceptions: OutOfMemory.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
02/25/97 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
VolumePropPage::ActivateExistingDetailsView(
|
|
VOID
|
|
) const
|
|
{
|
|
BOOL bResult = FALSE;
|
|
CString strVolDisplayName;
|
|
DetailsView::CreateVolumeDisplayName(m_idVolume, &strVolDisplayName);
|
|
|
|
CString strDetailsViewTitle(g_hInstDll, IDS_TITLE_MAINWINDOW, (LPCTSTR)strVolDisplayName);
|
|
|
|
HWND hwndDetailsView = FindWindow(c_szWndClassDetailsView,
|
|
strDetailsViewTitle);
|
|
|
|
if (NULL != hwndDetailsView)
|
|
{
|
|
//
|
|
// Restore the details view and bring it to the front.
|
|
//
|
|
ShowWindow(hwndDetailsView, SW_RESTORE);
|
|
bResult = SetForegroundWindow(hwndDetailsView);
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::ApplySettings
|
|
|
|
Description: Applies the current settings to the volume if they have
|
|
changed from the original settings.
|
|
|
|
Arguments:
|
|
hDlg - Dialog window handle.
|
|
|
|
Returns:
|
|
NO_ERROR - Success.
|
|
E_INVALIDARG - One of the settings was invalid.
|
|
ERROR_ACCESS_DENIED (hr) - No WRITE access to quota device.
|
|
E_FAIL - Any other error.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
VolumePropPage::ApplySettings(
|
|
HWND hDlg
|
|
)
|
|
{
|
|
HRESULT hResult = NO_ERROR;
|
|
DWORD dwStateSetting = 0;
|
|
DWORD dwLogFlagSettings = m_dwQuotaLogFlags;
|
|
BOOL bTranslated = FALSE;
|
|
LONGLONG llThreshold;
|
|
LONGLONG llLimit;
|
|
IDiskQuotaControl *pqc;
|
|
|
|
hResult = GetQuotaController(&pqc);
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
//
|
|
// Set quota state if changed.
|
|
//
|
|
QuotaStateFromControls(hDlg, &dwStateSetting);
|
|
if (dwStateSetting != (m_dwQuotaState & DISKQUOTA_STATE_MASK))
|
|
{
|
|
hResult = pqc->SetQuotaState(dwStateSetting);
|
|
if (FAILED(hResult))
|
|
goto apply_failed;
|
|
|
|
m_dwQuotaState = dwStateSetting;
|
|
}
|
|
|
|
//
|
|
// Set quota log flags if changed.
|
|
//
|
|
LogFlagsFromControls(hDlg, &dwLogFlagSettings);
|
|
if (dwLogFlagSettings != m_dwQuotaLogFlags)
|
|
{
|
|
hResult = pqc->SetQuotaLogFlags(dwLogFlagSettings);
|
|
if (FAILED(hResult))
|
|
goto apply_failed;
|
|
|
|
m_dwQuotaLogFlags = dwLogFlagSettings;
|
|
}
|
|
|
|
//
|
|
// Get current default quota threshold and limit values.
|
|
//
|
|
if (IsDlgButtonChecked(hDlg, IDC_RBN_DEF_NOLIMIT))
|
|
{
|
|
llThreshold = NOLIMIT;
|
|
llLimit = NOLIMIT;
|
|
}
|
|
else
|
|
{
|
|
llThreshold = m_pxbDefaultThreshold->GetBytes();
|
|
llLimit = m_pxbDefaultLimit->GetBytes();
|
|
}
|
|
|
|
//
|
|
// Set default quota threshold if changed.
|
|
//
|
|
if (llThreshold != m_llDefaultQuotaThreshold)
|
|
{
|
|
hResult = pqc->SetDefaultQuotaThreshold(llThreshold);
|
|
if (FAILED(hResult))
|
|
goto apply_failed;
|
|
|
|
m_llDefaultQuotaThreshold = llThreshold;
|
|
}
|
|
|
|
//
|
|
// Set default quota limit if changed.
|
|
//
|
|
if (llLimit != m_llDefaultQuotaLimit)
|
|
{
|
|
hResult = pqc->SetDefaultQuotaLimit(llLimit);
|
|
if (FAILED(hResult))
|
|
goto apply_failed;
|
|
|
|
m_llDefaultQuotaLimit = llLimit;
|
|
}
|
|
|
|
apply_failed:
|
|
|
|
pqc->Release();
|
|
}
|
|
return hResult;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::RefreshCachedVolumeInfo
|
|
|
|
Description: Reads the volume's quota information and stores it in
|
|
member variables.
|
|
|
|
Arguments: None.
|
|
|
|
Returns:
|
|
NO_ERROR - Success.
|
|
ERROR_ACCESS_DENIED (hr) - No READ access to quota device.
|
|
E_FAIL - Any other error.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
VolumePropPage::RefreshCachedVolumeQuotaInfo(
|
|
VOID
|
|
)
|
|
{
|
|
HRESULT hResult = NO_ERROR;
|
|
|
|
IDiskQuotaControl *pqc;
|
|
|
|
hResult = GetQuotaController(&pqc);
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
//
|
|
// Read quota state.
|
|
//
|
|
hResult = pqc->GetQuotaState(&m_dwQuotaState);
|
|
if (FAILED(hResult))
|
|
goto refresh_vol_info_failed;
|
|
|
|
//
|
|
// Read quota log flags.
|
|
//
|
|
hResult = pqc->GetQuotaLogFlags(&m_dwQuotaLogFlags);
|
|
if (FAILED(hResult))
|
|
goto refresh_vol_info_failed;
|
|
|
|
//
|
|
// Read default quota threshold.
|
|
//
|
|
hResult = pqc->GetDefaultQuotaThreshold(&m_llDefaultQuotaThreshold);
|
|
if (FAILED(hResult))
|
|
goto refresh_vol_info_failed;
|
|
|
|
//
|
|
// Read default quota limit.
|
|
//
|
|
hResult = pqc->GetDefaultQuotaLimit(&m_llDefaultQuotaLimit);
|
|
|
|
refresh_vol_info_failed:
|
|
|
|
pqc->Release();
|
|
}
|
|
|
|
return hResult;
|
|
}
|
|
|
|
|
|
//
|
|
// Determine if a given disk quota policy value is set.
|
|
//
|
|
bool
|
|
VolumePropPage::SetByPolicy(
|
|
LPCTSTR pszPolicyValue
|
|
)
|
|
{
|
|
DWORD dwData;
|
|
DWORD dwType;
|
|
DWORD cbData = sizeof(dwData);
|
|
|
|
return (ERROR_SUCCESS == SHGetValue(HKEY_LOCAL_MACHINE,
|
|
REGSTR_KEY_POLICYDATA,
|
|
pszPolicyValue,
|
|
&dwType,
|
|
&dwData,
|
|
&cbData));
|
|
}
|
|
|
|
|
|
HRESULT
|
|
VolumePropPage::EnableControls(
|
|
HWND hwndDlg
|
|
)
|
|
{
|
|
BOOL bQuotaEnabled = (BST_CHECKED == IsDlgButtonChecked(hwndDlg, IDC_CBX_ENABLE_QUOTA));
|
|
BOOL bEnable;
|
|
|
|
//
|
|
// "Enable quota management" checkbox.
|
|
//
|
|
// Policy Quota Enabled Ctl Enabled
|
|
// 0 0 1
|
|
// 0 1 1
|
|
// 1 0 0
|
|
// 1 1 0
|
|
//
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CBX_ENABLE_QUOTA),
|
|
!SetByPolicy(REGSTR_VAL_POLICY_ENABLE));
|
|
//
|
|
// "Deny disk space..." checkbox.
|
|
//
|
|
// Policy Quota Enabled Ctl Enabled
|
|
// 0 0 0
|
|
// 0 1 1
|
|
// 1 0 0
|
|
// 1 1 0
|
|
//
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CBX_DENY_LIMIT),
|
|
bQuotaEnabled && !SetByPolicy(REGSTR_VAL_POLICY_ENFORCE));
|
|
//
|
|
// Log event checkboxes
|
|
//
|
|
// Policy Quota Enabled Ctl Enabled
|
|
// 0 0 0
|
|
// 0 1 1
|
|
// 1 0 0
|
|
// 1 1 0
|
|
//
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CBX_LOG_OVERLIMIT),
|
|
bQuotaEnabled && !SetByPolicy(REGSTR_VAL_POLICY_LOGLIMIT));
|
|
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CBX_LOG_OVERWARNING),
|
|
bQuotaEnabled && !SetByPolicy(REGSTR_VAL_POLICY_LOGTHRESHOLD));
|
|
|
|
//
|
|
// "Do not limit disk usage" radio button
|
|
// "Limit disk space to" radio button
|
|
//
|
|
// Policy Quota Enabled No Limit Ctl Enabled
|
|
// 0 0 0 0
|
|
// 0 0 1 0
|
|
// 0 1 0 0
|
|
// 0 1 1 1
|
|
// 1 0 0 0
|
|
// 1 0 1 0
|
|
// 1 1 0 0
|
|
// 1 1 1 0
|
|
//
|
|
bEnable = bQuotaEnabled && !SetByPolicy(REGSTR_VAL_POLICY_LIMIT);
|
|
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_RBN_DEF_NOLIMIT), bEnable);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_RBN_DEF_LIMIT), bEnable);
|
|
//
|
|
// "Limit disk space" edit and combo controls.
|
|
//
|
|
// Policy Quota Enabled No Limit Ctl Enabled
|
|
// 0 0 0 0
|
|
// 0 0 1 0
|
|
// 0 1 0 1
|
|
// 0 1 1 0
|
|
// 1 0 0 0
|
|
// 1 0 1 0
|
|
// 1 1 0 0
|
|
// 1 1 1 0
|
|
//
|
|
bEnable = bQuotaEnabled &&
|
|
!SetByPolicy(REGSTR_VAL_POLICY_LIMIT) &&
|
|
NOLIMIT != m_pxbDefaultLimit->GetBytes();
|
|
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_DEF_LIMIT), bEnable);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_DEF_LIMIT), bEnable);
|
|
|
|
bEnable = bQuotaEnabled &&
|
|
!SetByPolicy(REGSTR_VAL_POLICY_THRESHOLD) &&
|
|
NOLIMIT != m_pxbDefaultThreshold->GetBytes();
|
|
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_TXT_WARN_LEVEL), bEnable);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_DEF_THRESHOLD), bEnable);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_CMB_DEF_THRESHOLD), bEnable);
|
|
//
|
|
// Miscellaneous text controls.
|
|
//
|
|
// Quota Enabled Ctl Enabled
|
|
// 0 0
|
|
// 1 1
|
|
//
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_TXT_DEFAULTS), bQuotaEnabled);
|
|
EnableWindow(GetDlgItem(hwndDlg, IDC_TXT_LOGGING), bQuotaEnabled);
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::InitializeControls
|
|
|
|
Description: Initializes the page controls based on the volume's
|
|
quota settings.
|
|
|
|
Arguments:
|
|
hDlg - Dialog window handle.
|
|
|
|
Returns:
|
|
NO_ERROR - Always returns NO_ERROR.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/15/96 Initial creation. BrianAu
|
|
08/01/97 Removed IDC_CBX_WARN_THRESHOLD from UI. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
VolumePropPage::InitializeControls(
|
|
HWND hDlg
|
|
)
|
|
{
|
|
BOOL bQuotaEnabled = !(DISKQUOTA_IS_DISABLED(m_dwQuotaState));
|
|
BOOL bUnlimited = (NOLIMIT == m_llDefaultQuotaLimit);
|
|
|
|
CheckDlgButton(hDlg,
|
|
IDC_CBX_ENABLE_QUOTA,
|
|
bQuotaEnabled);
|
|
|
|
CheckDlgButton(hDlg,
|
|
IDC_CBX_DENY_LIMIT,
|
|
DISKQUOTA_IS_ENFORCED(m_dwQuotaState));
|
|
|
|
CheckDlgButton(hDlg,
|
|
IDC_CBX_LOG_OVERWARNING,
|
|
!DISKQUOTA_IS_DISABLED(m_dwQuotaState) &&
|
|
DISKQUOTA_IS_LOGGED_USER_THRESHOLD(m_dwQuotaLogFlags));
|
|
|
|
CheckDlgButton(hDlg,
|
|
IDC_CBX_LOG_OVERLIMIT,
|
|
!DISKQUOTA_IS_DISABLED(m_dwQuotaState) &&
|
|
DISKQUOTA_IS_LOGGED_USER_LIMIT(m_dwQuotaLogFlags));
|
|
|
|
CheckDlgButton(hDlg, IDC_RBN_DEF_NOLIMIT, bUnlimited);
|
|
CheckDlgButton(hDlg, IDC_RBN_DEF_LIMIT, !bUnlimited);
|
|
|
|
EnableControls(hDlg);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::UpdateStatusIndicators
|
|
Description: Updates the "Status" text message at the top of the property
|
|
page according to the actual quota system state. Also updates the
|
|
traffic light AVI clip.
|
|
|
|
Arguments:
|
|
hDlg - Dialog handle.
|
|
|
|
Returns:
|
|
Always returns NO_ERROR.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/18/96 Initial creation. BrianAu
|
|
08/28/96 Added stoplight icon. BrianAu
|
|
09/10/96 Converted stoplight from an icon to an AVI clip. BrianAu
|
|
Call it a traffic light now.
|
|
07/14/97 Removed distinct "enforce" and "tracking" messages BrianAu
|
|
and replaced with a single "active" message.
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
VolumePropPage::UpdateStatusIndicators(
|
|
HWND hDlg
|
|
)
|
|
{
|
|
HRESULT hResult = NO_ERROR;
|
|
DWORD dwMsgID = IDS_STATUS_UNKNOWN;
|
|
IDiskQuotaControl *pqc;
|
|
|
|
hResult = GetQuotaController(&pqc);
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
//
|
|
// Update cached state information.
|
|
//
|
|
hResult = pqc->GetQuotaState(&m_dwQuotaState);
|
|
pqc->Release();
|
|
pqc = NULL;
|
|
|
|
}
|
|
if (SUCCEEDED(hResult))
|
|
{
|
|
//
|
|
// Figure out what message to display.
|
|
// "Rebuilding" overrides any other state.
|
|
//
|
|
if (DISKQUOTA_FILE_REBUILDING(m_dwQuotaState))
|
|
{
|
|
dwMsgID = IDS_STATUS_REBUILDING;
|
|
}
|
|
else switch(m_dwQuotaState & DISKQUOTA_STATE_MASK)
|
|
{
|
|
case DISKQUOTA_STATE_DISABLED:
|
|
dwMsgID = IDS_STATUS_DISABLED;
|
|
break;
|
|
case DISKQUOTA_STATE_TRACK:
|
|
case DISKQUOTA_STATE_ENFORCE:
|
|
dwMsgID = IDS_STATUS_ACTIVE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (dwMsgID != m_dwLastStatusMsgID)
|
|
{
|
|
//
|
|
// Format the status text and configure the traffic light.
|
|
//
|
|
// Traffic light states:
|
|
// RED = Quotas disabled.
|
|
// GREEN = Quotas enabled.
|
|
// Flashing YELLOW = Quota file is rebuilding.
|
|
//
|
|
INT iTrafficLightState = TrafficLight::GREEN;
|
|
|
|
if (DISKQUOTA_FILE_REBUILDING(m_dwQuotaState))
|
|
iTrafficLightState = TrafficLight::FLASHING_YELLOW;
|
|
else if (DISKQUOTA_IS_DISABLED(m_dwQuotaState))
|
|
iTrafficLightState = TrafficLight::RED;
|
|
|
|
m_TrafficLight.Show(iTrafficLightState);
|
|
|
|
CString strStatus(g_hInstDll, dwMsgID);
|
|
SetWindowText(GetDlgItem(hDlg, IDC_TXT_QUOTA_STATUS), strStatus);
|
|
|
|
m_dwLastStatusMsgID = dwMsgID;
|
|
//
|
|
// Re-initialize the controls based on the new state.
|
|
//
|
|
InitializeControls(hDlg);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::QuotaStateFromControls
|
|
|
|
Description: Determines the quota state from the states of the individual
|
|
controls on the page.
|
|
|
|
Arguments:
|
|
hDlg - Dialog's window handle.
|
|
|
|
pdwState - Address of DWORD variable to receive state bits.
|
|
|
|
Returns:
|
|
Always returns NO_ERROR.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/19/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
VolumePropPage::QuotaStateFromControls(
|
|
HWND hDlg,
|
|
LPDWORD pdwState
|
|
) const
|
|
{
|
|
DBGASSERT((NULL != pdwState));
|
|
|
|
//
|
|
// Set quota state if changed.
|
|
//
|
|
if (IsDlgButtonChecked(hDlg, IDC_CBX_ENABLE_QUOTA))
|
|
{
|
|
if (IsDlgButtonChecked(hDlg, IDC_CBX_DENY_LIMIT))
|
|
{
|
|
*pdwState = DISKQUOTA_STATE_ENFORCE;
|
|
}
|
|
else
|
|
*pdwState = DISKQUOTA_STATE_TRACK;
|
|
}
|
|
else
|
|
*pdwState = DISKQUOTA_STATE_DISABLED;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::LogFlagsFromControls
|
|
|
|
Description: Determines the log flags state from the states of the
|
|
individual controls on the page.
|
|
|
|
Arguments:
|
|
hDlg - Dialog's window handle.
|
|
|
|
pdwLogFlags - Address of DWORD variable to receive flag bits.
|
|
|
|
Returns:
|
|
Always returns NO_ERROR.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
08/19/96 Initial creation. BrianAu
|
|
08/01/97 Removed IDC_CBX_WARN_THRESHOLD from UI. BrianAu
|
|
11/20/98 Added "log over limit" and "log over warning" BrianAu
|
|
controls.
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
VolumePropPage::LogFlagsFromControls(
|
|
HWND hDlg,
|
|
LPDWORD pdwLogFlags
|
|
) const
|
|
{
|
|
DBGASSERT((NULL != pdwLogFlags));
|
|
DISKQUOTA_SET_LOG_USER_LIMIT(*pdwLogFlags,
|
|
IsDlgButtonChecked(hDlg, IDC_CBX_LOG_OVERLIMIT));
|
|
|
|
DISKQUOTA_SET_LOG_USER_THRESHOLD(*pdwLogFlags,
|
|
IsDlgButtonChecked(hDlg, IDC_CBX_LOG_OVERWARNING));
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::TrafficLight::Initialize
|
|
|
|
Description: Initializes the traffic light by opening the AVI clip.
|
|
|
|
Arguments:
|
|
hwndAnimateCtl - Handle to the animation control in the dialog.
|
|
|
|
idAviClipRes - Resource ID of the AVI clip resource.
|
|
|
|
Returns: Nothing. If the thing doesn't load, it just won't play.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
09/10/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
VolumePropPage::TrafficLight::Initialize(
|
|
HWND hwndAnimateCtl,
|
|
INT idAviClipRes
|
|
)
|
|
{
|
|
DBGASSERT((NULL != hwndAnimateCtl));
|
|
|
|
m_hwndAnimateCtl = hwndAnimateCtl;
|
|
m_idAviClipRes = idAviClipRes;
|
|
|
|
Animate_Open(m_hwndAnimateCtl, MAKEINTRESOURCE(idAviClipRes));
|
|
//
|
|
// See note in TrafficLight::Show below.
|
|
//
|
|
// Animate_SetFrameTime(m_hwndAnimateCtl, GetCaretBlinkTime());
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Function: VolumePropPage::TrafficLight::Show
|
|
|
|
Description: Shows the traffic light in one of it's states.
|
|
|
|
Arguments:
|
|
eShow - One of the following enumerated constant values:
|
|
|
|
OFF, YELLOW, RED, GREEN, FLASHING_YELLOW.
|
|
|
|
NOTE: THIS IS VERY IMPORTANT!!!
|
|
|
|
The definitions of these constants MUST match as follows
|
|
with the frame numbers in the AVI clip TRAFFIC.AVI. If
|
|
you change either, it won't work.
|
|
|
|
Frame Constant Value
|
|
------ ---------------- ------
|
|
0 OFF 0
|
|
1 YELLOW 1
|
|
2 RED 2
|
|
3 GREEN 3
|
|
N/A FLASHING_YELLOW 4
|
|
|
|
Flashing yellow is created by playing frames 0 and 1
|
|
repeatedly.
|
|
|
|
Returns: Nothing.
|
|
|
|
Revision History:
|
|
|
|
Date Description Programmer
|
|
-------- --------------------------------------------------- ----------
|
|
09/10/96 Initial creation. BrianAu
|
|
*/
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
VOID
|
|
VolumePropPage::TrafficLight::Show(
|
|
INT eShow
|
|
)
|
|
{
|
|
switch(eShow)
|
|
{
|
|
case OFF:
|
|
case YELLOW:
|
|
case RED:
|
|
case GREEN:
|
|
Animate_Seek(m_hwndAnimateCtl, eShow);
|
|
break;
|
|
|
|
case FLASHING_YELLOW:
|
|
Animate_Seek(m_hwndAnimateCtl, YELLOW);
|
|
//
|
|
// NOTE:
|
|
//
|
|
// The common control guys didn't want me to add the ACM_SETFRAMETIME
|
|
// message so we can't vary the rate of the animation. Since we can't
|
|
// have a fixed-rate blinking control, I'm just fixing the traffic light
|
|
// at yellow rather than flashing. If we can ever add the frame time
|
|
// modification message to the animation control, we can activate
|
|
// this functionality. A flashing light isn't worth the trouble of
|
|
// a unique implementation. I really wanted this. It looks cool.
|
|
//
|
|
// FEATURE: If we have time. Make this work without the animation control.
|
|
// Note that I tried just setting the icon. But since the volume
|
|
// status checking is done on the same thread that processes the
|
|
// STM_SETICON messgae, flashing of the icon is erratic.
|
|
//
|
|
// Animate_Play(m_hwndAnimateCtl, YELLOW, OFF, (UINT)-1);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
INT_PTR
|
|
VolumePropPage::TrafficLight::ForwardMessage(
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
return SendMessage(m_hwndAnimateCtl, uMsg, wParam, lParam);
|
|
}
|
|
|