1050 lines
23 KiB
C++
1050 lines
23 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1999 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// ClusDisk.cpp
|
|
//
|
|
// Description:
|
|
// Implementation of the cluster disk class for the MSCLUS
|
|
// automation classes.
|
|
//
|
|
// Author:
|
|
// Galen Barbee (galenb) 11-Feb-1999
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Notes:
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
#include "stdafx.h"
|
|
|
|
#if CLUSAPI_VERSION >= 0x0500
|
|
#include <PropList.h>
|
|
#else
|
|
#include "PropList.h"
|
|
#endif // CLUSAPI_VERSION >= 0x0500
|
|
|
|
#include "ClusDisk.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Global variables
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
static const IID * iidCClusDisk[] =
|
|
{
|
|
&IID_ISClusDisk
|
|
};
|
|
|
|
static const IID * iidCClusDisks[] =
|
|
{
|
|
&IID_ISClusDisks
|
|
};
|
|
|
|
static const IID * iidCClusScsiAddress[] =
|
|
{
|
|
&IID_ISClusScsiAddress
|
|
};
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusDisk class
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisk::CClusDisk
|
|
//
|
|
// Description:
|
|
// Constructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CClusDisk::CClusDisk( void )
|
|
{
|
|
m_pPartitions = NULL;
|
|
m_dwSignature = 0;
|
|
m_dwDiskNumber = 0;
|
|
m_piids = (const IID *) iidCClusDisk;
|
|
m_piidsSize = ARRAYSIZE( iidCClusDisk );
|
|
|
|
} //*** CClusDisk::CClusDisk()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisk::~CClusDisk
|
|
//
|
|
// Description:
|
|
// Destructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CClusDisk::~CClusDisk( void )
|
|
{
|
|
if ( m_pPartitions != NULL )
|
|
{
|
|
m_pPartitions->Release();
|
|
} // if:
|
|
|
|
} //*** CClusDisk::~CClusDisk()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisk::Create
|
|
//
|
|
// Description:
|
|
// Finish creating this object. This method get the value list from
|
|
// the passed in physical disk resource handle.
|
|
//
|
|
// Arguments:
|
|
// hResource [IN] - Handle to the physical disk resource.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or Win32 error wrapped in HRESULT.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CClusDisk::Create( IN HRESOURCE hResource )
|
|
{
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
DWORD _sc = ERROR_SUCCESS;
|
|
CClusPropValueList _cpvl;
|
|
|
|
_sc = _cpvl.ScGetResourceValueList( hResource, CLUSCTL_RESOURCE_STORAGE_GET_DISK_INFO );
|
|
_hr = HRESULT_FROM_WIN32( _sc );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
_sc = _cpvl.ScMoveToFirstValue();
|
|
_hr = HRESULT_FROM_WIN32( _sc );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
CLUSPROP_BUFFER_HELPER _cbhValue = { NULL };
|
|
CComObject< CClusPartitions > * pPartitions = NULL;
|
|
|
|
if ( m_pPartitions != NULL )
|
|
{
|
|
m_pPartitions->Release();
|
|
m_pPartitions = NULL;
|
|
} // if: clean up any old partitions collection
|
|
|
|
_hr = CComObject< CClusPartitions >::CreateInstance( &pPartitions );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
CSmartPtr< CComObject< CClusPartitions > > ptrPartitions( pPartitions );
|
|
|
|
m_pPartitions = ptrPartitions;
|
|
ptrPartitions->AddRef();
|
|
|
|
do
|
|
{
|
|
_cbhValue = _cpvl;
|
|
|
|
switch ( _cbhValue.pSyntax->dw )
|
|
{
|
|
case CLUSPROP_SYNTAX_PARTITION_INFO :
|
|
{
|
|
_hr = ptrPartitions->HrCreateItem( _cbhValue.pPartitionInfoValue );
|
|
break;
|
|
} // case: CLUSPROP_SYNTAX_PARTITION_INFO
|
|
|
|
case CLUSPROP_SYNTAX_DISK_SIGNATURE :
|
|
{
|
|
m_dwSignature = _cbhValue.pDiskSignatureValue->dw;
|
|
break;
|
|
} // case: CLUSPROP_SYNTAX_DISK_SIGNATURE
|
|
|
|
case CLUSPROP_SYNTAX_SCSI_ADDRESS :
|
|
{
|
|
m_csaScsiAddress.dw = _cbhValue.pScsiAddressValue->dw;
|
|
break;
|
|
} // case: CLUSPROP_SYNTAX_SCSI_ADDRESS
|
|
|
|
case CLUSPROP_SYNTAX_DISK_NUMBER :
|
|
{
|
|
m_dwDiskNumber = _cbhValue.pDiskNumberValue->dw;
|
|
break;
|
|
} // case: CLUSPROP_SYNTAX_DISK_NUMBER
|
|
|
|
} // switch:
|
|
|
|
//
|
|
// Move to the next value.
|
|
//
|
|
_sc = _cpvl.ScMoveToNextValue();
|
|
if ( _sc == ERROR_NO_MORE_ITEMS )
|
|
{
|
|
_hr = S_OK;
|
|
break;
|
|
} // if: error occurred moving to the next value
|
|
|
|
_hr = HRESULT_FROM_WIN32( _sc );
|
|
|
|
} while ( SUCCEEDED( _hr ) ); // do-while: there are no errors
|
|
} // if: created the partition collection
|
|
} // if: move to first value ok
|
|
} // if: get the value list ok
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisk::Create()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisk::HrCreate
|
|
//
|
|
// Description:
|
|
// Finish creating this object. This method parses a passed in value
|
|
// list to get the values for the physical disk object.
|
|
//
|
|
// Arguments:
|
|
// rcpvl [IN OUT] - Value list to parse.
|
|
// pbEndFound [OUT] - Did find the end of the value list?
|
|
//
|
|
// Return Value:
|
|
// S_OK, or Win32 error code wrapped in an HRESULT.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CClusDisk::HrCreate(
|
|
IN OUT CClusPropValueList & rcpvl,
|
|
OUT BOOL * pbEndFound
|
|
)
|
|
{
|
|
DWORD _sc = ERROR_SUCCESS;
|
|
CLUSPROP_BUFFER_HELPER _cbhValue = { NULL };
|
|
CComObject< CClusPartitions > * pPartitions = NULL;
|
|
HRESULT _hr = S_FALSE;
|
|
|
|
if ( m_pPartitions != NULL )
|
|
{
|
|
m_pPartitions->Release();
|
|
m_pPartitions = NULL;
|
|
} // if: clean up any old partitions collection
|
|
|
|
_hr = CComObject< CClusPartitions >::CreateInstance( &pPartitions );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
CSmartPtr< CComObject< CClusPartitions > > ptrPartitions( pPartitions );
|
|
|
|
m_pPartitions = ptrPartitions;
|
|
ptrPartitions->AddRef();
|
|
|
|
_cbhValue = rcpvl;
|
|
|
|
do
|
|
{
|
|
switch ( _cbhValue.pSyntax->dw )
|
|
{
|
|
case CLUSPROP_SYNTAX_DISK_SIGNATURE :
|
|
{
|
|
m_dwSignature = _cbhValue.pDiskSignatureValue->dw;
|
|
break;
|
|
} // case: CLUSPROP_SYNTAX_DISK_SIGNATURE
|
|
|
|
case CLUSPROP_SYNTAX_PARTITION_INFO :
|
|
{
|
|
_hr = ptrPartitions->HrCreateItem( _cbhValue.pPartitionInfoValue );
|
|
break;
|
|
} // case: CLUSPROP_SYNTAX_PARTITION_INFO
|
|
|
|
case CLUSPROP_SYNTAX_SCSI_ADDRESS :
|
|
{
|
|
m_csaScsiAddress.dw = _cbhValue.pScsiAddressValue->dw;
|
|
break;
|
|
} // case: CLUSPROP_SYNTAX_SCSI_ADDRESS
|
|
|
|
case CLUSPROP_SYNTAX_DISK_NUMBER :
|
|
{
|
|
m_dwDiskNumber = _cbhValue.pDiskNumberValue->dw;
|
|
break;
|
|
} // case: CLUSPROP_SYNTAX_DISK_NUMBER
|
|
|
|
} // switch:
|
|
|
|
//
|
|
// Move to the next value.
|
|
//
|
|
_sc = rcpvl.ScMoveToNextValue();
|
|
if ( _sc == ERROR_NO_MORE_ITEMS )
|
|
{
|
|
_hr = S_OK;
|
|
*pbEndFound = TRUE;
|
|
break;
|
|
} // if: error occurred moving to the next value
|
|
|
|
_cbhValue = rcpvl;
|
|
|
|
if ( _cbhValue.pSyntax->dw == CLUSPROP_SYNTAX_DISK_SIGNATURE )
|
|
{
|
|
_hr = HRESULT_FROM_WIN32( _sc );
|
|
break;
|
|
} // if: exit if another signature is found before the end of the list is seen
|
|
|
|
_hr = HRESULT_FROM_WIN32( _sc );
|
|
|
|
} while ( SUCCEEDED( _hr ) ); // do-while: there are no errors
|
|
|
|
} // if: the patitions collection can be created
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisk::HrCreate()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisk::get_Signature
|
|
//
|
|
// Description:
|
|
// Get the disk signature.
|
|
//
|
|
// Arguments:
|
|
// plSignature [OUT] - catches the signature.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or E_POINTER
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusDisk::get_Signature( OUT long * plSignature )
|
|
{
|
|
//ASSERT( plSignature != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( plSignature != NULL )
|
|
{
|
|
*plSignature = static_cast< long >( m_dwSignature );
|
|
_hr = S_OK;
|
|
}
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisk::get_Signature()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisk::get_ScsiAddress
|
|
//
|
|
// Description:
|
|
// Get the disk's SCSI address.
|
|
//
|
|
// Arguments:
|
|
// ppScsiAddress [OUT] - catches the SCSI address..
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or E_POINTER
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusDisk::get_ScsiAddress(
|
|
OUT ISClusScsiAddress ** ppScsiAddress
|
|
)
|
|
{
|
|
//ASSERT( ppScsiAddress != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( ppScsiAddress != NULL )
|
|
{
|
|
CComObject< CClusScsiAddress > * _pScsiAddress = NULL;
|
|
|
|
_hr = CComObject< CClusScsiAddress >::CreateInstance( &_pScsiAddress );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
CSmartPtr< CComObject< CClusScsiAddress > > _ptrScsiAddress( _pScsiAddress );
|
|
|
|
_hr = _ptrScsiAddress->Create( m_csaScsiAddress );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
_hr = _ptrScsiAddress->QueryInterface( IID_ISClusScsiAddress, (void **) ppScsiAddress );
|
|
} // if:
|
|
} // if:
|
|
} // if:
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisk::get_ScsiAddress()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisk::get_DiskNumber
|
|
//
|
|
// Description:
|
|
// Get the disk number.
|
|
//
|
|
// Arguments:
|
|
// plDiskNumber [OUT] - catches the disk number.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or E_POINTER
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusDisk::get_DiskNumber( OUT long * plDiskNumber )
|
|
{
|
|
//ASSERT( plDiskNumber != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( plDiskNumber != NULL )
|
|
{
|
|
*plDiskNumber = static_cast< long >( m_dwDiskNumber );
|
|
_hr = S_OK;
|
|
}
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisk::get_DiskNumber()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisk::get_Partitions
|
|
//
|
|
// Description:
|
|
// Get the disk partitions.
|
|
//
|
|
// Arguments:
|
|
// ppPartitions [OUT] - catches the partitions collection.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or E_POINTER
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusDisk::get_Partitions( OUT ISClusPartitions ** ppPartitions )
|
|
{
|
|
//ASSERT( ppPartitions != NULL );
|
|
ASSERT( m_pPartitions != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( ppPartitions != NULL )
|
|
{
|
|
if ( ppPartitions != NULL )
|
|
{
|
|
_hr = m_pPartitions->QueryInterface( IID_ISClusPartitions, (void **) ppPartitions );
|
|
} // if:
|
|
} // if:
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisk::get_Partitions()
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusDisks class
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::CClusDisks
|
|
//
|
|
// Description:
|
|
// Constructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CClusDisks::CClusDisks( void )
|
|
{
|
|
m_pClusRefObject = NULL;
|
|
m_piids = (const IID *) iidCClusDisks;
|
|
m_piidsSize = ARRAYSIZE( iidCClusDisks );
|
|
|
|
} //*** CClusDisks::CClusDisks()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::~CClusDisks
|
|
//
|
|
// Description:
|
|
// Destructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CClusDisks::~CClusDisks( void )
|
|
{
|
|
Clear();
|
|
|
|
if ( m_pClusRefObject != NULL )
|
|
{
|
|
m_pClusRefObject->Release();
|
|
m_pClusRefObject = NULL;
|
|
} // if: do we have a pointer to the cluster handle wrapper?
|
|
|
|
} //*** CClusDisks::~CClusDisks()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::Create
|
|
//
|
|
// Description:
|
|
// Complete the heavy weight construction,
|
|
//
|
|
// Arguments:
|
|
// rpvl [IN] - Property value list.
|
|
//
|
|
// Return Value:
|
|
// E_NOTIMPL
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CClusDisks::Create( IN const CClusPropValueList &rpvl )
|
|
{
|
|
HRESULT _hr = E_NOTIMPL;
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisks::Create()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::GetIndex
|
|
//
|
|
// Description:
|
|
// Convert the passed in 1 based index into a 0 based index.
|
|
//
|
|
// Arguments:
|
|
// varIndex [IN] - holds the 1 based index.
|
|
// pnIndex [OUT] - catches the 0 based index.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, E_POINTER, or E_INVALIDARG if out of range.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CClusDisks::GetIndex( IN VARIANT varIndex, OUT UINT * pnIndex )
|
|
{
|
|
//ASSERT( pnIndex != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( pnIndex != NULL )
|
|
{
|
|
CComVariant v;
|
|
UINT nIndex = 0;
|
|
|
|
*pnIndex = 0;
|
|
|
|
v.Copy( &varIndex );
|
|
|
|
// Check to see if the index is a number.
|
|
_hr = v.ChangeType( VT_I4 );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
nIndex = v.lVal;
|
|
nIndex--; // Adjust index to be 0 relative instead of 1 relative
|
|
|
|
if ( nIndex < m_dvDisks.size() )
|
|
{
|
|
*pnIndex = nIndex;
|
|
}
|
|
else
|
|
{
|
|
_hr = E_INVALIDARG;
|
|
}
|
|
}
|
|
}
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisks::GetIndex()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::get_Count
|
|
//
|
|
// Description:
|
|
// Get the count of objects in the collection.
|
|
//
|
|
// Arguments:
|
|
// plCount [OUT] - Catches the count.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful or E_POINTER.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusDisks::get_Count( OUT long * plCount )
|
|
{
|
|
//ASSERT( plCount != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( plCount != NULL )
|
|
{
|
|
*plCount = m_dvDisks.size();
|
|
_hr = S_OK;
|
|
}
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisks::get_Count()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::Clear
|
|
//
|
|
// Description:
|
|
// Empty the vector of disks.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void CClusDisks::Clear( void )
|
|
{
|
|
::ReleaseAndEmptyCollection< DiskVector, CComObject< CClusDisk > >( m_dvDisks );
|
|
|
|
} //*** CClusDisks::Clear()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::get_Item
|
|
//
|
|
// Description:
|
|
// Get the item (disk) at the passed in index.
|
|
//
|
|
// Arguments:
|
|
// varIndex [IN] - Contains the index requested.
|
|
// ppbstrRegistryKey [OUT] - Catches the key.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, E_POINTER, or other HRESULT error.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusDisks::get_Item(
|
|
IN VARIANT varIndex,
|
|
OUT ISClusDisk ** ppDisk
|
|
)
|
|
{
|
|
//ASSERT( ppDisk != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( ppDisk != NULL )
|
|
{
|
|
CComObject< CClusDisk > * pDisk = NULL;
|
|
|
|
// Zero the out param
|
|
*ppDisk = NULL;
|
|
|
|
UINT nIndex = 0;
|
|
|
|
_hr = GetIndex( varIndex, &nIndex );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
pDisk = m_dvDisks[ nIndex ];
|
|
_hr = pDisk->QueryInterface( IID_ISClusDisk, (void **) ppDisk );
|
|
}
|
|
}
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisks::get_Item()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::get__NewEnum
|
|
//
|
|
// Description:
|
|
// Create and return a new enumeration for this collection.
|
|
//
|
|
// Arguments:
|
|
// ppunk [OUT] - Catches the new enumeration.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, E_POINTER, or other HRESULT error.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusDisks::get__NewEnum( OUT IUnknown ** ppunk )
|
|
{
|
|
return ::HrNewIDispatchEnum< DiskVector, CComObject< CClusDisk > >( ppunk, m_dvDisks );
|
|
|
|
} //*** CClusDisks::get__NewEnum()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::Create
|
|
//
|
|
// Description:
|
|
// Finish creating the object by doing things that cannot be done in
|
|
// a light weight constructor.
|
|
//
|
|
// Arguments:
|
|
// pClusRefObject [IN] - Wraps the cluster handle.
|
|
// bstrResTypeName [IN] - The resource type this collection is for.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or E_POINTER if not.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CClusDisks::Create(
|
|
IN ISClusRefObject * pClusRefObject,
|
|
IN BSTR bstrResTypeName
|
|
)
|
|
{
|
|
ASSERT( pClusRefObject != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( pClusRefObject != NULL )
|
|
{
|
|
m_pClusRefObject = pClusRefObject;
|
|
m_pClusRefObject->AddRef();
|
|
m_bstrResTypeName = bstrResTypeName;
|
|
_hr = S_OK;
|
|
}
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisks::Create()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::Refresh
|
|
//
|
|
// Description:
|
|
// Load the collection from the cluster database.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or Win32 error as HRESULT if not.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusDisks::Refresh( void )
|
|
{
|
|
HRESULT _hr = S_OK;
|
|
DWORD _sc = ERROR_SUCCESS;
|
|
HCLUSTER _hCluster = NULL;
|
|
BOOL _bEndFound = FALSE;
|
|
|
|
_hr = m_pClusRefObject->get_Handle( (ULONG_PTR *) &_hCluster );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
CClusPropValueList _cpvl;
|
|
DWORD _sc = ERROR_SUCCESS;
|
|
|
|
_sc = _cpvl.ScGetResourceTypeValueList(
|
|
_hCluster,
|
|
m_bstrResTypeName,
|
|
CLUSCTL_RESOURCE_TYPE_STORAGE_GET_AVAILABLE_DISKS
|
|
);
|
|
_hr = HRESULT_FROM_WIN32( _sc );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
Clear();
|
|
|
|
_sc = _cpvl.ScMoveToFirstValue();
|
|
_hr = HRESULT_FROM_WIN32( _sc );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
CLUSPROP_BUFFER_HELPER _cbhValue = { NULL };
|
|
|
|
do
|
|
{
|
|
_cbhValue = _cpvl;
|
|
|
|
if ( _cbhValue.pSyntax->dw == CLUSPROP_SYNTAX_DISK_SIGNATURE )
|
|
{
|
|
_hr = HrCreateDisk( _cpvl, &_bEndFound );
|
|
} // if: value list MUST start with signature!
|
|
|
|
} while ( ! _bEndFound ); // do-while: there are values in the list
|
|
|
|
} // if: we moved to the first value
|
|
} // if: the value list of available disks was retrieved
|
|
} // if: we have a cluster handle
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisks::Refresh()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusDisks::HrCreateDisk
|
|
//
|
|
// Description:
|
|
// Create a CClusDisk object from the passed in value list and add it
|
|
// to the collection. This method assumes that the value list's curent
|
|
// value is the disk signature.
|
|
//
|
|
// Arguments:
|
|
// rcpvl [IN OUT] - The value list to parse.
|
|
// pbEndFound [IN] - Catches the end of list state.
|
|
//
|
|
// Return Value:
|
|
// S_OK, if successful, Win32 error code wrapped in an HRESULT.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CClusDisks::HrCreateDisk(
|
|
IN OUT CClusPropValueList & rcpvl,
|
|
OUT BOOL * pbEndFound
|
|
)
|
|
{
|
|
CComObject< CClusDisk > * _pDisk = NULL;
|
|
HRESULT _hr = S_FALSE;
|
|
|
|
_hr = CComObject< CClusDisk >::CreateInstance( &_pDisk );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
CSmartPtr< CComObject< CClusDisk > > _ptrDisk( _pDisk );
|
|
|
|
_hr = _ptrDisk->HrCreate( rcpvl, pbEndFound );
|
|
if ( SUCCEEDED( _hr ) )
|
|
{
|
|
m_dvDisks.insert( m_dvDisks.end(), _pDisk );
|
|
_ptrDisk->AddRef();
|
|
} // if:
|
|
} // if:
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusDisks::HrCreateDisk()
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CClusScsiAddress class
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusScsiAddress::CClusScsiAddress
|
|
//
|
|
// Description:
|
|
// Constructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// None.
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CClusScsiAddress::CClusScsiAddress( void )
|
|
{
|
|
m_piids = (const IID *) iidCClusScsiAddress;
|
|
m_piidsSize = ARRAYSIZE( iidCClusScsiAddress );
|
|
|
|
} //*** CClusScsiAddress::CClusScsiAddress()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusScsiAddress::Create
|
|
//
|
|
// Description:
|
|
// Finish creating this object.
|
|
//
|
|
// Arguments:
|
|
// pcpi [IN] - points to the CLUS_PARTITION_INFO struct.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or E_POINTER
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
HRESULT CClusScsiAddress::Create( IN const CLUS_SCSI_ADDRESS & rcsa )
|
|
{
|
|
m_csa = rcsa;
|
|
|
|
return S_OK;
|
|
|
|
} //*** CClusScsiAddress::Create()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusScsiAddress::get_PortNumber
|
|
//
|
|
// Description:
|
|
// Get the disk's port number.
|
|
//
|
|
// Arguments:
|
|
// pvarPortNumber [OUT] - catches the port number.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or E_POINTER
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusScsiAddress::get_PortNumber( OUT VARIANT * pvarPortNumber )
|
|
{
|
|
//ASSERT( pvarPortNumber != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( pvarPortNumber != NULL )
|
|
{
|
|
pvarPortNumber->bVal = m_csa.PortNumber;
|
|
pvarPortNumber->vt = VT_UI1;
|
|
_hr = S_OK;
|
|
}
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusScsiAddress::get_PortNumber()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusScsiAddress::get_PathId
|
|
//
|
|
// Description:
|
|
// Get the disk's path id.
|
|
//
|
|
// Arguments:
|
|
// pvarPathId [OUT] - catches the path id.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or E_POINTER
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusScsiAddress::get_PathId( OUT VARIANT * pvarPathId )
|
|
{
|
|
//ASSERT( pvarPathId != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( pvarPathId != NULL )
|
|
{
|
|
pvarPathId->bVal = m_csa.PathId;
|
|
pvarPathId->vt = VT_UI1;
|
|
_hr = S_OK;
|
|
}
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusScsiAddress::get_PathId()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusScsiAddress::get_TargetId
|
|
//
|
|
// Description:
|
|
// Get the disk's target id.
|
|
//
|
|
// Arguments:
|
|
// pvarTargetId [OUT] - catches the target id.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or E_POINTER
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusScsiAddress::get_TargetId( OUT VARIANT * pvarTargetId )
|
|
{
|
|
//ASSERT( pvarTargetId != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( pvarTargetId != NULL )
|
|
{
|
|
pvarTargetId->bVal = m_csa.TargetId;
|
|
pvarTargetId->vt = VT_UI1;
|
|
_hr = S_OK;
|
|
}
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusScsiAddress::get_TargetId()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CClusScsiAddress::get_Lun
|
|
//
|
|
// Description:
|
|
// Get the disk's Lun.
|
|
//
|
|
// Arguments:
|
|
// pvarLun [OUT] - catches the Lun.
|
|
//
|
|
// Return Value:
|
|
// S_OK if successful, or E_POINTER
|
|
//
|
|
//--
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP CClusScsiAddress::get_Lun( OUT VARIANT * pvarLun )
|
|
{
|
|
//ASSERT( pvarLun != NULL );
|
|
|
|
HRESULT _hr = E_POINTER;
|
|
|
|
if ( pvarLun != NULL )
|
|
{
|
|
pvarLun->bVal = m_csa.Lun;
|
|
pvarLun->vt = VT_UI1;
|
|
_hr = S_OK;
|
|
}
|
|
|
|
return _hr;
|
|
|
|
} //*** CClusScsiAddress::get_Lun()
|