713 lines
21 KiB
C++
713 lines
21 KiB
C++
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Copyright (c) 1996-2000 Microsoft Corporation
|
||
|
//
|
||
|
// Module Name:
|
||
|
// Disks.cpp
|
||
|
//
|
||
|
// Abstract:
|
||
|
// Implementation of the CPhysDiskParamsPage class.
|
||
|
//
|
||
|
// Author:
|
||
|
// David Potter (davidp) June 28, 1996
|
||
|
//
|
||
|
// Revision History:
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "CluAdmX.h"
|
||
|
#include "ExtObj.h"
|
||
|
#include "Disks.h"
|
||
|
#include "DDxDDv.h"
|
||
|
#include "PropList.h"
|
||
|
#include "HelpData.h"
|
||
|
#include "ExcOper.h"
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#define new DEBUG_NEW
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CPhysDiskParamsPage property page
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
IMPLEMENT_DYNCREATE(CPhysDiskParamsPage, CBasePropertyPage)
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// Message Maps
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CPhysDiskParamsPage, CBasePropertyPage)
|
||
|
//{{AFX_MSG_MAP(CPhysDiskParamsPage)
|
||
|
ON_CBN_SELCHANGE(IDC_PP_DISKS_PARAMS_DISK, OnChangeDisk)
|
||
|
//}}AFX_MSG_MAP
|
||
|
// TODO: Modify the following lines to represent the data displayed on this page.
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::CPhysDiskParamsPage
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Default constructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CPhysDiskParamsPage::CPhysDiskParamsPage(void)
|
||
|
: CBasePropertyPage(g_aHelpIDs_IDD_PP_DISKS_PARAMETERS, g_aHelpIDs_IDD_WIZ_DISKS_PARAMETERS)
|
||
|
{
|
||
|
// TODO: Modify the following lines to represent the data displayed on this page.
|
||
|
//{{AFX_DATA_INIT(CPhysDiskParamsPage)
|
||
|
m_strDisk = _T("");
|
||
|
//}}AFX_DATA_INIT
|
||
|
|
||
|
m_dwSignature = 0;
|
||
|
|
||
|
m_pbAvailDiskInfo = NULL;
|
||
|
m_cbAvailDiskInfo = 0;
|
||
|
m_pbDiskInfo = NULL;
|
||
|
m_cbDiskInfo = 0;
|
||
|
|
||
|
// Setup the property array.
|
||
|
{
|
||
|
m_rgProps[epropSignature].Set(REGPARAM_DISKS_SIGNATURE, m_dwSignature, m_dwPrevSignature);
|
||
|
} // Setup the property array
|
||
|
|
||
|
m_iddPropertyPage = IDD_PP_DISKS_PARAMETERS;
|
||
|
m_iddWizardPage = IDD_WIZ_DISKS_PARAMETERS;
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::CPhysDiskParamsPage()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::~CPhysDiskParamsPage
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Destructor.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
CPhysDiskParamsPage::~CPhysDiskParamsPage(void)
|
||
|
{
|
||
|
delete [] m_pbAvailDiskInfo;
|
||
|
delete [] m_pbDiskInfo;
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::~CPhysDiskParamsPage()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::HrInit
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Initialize the page.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// peo [IN OUT] Pointer to the extension object.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// S_OK Page initialized successfully.
|
||
|
// hr Page failed to initialize.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
HRESULT CPhysDiskParamsPage::HrInit(IN OUT CExtObject * peo)
|
||
|
{
|
||
|
HRESULT _hr;
|
||
|
CWaitCursor _wc;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
// Call the base class method.
|
||
|
_hr = CBasePropertyPage::HrInit(peo);
|
||
|
if ( FAILED( _hr ) )
|
||
|
{
|
||
|
break;
|
||
|
} // if: error from base class method
|
||
|
|
||
|
// Collect available disk information.
|
||
|
BGetAvailableDisks();
|
||
|
|
||
|
// If creating a new resource, select the first disk.
|
||
|
// Otherwise, collect information about the selected disk.
|
||
|
if (BWizard())
|
||
|
{
|
||
|
CLUSPROP_BUFFER_HELPER buf;
|
||
|
|
||
|
buf.pb = m_pbAvailDiskInfo;
|
||
|
if (m_cbAvailDiskInfo > 0)
|
||
|
{
|
||
|
while (buf.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK)
|
||
|
{
|
||
|
if (BStringFromDiskInfo(buf, m_cbAvailDiskInfo, m_strDisk))
|
||
|
break;
|
||
|
ASSERT( (buf.pSyntax->dw == CLUSPROP_SYNTAX_ENDMARK)
|
||
|
|| (buf.pSyntax->dw == CLUSPROP_SYNTAX_DISK_SIGNATURE));
|
||
|
} // while: more entries in the list
|
||
|
} // if: there are available disks
|
||
|
} // if: creating a new resource
|
||
|
else
|
||
|
{
|
||
|
// Don't return false because that will prevent the page from showing up.
|
||
|
BGetDiskInfo();
|
||
|
|
||
|
// Get the current state of the resource.
|
||
|
m_crs = GetClusterResourceState(Peo()->PrdResData()->m_hresource, NULL, NULL, NULL, NULL );
|
||
|
} // else: viewing an existing resource
|
||
|
} while ( 0 );
|
||
|
|
||
|
return _hr;
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::HrInit()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::DoDataExchange
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Do data exchange between the dialog and the class.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// pDX [IN OUT] Data exchange object
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CPhysDiskParamsPage::DoDataExchange(CDataExchange * pDX)
|
||
|
{
|
||
|
if (!pDX->m_bSaveAndValidate || !BSaved())
|
||
|
{
|
||
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
|
||
|
// TODO: Modify the following lines to represent the data displayed on this page.
|
||
|
//{{AFX_DATA_MAP(CPhysDiskParamsPage)
|
||
|
DDX_Control(pDX, IDC_PP_DISKS_PARAMS_DISK, m_cboxDisk);
|
||
|
DDX_Text(pDX, IDC_PP_DISKS_PARAMS_DISK, m_strDisk);
|
||
|
//}}AFX_DATA_MAP
|
||
|
|
||
|
if (pDX->m_bSaveAndValidate)
|
||
|
{
|
||
|
if (!BBackPressed())
|
||
|
{
|
||
|
if (BWizard()
|
||
|
&& !( (m_strDisk.GetLength() == 0)
|
||
|
&& (m_crs == ClusterResourceOffline)))
|
||
|
{
|
||
|
DDV_RequiredText(pDX, IDC_PP_DISKS_PARAMS_DISK, IDC_PP_DISKS_PARAMS_DISK_LABEL, m_strDisk);
|
||
|
m_dwSignature = (DWORD)m_cboxDisk.GetItemData(m_cboxDisk.GetCurSel());
|
||
|
ASSERT(m_dwSignature != 0);
|
||
|
} // if: not offline with an empty disk string
|
||
|
} // if: Back button not pressed
|
||
|
} // if: saving data
|
||
|
} // if: not saving or haven't saved yet
|
||
|
|
||
|
CBasePropertyPage::DoDataExchange(pDX);
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::DoDataExchange()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::OnInitDialog
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler for the WM_INITDIALOG message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE We need the focus to be set for us.
|
||
|
// FALSE We already set the focus to the proper control.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CPhysDiskParamsPage::OnInitDialog(void)
|
||
|
{
|
||
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
|
||
|
CBasePropertyPage::OnInitDialog();
|
||
|
|
||
|
// Set the combobox as read-only if not creating a new resource.
|
||
|
m_cboxDisk.EnableWindow(BWizard());
|
||
|
|
||
|
// Fill the disks list.
|
||
|
FillList();
|
||
|
|
||
|
return TRUE; // return TRUE unless you set the focus to a control
|
||
|
// EXCEPTION: OCX Property Pages should return FALSE
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::OnInitDialog()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::OnSetActive
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler for the PSN_SETACTIVE message.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE Page successfully initialized.
|
||
|
// FALSE Page not initialized.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CPhysDiskParamsPage::OnSetActive(void)
|
||
|
{
|
||
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
|
||
|
// Enable/disable the Next/Finish button.
|
||
|
if (BWizard())
|
||
|
{
|
||
|
if (m_strDisk.GetLength() == 0)
|
||
|
EnableNext(FALSE);
|
||
|
else
|
||
|
EnableNext(TRUE);
|
||
|
} // if: enable/disable the Next button
|
||
|
|
||
|
return CBasePropertyPage::OnSetActive();
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::OnSetActive()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::BApplyChanges
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Apply changes made on the page.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE Page successfully applied.
|
||
|
// FALSE Error applying page.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CPhysDiskParamsPage::BApplyChanges(void)
|
||
|
{
|
||
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
|
||
|
CWaitCursor wc;
|
||
|
|
||
|
if (!( (m_strDisk.GetLength() == 0)
|
||
|
&& (m_crs == ClusterResourceOffline)))
|
||
|
{
|
||
|
// Call the base class method.
|
||
|
if (!CBasePropertyPage::BApplyChanges())
|
||
|
return FALSE;
|
||
|
|
||
|
// Reread the disk info and the available disks.
|
||
|
// Ignore errors because we can't do anything about it at this point anyway.
|
||
|
BGetAvailableDisks();
|
||
|
BGetDiskInfo();
|
||
|
|
||
|
// Refill the combobox.
|
||
|
FillList();
|
||
|
} // if: not offline with an empty disk string
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::BApplyChanges()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::OnChangeDisk
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Handler for the CBN_SELCHANGE message on the Disks combobox.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CPhysDiskParamsPage::OnChangeDisk(void)
|
||
|
{
|
||
|
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
|
|
||
|
OnChangeCtrl();
|
||
|
|
||
|
if (BWizard())
|
||
|
{
|
||
|
if (m_cboxDisk.GetWindowTextLength() == 0)
|
||
|
EnableNext(FALSE);
|
||
|
else
|
||
|
EnableNext(TRUE);
|
||
|
} // if: in a wizard
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::OnChangeDisk()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::BGetAvailableDisks
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Get the list of disks for this type of resource that can be assigned
|
||
|
// to a resource.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE The operation was successful.
|
||
|
// FALSE The operation failed.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CPhysDiskParamsPage::BGetAvailableDisks(void)
|
||
|
{
|
||
|
DWORD dwStatus = ERROR_SUCCESS;
|
||
|
DWORD cbDiskInfo = sizeof(CLUSPROP_DWORD)
|
||
|
+ sizeof(CLUSPROP_SCSI_ADDRESS)
|
||
|
+ sizeof(CLUSPROP_DISK_NUMBER)
|
||
|
+ sizeof(CLUSPROP_PARTITION_INFO)
|
||
|
+ sizeof(CLUSPROP_SYNTAX);
|
||
|
PBYTE pbDiskInfo = NULL;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
// Get disk info.
|
||
|
pbDiskInfo = new BYTE[cbDiskInfo];
|
||
|
dwStatus = ClusterResourceTypeControl(
|
||
|
Peo()->Hcluster(),
|
||
|
Peo()->PrdResData()->m_strResTypeName,
|
||
|
NULL,
|
||
|
CLUSCTL_RESOURCE_TYPE_STORAGE_GET_AVAILABLE_DISKS,
|
||
|
NULL,
|
||
|
0,
|
||
|
pbDiskInfo,
|
||
|
cbDiskInfo,
|
||
|
&cbDiskInfo
|
||
|
);
|
||
|
if (dwStatus == ERROR_MORE_DATA)
|
||
|
{
|
||
|
delete [] pbDiskInfo;
|
||
|
pbDiskInfo = new BYTE[cbDiskInfo];
|
||
|
dwStatus = ClusterResourceTypeControl(
|
||
|
Peo()->Hcluster(),
|
||
|
Peo()->PrdResData()->m_strResTypeName,
|
||
|
NULL,
|
||
|
CLUSCTL_RESOURCE_TYPE_STORAGE_GET_AVAILABLE_DISKS,
|
||
|
NULL,
|
||
|
0,
|
||
|
pbDiskInfo,
|
||
|
cbDiskInfo,
|
||
|
&cbDiskInfo
|
||
|
);
|
||
|
} // if: buffer too small
|
||
|
} // try
|
||
|
catch (CMemoryException * pme)
|
||
|
{
|
||
|
pme->Delete();
|
||
|
dwStatus = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
} // catch: CMemoryException
|
||
|
|
||
|
if (dwStatus != ERROR_SUCCESS)
|
||
|
{
|
||
|
CNTException nte(
|
||
|
dwStatus,
|
||
|
IDS_GET_AVAILABLE_DISKS_ERROR,
|
||
|
Peo()->PrdResData()->m_strResTypeName,
|
||
|
NULL,
|
||
|
FALSE /*bAutoDelete*/
|
||
|
);
|
||
|
delete [] pbDiskInfo;
|
||
|
nte.ReportError();
|
||
|
nte.Delete();
|
||
|
return FALSE;
|
||
|
} // if: error getting disk info
|
||
|
|
||
|
delete [] m_pbAvailDiskInfo;
|
||
|
m_pbAvailDiskInfo = pbDiskInfo;
|
||
|
m_cbAvailDiskInfo = cbDiskInfo;
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::BGetAvailableDisks()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::BGetDiskInfo
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Get information about the currently selected disk.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE The operation was successful.
|
||
|
// FALSE The operation failed.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CPhysDiskParamsPage::BGetDiskInfo(void)
|
||
|
{
|
||
|
DWORD dwStatus = ERROR_SUCCESS;
|
||
|
DWORD cbDiskInfo = sizeof(CLUSPROP_DWORD)
|
||
|
+ sizeof(CLUSPROP_SCSI_ADDRESS)
|
||
|
+ sizeof(CLUSPROP_DISK_NUMBER)
|
||
|
+ sizeof(CLUSPROP_PARTITION_INFO)
|
||
|
+ sizeof(CLUSPROP_SYNTAX);
|
||
|
PBYTE pbDiskInfo = NULL;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
// Get disk info.
|
||
|
pbDiskInfo = new BYTE[cbDiskInfo];
|
||
|
dwStatus = ClusterResourceControl(
|
||
|
Peo()->PrdResData()->m_hresource,
|
||
|
NULL,
|
||
|
CLUSCTL_RESOURCE_STORAGE_GET_DISK_INFO,
|
||
|
NULL,
|
||
|
0,
|
||
|
pbDiskInfo,
|
||
|
cbDiskInfo,
|
||
|
&cbDiskInfo
|
||
|
);
|
||
|
if (dwStatus == ERROR_MORE_DATA)
|
||
|
{
|
||
|
delete [] pbDiskInfo;
|
||
|
pbDiskInfo = new BYTE[cbDiskInfo];
|
||
|
dwStatus = ClusterResourceControl(
|
||
|
Peo()->PrdResData()->m_hresource,
|
||
|
NULL,
|
||
|
CLUSCTL_RESOURCE_STORAGE_GET_DISK_INFO,
|
||
|
NULL,
|
||
|
0,
|
||
|
pbDiskInfo,
|
||
|
cbDiskInfo,
|
||
|
&cbDiskInfo
|
||
|
);
|
||
|
} // if: buffer too small
|
||
|
} // try
|
||
|
catch (CMemoryException * pme)
|
||
|
{
|
||
|
pme->Delete();
|
||
|
dwStatus = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
} // catch: CMemoryException
|
||
|
|
||
|
if (dwStatus != ERROR_SUCCESS)
|
||
|
{
|
||
|
CNTException nte(
|
||
|
dwStatus,
|
||
|
IDS_GET_DISK_INFO_ERROR,
|
||
|
Peo()->PrdResData()->m_strName,
|
||
|
NULL,
|
||
|
FALSE /*bAutoDelete*/
|
||
|
);
|
||
|
delete [] pbDiskInfo;
|
||
|
nte.ReportError();
|
||
|
nte.Delete();
|
||
|
return FALSE;
|
||
|
} // if: error getting disk info
|
||
|
|
||
|
delete [] m_pbDiskInfo;
|
||
|
m_pbDiskInfo = pbDiskInfo;
|
||
|
m_cbDiskInfo = cbDiskInfo;
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::BGetDiskInfo()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::BStringFromDiskInfo
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Convert disk information to a string for display.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// rbuf [IN OUT] Buffer pointer.
|
||
|
// cbBuf [IN] Number of bytes in the buffer.
|
||
|
// rstr [OUT] String to fill.
|
||
|
// pdwSignature [OUT] Signature associated with the disk info being
|
||
|
// returned.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// TRUE A string was produced from disk info.
|
||
|
// FALSE No string could be produced.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL CPhysDiskParamsPage::BStringFromDiskInfo(
|
||
|
IN OUT CLUSPROP_BUFFER_HELPER & rbuf,
|
||
|
IN DWORD cbBuf,
|
||
|
OUT CString & rstr,
|
||
|
OUT DWORD * pdwSignature // = NULL
|
||
|
) const
|
||
|
{
|
||
|
CString strPartitionInfo;
|
||
|
DWORD dwSignature = 0;
|
||
|
DWORD cbData;
|
||
|
BOOL bDisplay;
|
||
|
|
||
|
ASSERT(cbBuf > 0);
|
||
|
ASSERT(rbuf.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK);
|
||
|
|
||
|
rstr = _T("");
|
||
|
|
||
|
if (rbuf.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK)
|
||
|
{
|
||
|
do
|
||
|
{
|
||
|
// Calculate the size of the value.
|
||
|
cbData = sizeof(*rbuf.pValue) + ALIGN_CLUSPROP(rbuf.pValue->cbLength);
|
||
|
ASSERT(cbData <= cbBuf);
|
||
|
|
||
|
// Parse the value.
|
||
|
if (rbuf.pSyntax->dw == CLUSPROP_SYNTAX_DISK_SIGNATURE)
|
||
|
{
|
||
|
// Save the signature.
|
||
|
dwSignature = rbuf.pDwordValue->dw;
|
||
|
ASSERT(dwSignature != 0);
|
||
|
} // if: signature
|
||
|
else if (rbuf.pSyntax->dw == CLUSPROP_SYNTAX_PARTITION_INFO)
|
||
|
{
|
||
|
// Add the partition to the string if it is a usable partition
|
||
|
// and hasn't been added already. If the resource is offline,
|
||
|
// don't check the usable flag.
|
||
|
bDisplay = ( rstr.Find(rbuf.pPartitionInfoValue->szDeviceName) == -1 );
|
||
|
if ( bDisplay && ( m_crs == ClusterResourceOnline ) )
|
||
|
{
|
||
|
bDisplay = (rbuf.pPartitionInfoValue->dwFlags & CLUSPROP_PIFLAG_USABLE) == CLUSPROP_PIFLAG_USABLE;
|
||
|
} // if: resource is online
|
||
|
if (bDisplay)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
strPartitionInfo.Format(
|
||
|
(rbuf.pPartitionInfoValue->szVolumeLabel[0] ? _T("%ls (%ls) ") : _T("%ls ")),
|
||
|
rbuf.pPartitionInfoValue->szDeviceName,
|
||
|
rbuf.pPartitionInfoValue->szVolumeLabel
|
||
|
);
|
||
|
rstr += strPartitionInfo;
|
||
|
if (pdwSignature != NULL)
|
||
|
{
|
||
|
_ASSERTE(dwSignature != 0);
|
||
|
*pdwSignature = dwSignature;
|
||
|
} // if: caller wants signature as well
|
||
|
} // try
|
||
|
catch (...)
|
||
|
{
|
||
|
// Ignore all errors because there is really nothing we can do.
|
||
|
// Displaying a message isn't really very useful.
|
||
|
} // catch: Anything
|
||
|
} // if: partition should be displayed
|
||
|
} // else if: partition info
|
||
|
|
||
|
// Advance the buffer pointer
|
||
|
rbuf.pb += cbData;
|
||
|
cbBuf -= cbData;
|
||
|
|
||
|
} while ( (rbuf.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK)
|
||
|
&& (rbuf.pSyntax->dw != CLUSPROP_SYNTAX_DISK_SIGNATURE));
|
||
|
} // if: not an endmark
|
||
|
|
||
|
return (rstr.GetLength() > 0);
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::BStringFromDiskInfo()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
//++
|
||
|
//
|
||
|
// CPhysDiskParamsPage::FillList
|
||
|
//
|
||
|
// Routine Description:
|
||
|
// Fill the list of disks.
|
||
|
//
|
||
|
// Arguments:
|
||
|
// None.
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None.
|
||
|
//
|
||
|
//--
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
void CPhysDiskParamsPage::FillList(void)
|
||
|
{
|
||
|
CString strDisk;
|
||
|
DWORD dwSignature;
|
||
|
int icbox;
|
||
|
|
||
|
// Clear the list first.
|
||
|
m_cboxDisk.ResetContent();
|
||
|
|
||
|
// Add the disk info first.
|
||
|
if (m_cbDiskInfo > 0)
|
||
|
{
|
||
|
CLUSPROP_BUFFER_HELPER buf;
|
||
|
|
||
|
buf.pb = m_pbDiskInfo;
|
||
|
if (BStringFromDiskInfo(buf, m_cbDiskInfo, m_strDisk, &dwSignature))
|
||
|
{
|
||
|
ASSERT(dwSignature != 0);
|
||
|
icbox = m_cboxDisk.AddString(m_strDisk);
|
||
|
m_cboxDisk.SetItemData(icbox, dwSignature);
|
||
|
} // if: disk info was found
|
||
|
} // if: there is disk info
|
||
|
|
||
|
// Now add the available disk info.
|
||
|
if (m_cbAvailDiskInfo > 0)
|
||
|
{
|
||
|
CString strDisk;
|
||
|
CLUSPROP_BUFFER_HELPER buf;
|
||
|
|
||
|
buf.pb = m_pbAvailDiskInfo;
|
||
|
while (buf.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK)
|
||
|
{
|
||
|
if (BStringFromDiskInfo(buf, m_cbAvailDiskInfo, strDisk, &dwSignature))
|
||
|
{
|
||
|
ASSERT(dwSignature != 0);
|
||
|
icbox = m_cboxDisk.AddString(strDisk);
|
||
|
m_cboxDisk.SetItemData(icbox, dwSignature);
|
||
|
} // if: disk info was found
|
||
|
} // while: more entries in the list
|
||
|
} // if: there is available disk info
|
||
|
|
||
|
// Now select an item in the list.
|
||
|
if (m_strDisk.GetLength() > 0)
|
||
|
{
|
||
|
int nIndex;
|
||
|
|
||
|
nIndex = m_cboxDisk.FindStringExact(-1, m_strDisk);
|
||
|
m_cboxDisk.SetCurSel(nIndex);
|
||
|
} // if: there is a selected item
|
||
|
|
||
|
} //*** CPhysDiskParamsPage::FillList()
|