windows-nt/Source/XPSP1/NT/base/fs/hsm/gui/hsmadmin/rsadutil.cpp
2020-09-26 16:20:57 +08:00

1916 lines
51 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
© 1998 Seagate Software, Inc. All rights reserved.
Module Name:
RsAdUtil.cpp
Abstract:
Utility functions for GUI - for us in HSMADMIN files only
Author:
Art Bragg [abragg] 04-Mar-1997
Revision History:
Chris Timmes [ctimmes] 21-Nov-1997
- modified RsCreateAndRunFsaJob(), RsCreateAndRunMediaCopyJob(),and
RsCreateAndRunMediaRecreateJob() to use the new Engine method CreateTask(), which
creates a task in the NT Task Scheduler. Change required due to changing Sakkara
to run under LocalSystem account.
--*/
#include "stdafx.h"
HRESULT
RsGetStatusString (
DWORD serviceStatus,
HRESULT hrSetup,
CString& sStatus
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
switch( serviceStatus ) {
case SERVICE_STOPPED:
sStatus.LoadString(IDS_SERVICE_STATUS_STOPPED);
break;
case SERVICE_START_PENDING:
sStatus.LoadString(IDS_SERVICE_STATUS_START_PENDING);
break;
case SERVICE_STOP_PENDING:
sStatus.LoadString(IDS_SERVICE_STATUS_STOP_PENDING);
break;
case SERVICE_RUNNING:
//
// See if we are setup yet
//
if( S_FALSE == hrSetup ) {
sStatus.LoadString(IDS_SERVICE_STATUS_NOT_SETUP);
} else {
sStatus.LoadString(IDS_SERVICE_STATUS_RUNNING);
}
break;
case SERVICE_CONTINUE_PENDING:
sStatus.LoadString(IDS_SERVICE_STATUS_CONTINUE_PENDING);
break;
case SERVICE_PAUSE_PENDING:
sStatus.LoadString(IDS_SERVICE_STATUS_PAUSE_PENDING);
break;
case SERVICE_PAUSED:
sStatus.LoadString(IDS_SERVICE_STATUS_PAUSED);
break;
}
return S_OK;
}
WCHAR *
RsNotifyEventAsString (
IN MMC_NOTIFY_TYPE event
)
/*++
Routine Description:
For debug purposes, converts the event type into a UNICODE string.
Arguments:
event - The event type
Return Value:
String representing notify code - not I18N'd.
--*/
{
#define CASE_EVENT(x) case x: return TEXT(#x); break;
switch( event )
{
CASE_EVENT( MMCN_ACTIVATE )
CASE_EVENT( MMCN_ADD_IMAGES )
CASE_EVENT( MMCN_BTN_CLICK )
CASE_EVENT( MMCN_CLICK )
CASE_EVENT( MMCN_COLUMN_CLICK )
CASE_EVENT( MMCN_CONTEXTMENU )
CASE_EVENT( MMCN_CUTORMOVE )
CASE_EVENT( MMCN_DBLCLICK )
CASE_EVENT( MMCN_DELETE )
CASE_EVENT( MMCN_DESELECT_ALL )
CASE_EVENT( MMCN_EXPAND )
CASE_EVENT( MMCN_HELP )
CASE_EVENT( MMCN_MENU_BTNCLICK )
CASE_EVENT( MMCN_MINIMIZED )
CASE_EVENT( MMCN_PASTE )
CASE_EVENT( MMCN_PROPERTY_CHANGE )
CASE_EVENT( MMCN_QUERY_PASTE )
CASE_EVENT( MMCN_REFRESH )
CASE_EVENT( MMCN_REMOVE_CHILDREN )
CASE_EVENT( MMCN_RENAME )
CASE_EVENT( MMCN_SELECT )
CASE_EVENT( MMCN_SHOW )
CASE_EVENT( MMCN_VIEW_CHANGE )
CASE_EVENT( MMCN_SNAPINHELP )
CASE_EVENT( MMCN_CONTEXTHELP )
CASE_EVENT( MMCN_INITOCX )
CASE_EVENT( MMCN_FILTER_CHANGE )
CASE_EVENT( MMCN_FILTERBTN_CLICK )
CASE_EVENT( MMCN_RESTORE_VIEW )
CASE_EVENT( MMCN_PRINT )
CASE_EVENT( MMCN_PRELOAD )
CASE_EVENT( MMCN_LISTPAD )
CASE_EVENT( MMCN_EXPANDSYNC )
default:
static WCHAR buf[32];
swprintf( buf, L"Unknown Event[0x%p]", event );
return( buf );
}
}
WCHAR *
RsClipFormatAsString (
IN CLIPFORMAT cf
)
/*++
Routine Description:
For debug purposes, converts the event type into a UNICODE string.
Arguments:
event - The event type
Return Value:
String representing notify code - not I18N'd.
--*/
{
static WCHAR buf[128];
GetClipboardFormatName( cf, buf, 128 );
return( buf );
}
HRESULT
RsIsRemoteStorageSetup(
void
)
/*++
Routine Description:
Reports back if Remote Storage has been set up on this machine.
Arguments:
none.
Return Value:
S_OK if setup
S_FALSE if not
--*/
{
WsbTraceIn( L"RsIsRemoteStorageSetup", L"" );
HRESULT hr = S_FALSE;
try {
//
// First, see if service is registered
//
CWsbStringPtr hsmName;
WsbTrace( L"Checking if service is registered\n" );
WsbAffirmHr( WsbGetServiceInfo( APPID_RemoteStorageEngine, &hsmName, 0 ) );
//
// Second, contact the engine. this will start the service if it
// is not already started.
//
CWsbStringPtr computerName;
WsbAffirmHr( WsbGetComputerName( computerName ) );
CComPtr<IHsmServer> pHsm;
WsbTrace( L"Contacting Engine\n" );
WsbAffirmHr( HsmConnectFromName( HSMCONN_TYPE_HSM, computerName, IID_IHsmServer, (void**)&pHsm ) );
//
// Third, see if it has a storage pool ID
//
hr = RsIsRemoteStorageSetupEx( pHsm );
} WsbCatch( hr );
WsbTraceOut( L"RsIsRemoteStorageSetup", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
void
RsReportError( HRESULT hrToReport, int textId, ... )
/*++
Routine Description:
Reports an error to the user.
Arguments:
hrToReport - the hr that was thrown
textId - Resource Id of context of the error
... - Substitution arguments for textId
Return Value:
none
--*/
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
//
// Make sure we don't report S_OK, S_FALSE
//
if( FAILED( hrToReport ) ) {
CString errorText;
CString formatString;
//
// Substitute in the text context string
//
va_list list;
va_start( list, textId );
formatString.LoadString( textId );
LPTSTR p;
p = errorText.GetBuffer( 1024 );
vswprintf( p, (LPCTSTR) formatString, list );
errorText.ReleaseBuffer();
va_end( list );
CWsbStringPtr hrText;
CString msgText;
CString headerText;
//
// Put together the complete text
//
hrText = WsbHrAsString( hrToReport );
headerText.LoadString( IDS_ERROR_HEADER );
msgText = headerText + L"\n\r\n\r" + errorText + L"\n\r\n\r" + hrText;
//
// Show the message
//
AfxMessageBox( msgText, RS_MB_ERROR );
}
}
HRESULT
RsIsRemoteStorageSetupEx(
IHsmServer * pHsmServer
)
/*++
Routine Description:
Reports back if Remote Storage has been set up on this machine.
Arguments:
none.
Return Value:
S_OK if setup
S_FALSE if not
--*/
{
WsbTraceIn( L"RsIsRemoteStorageSetupEx", L"" );
HRESULT hr = S_FALSE;
try {
//
// If it has a Media Set ID, it's set up.
//
GUID guid;
CWsbBstrPtr poolName;
CComPtr<IHsmStoragePool> pPool;
WsbAffirmHr( RsGetStoragePool( pHsmServer, &pPool ) );
WsbAffirmHr( pPool->GetMediaSet( &guid, &poolName ) );
if( ! IsEqualGUID( guid, GUID_NULL ) ) {
hr = S_OK;
}
} WsbCatch( hr );
WsbTraceOut( L"RsIsRemoteStorageSetupEx", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
RsIsSupportedMediaAvailable(
void
)
/*++
Routine Description:
Checks to see if NTMS is setup, and setup with useable media.
Arguments:
none.
Return Value:
TRUE if NTMS is configured with supported media
FALSE if NTMS is not configured with supported media
--*/
{
WsbTraceIn( L"RsIsSupportedMediaAvailable", L"" );
HRESULT hr = S_FALSE;
try {
//
// First, contact the RMS engine and ask it if
// RMS has supported media.
//
CWsbStringPtr computerName;
WsbAffirmHr( WsbGetComputerName( computerName ) );
CComPtr<IHsmServer> pHsm;
CComPtr<IRmsServer> pRms;
WsbTrace( L"Contacting HSM Server to get RMS\n" );
WsbAffirmHr( HsmConnectFromName( HSMCONN_TYPE_HSM, computerName, IID_IHsmServer, (void**)&pHsm ) );
WsbAffirmPointer(pHsm);
WsbAffirmHr(pHsm->GetHsmMediaMgr(&pRms));
WsbTrace( L"Connected to RMS\n" );
//
// Second, wait for RMS to finish initializing, thus
// to have all media sets added
//
{
CComObject<CRmsSink> *pSink = new CComObject<CRmsSink>;
CComPtr<IUnknown> pSinkUnk = pSink;
WsbAffirmHr( pSink->Construct( pRms ) );
WsbAffirmHr( pSink->WaitForReady( ) );
WsbAffirmHr( pSink->DoUnadvise( ) );
}
//
// Fourth
// Ask it
//
CComPtr<IWsbIndexedCollection> pMediaSets;
WsbAffirmHr( pRms->GetMediaSets( &pMediaSets ) );
ULONG numEntries;
WsbTrace( L"Checking for Media Sets\n" );
WsbAffirmHr( pMediaSets->GetEntries( &numEntries ) );
WsbTrace( L"NumMediaSets = 0x%lu\n", numEntries );
if( numEntries > 0 ) {
//
// All conditions met, return TRUE
//
WsbTrace( L"Supported Media Found\n" );
hr = S_OK;
}
} WsbCatch( hr );
WsbTraceOut( L"RsIsSupportedMediaAvailable", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
USHORT
RsGetCopyStatus(
IN REFGUID CopyId,
IN HRESULT CopyHr,
IN SHORT CopyNextDataSet,
IN SHORT LastGoodNextDataSet
)
/*++
Routine Description:
Compares the two times and returns an appropriate defined value
based upon comparison (for Media Copies)
Arguments:
MasterTime - the time of last update to master
CopyTime - the time of last update to copy
copyStatus - returned value
Return Value:
none
--*/
{
WsbTraceIn( L"RsGetCopyStatus", L"CopyId = <%ls>, CopyHr = <%ls>, CopyNextDataSet = <%hd>, LastGoodNextDataSet = <%hd>", WsbGuidAsString( CopyId ), WsbHrAsString( CopyHr ), CopyNextDataSet, LastGoodNextDataSet );
USHORT copyStatus;
//
// Certain errors need to be masked out because they do not necessarily
// mean the media copy has an error - just that something happened that
// was unexpected, like timed out mounts or canceled mounts
//
switch( CopyHr ) {
case RMS_E_CANCELLED:
case RMS_E_REQUEST_REFUSED:
case RMS_E_WRITE_PROTECT:
case RMS_E_MEDIA_OFFLINE:
case RMS_E_TIMEOUT:
case RMS_E_SCRATCH_NOT_FOUND:
case RMS_E_CARTRIDGE_UNAVAILABLE:
case RMS_E_CARTRIDGE_DISABLED:
CopyHr = S_OK;
break;
}
if( IsEqualGUID( CopyId, GUID_NULL ) ) {
copyStatus = RS_MEDIA_COPY_STATUS_NONE;
} else if( RMS_E_CARTRIDGE_NOT_FOUND == CopyHr ) {
copyStatus = RS_MEDIA_COPY_STATUS_MISSING;
} else if( FAILED( CopyHr ) ) {
copyStatus = RS_MEDIA_COPY_STATUS_ERROR;
} else if( CopyNextDataSet < LastGoodNextDataSet ) {
copyStatus = RS_MEDIA_COPY_STATUS_OUTSYNC;
} else {
copyStatus = RS_MEDIA_COPY_STATUS_INSYNC;
}
WsbTraceOut( L"RsGetCopyStatus", L"copyStatus = <%hu>", copyStatus );
return copyStatus;
}
HRESULT
RsGetCopyStatusStringVerb(
IN USHORT copyStatus,
IN BOOL plural,
OUT CString & statusString
)
/*++
Routine Description:
Creates and returns a status string based on the status, with
a verb on it, for example "is synchronized"
Arguments:
copyStatus - defined status for media copies
plural - true if verb should be plural
String - Resulting string
Return Value:
non.
--*/
{
HRESULT hr = S_OK;
WsbTraceIn( L"RsGetCopyStatusStringVerb", L"CopyStatus = <%hu> ", copyStatus );
switch ( copyStatus ) {
case RS_MEDIA_COPY_STATUS_NONE:
if ( plural )
statusString.LoadString( IDS_CAR_COPYSET_NONE_PLURAL );
else
statusString.LoadString( IDS_CAR_COPYSET_NONE_SINGULAR );
break;
case RS_MEDIA_COPY_STATUS_ERROR:
statusString.LoadString( IDS_CAR_COPYSET_ERROR_SP );
break;
case RS_MEDIA_COPY_STATUS_MISSING:
if ( plural )
statusString.LoadString( IDS_CAR_COPYSET_MISSING_PLURAL );
else
statusString.LoadString( IDS_CAR_COPYSET_MISSING_SINGULAR );
break;
case RS_MEDIA_COPY_STATUS_OUTSYNC:
if ( plural )
statusString.LoadString( IDS_CAR_COPYSET_OUTSYNC_PLURAL );
else
statusString.LoadString( IDS_CAR_COPYSET_OUTSYNC_SINGULAR );
break;
case RS_MEDIA_COPY_STATUS_INSYNC:
if ( plural )
statusString.LoadString( IDS_CAR_COPYSET_INSYNC_PLURAL );
else
statusString.LoadString( IDS_CAR_COPYSET_INSYNC_SINGULAR );
break;
default:
statusString = L"";
hr = E_INVALIDARG;
break;
}
WsbTraceOut( L"RsGetCopyStatusStringVerb", L"String = <%ls>", statusString );
return hr;
}
HRESULT
RsGetCopyStatusString(
IN USHORT copyStatus,
OUT CString & statusString
)
/*++
Routine Description:
Creates and returns a status string based on the status
Arguments:
copyStatus - defined status for media copies
String - Resulting string
Return Value:
non.
--*/
{
HRESULT hr = S_OK;
WsbTraceIn( L"RsGetCopyStatusString", L"CopyStatus = <%hu> ", copyStatus );
switch ( copyStatus ) {
case RS_MEDIA_COPY_STATUS_NONE:
statusString.LoadString( IDS_CAR_COPYSET_NONE );
break;
case RS_MEDIA_COPY_STATUS_ERROR:
statusString.LoadString( IDS_CAR_COPYSET_ERROR );
break;
case RS_MEDIA_COPY_STATUS_MISSING:
statusString.LoadString( IDS_CAR_COPYSET_MISSING );
break;
case RS_MEDIA_COPY_STATUS_OUTSYNC:
statusString.LoadString( IDS_CAR_COPYSET_OUTSYNC );
break;
case RS_MEDIA_COPY_STATUS_INSYNC:
statusString.LoadString( IDS_CAR_COPYSET_INSYNC );
break;
default:
statusString = L"";
hr = E_INVALIDARG;
break;
}
WsbTraceOut( L"RsGetCopyStatusString", L"String = <%ls>", statusString );
return hr;
}
USHORT
RsGetCartStatus(
IN HRESULT LastHr,
IN BOOL ReadOnly,
IN BOOL Recreate,
IN SHORT NextDataSet,
IN SHORT LastGoodNextDataSet
)
/*++
Routine Description:
Returns a constant appropriate the status of a piece of media.
Arguments:
MasterTime - the time of last update to master
CopyTime - the time of last update to copy
Return Value:
defined constant for media status
--*/
{
USHORT cartStatus;
if( Recreate ) {
cartStatus = RS_MEDIA_STATUS_RECREATE;
} else if( NextDataSet < LastGoodNextDataSet ) {
cartStatus = RS_MEDIA_STATUS_ERROR_INCOMPLETE;
} else if( SUCCEEDED( LastHr ) || ( RMS_E_CARTRIDGE_DISABLED == LastHr ) ) {
cartStatus = ( ReadOnly ? RS_MEDIA_STATUS_READONLY : RS_MEDIA_STATUS_NORMAL );
} else if( RMS_E_CARTRIDGE_NOT_FOUND == LastHr ) {
cartStatus = RS_MEDIA_STATUS_ERROR_MISSING;
} else {
cartStatus = ( ReadOnly ? RS_MEDIA_STATUS_ERROR_RO : RS_MEDIA_STATUS_ERROR_RW );
}
return cartStatus;
}
HRESULT
RsGetCartStatusStringVerb(
IN USHORT cartStatus,
IN BOOL plural,
OUT CString & statusString
)
/*++
Routine Description:
Retreives a string appropriate the status of a piece of media with
a verb on it, for example "is read-only"
Arguments:
cartStatus
String - Resulting string
Return Value:
non.
--*/
{
HRESULT hr = S_OK;
switch( cartStatus ) {
case RS_MEDIA_STATUS_RECREATE:
if( plural ) {
statusString.LoadString( IDS_CAR_STATUS_RECREATE_PLURAL );
} else {
statusString.LoadString( IDS_CAR_STATUS_RECREATE_SINGULAR );
}
break;
case RS_MEDIA_STATUS_READONLY:
if( plural ) {
statusString.LoadString( IDS_CAR_STATUS_READONLY_PLURAL );
} else {
statusString.LoadString( IDS_CAR_STATUS_READONLY_SINGULAR );
}
break;
case RS_MEDIA_STATUS_NORMAL:
if( plural ) {
statusString.LoadString( IDS_CAR_STATUS_NORMAL_PLURAL );
} else {
statusString.LoadString( IDS_CAR_STATUS_NORMAL_SINGULAR );
}
break;
case RS_MEDIA_STATUS_ERROR_RO:
statusString.LoadString( IDS_CAR_STATUS_ERROR_RO_SP );
break;
case RS_MEDIA_STATUS_ERROR_RW:
statusString.LoadString( IDS_CAR_STATUS_ERROR_RW_SP );
break;
case RS_MEDIA_STATUS_ERROR_INCOMPLETE:
if( plural ) {
statusString.LoadString( IDS_CAR_STATUS_ERROR_INCOMPLETE_PLURAL );
} else {
statusString.LoadString( IDS_CAR_STATUS_ERROR_INCOMPLETE_SINGULAR );
}
break;
case RS_MEDIA_STATUS_ERROR_MISSING:
if( plural ) {
statusString.LoadString( IDS_CAR_STATUS_ERROR_MISSING_PLURAL );
} else {
statusString.LoadString( IDS_CAR_STATUS_ERROR_MISSING_SINGULAR );
}
break;
default:
statusString = L"";
hr = E_INVALIDARG;
}
return hr;
}
HRESULT
RsGetCartStatusString(
IN USHORT cartStatus,
OUT CString & statusString
)
/*++
Routine Description:
Retreives a string appropriate the status of a piece of media.
Arguments:
cartStatus
String - Resulting string
Return Value:
non.
--*/
{
HRESULT hr = S_OK;
switch( cartStatus ) {
case RS_MEDIA_STATUS_RECREATE:
statusString.LoadString( IDS_CAR_STATUS_RECREATE );
break;
case RS_MEDIA_STATUS_READONLY:
statusString.LoadString( IDS_CAR_STATUS_READONLY );
break;
case RS_MEDIA_STATUS_NORMAL:
statusString.LoadString( IDS_CAR_STATUS_NORMAL );
break;
case RS_MEDIA_STATUS_ERROR_RO:
statusString.LoadString( IDS_CAR_STATUS_ERROR_RO );
break;
case RS_MEDIA_STATUS_ERROR_RW:
statusString.LoadString( IDS_CAR_STATUS_ERROR_RW );
break;
case RS_MEDIA_STATUS_ERROR_MISSING:
statusString.LoadString( IDS_CAR_STATUS_ERROR_MISSING );
break;
case RS_MEDIA_STATUS_ERROR_INCOMPLETE:
statusString.LoadString( IDS_CAR_STATUS_ERROR_INCOMPLETE );
break;
default:
statusString = L"";
hr = E_INVALIDARG;
}
return( hr );
}
HRESULT
RsGetCartMultiStatusString(
IN USHORT statusRecreate,
IN USHORT statusReadOnly,
IN USHORT statusNormal,
IN USHORT statusRO,
IN USHORT statusRW,
IN USHORT statusMissing,
OUT CString &outString )
{
HRESULT hr = S_OK;
try {
outString = L"";
CString statusString;
CString formatString;
BOOL skipSeparator = TRUE; // used to omit first prepended comma
#define INSERT_SEPARATOR if( ! skipSeparator ) { outString += ", "; } else { skipSeparator = FALSE; }
if( statusNormal > 0 ) {
INSERT_SEPARATOR
WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_NORMAL, ( statusNormal != 1 ), statusString ) );
formatString.Format( L"%d %s", statusNormal, statusString );
outString += formatString;
}
if( statusReadOnly > 0 ) {
INSERT_SEPARATOR
WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_READONLY, ( statusReadOnly != 1 ), statusString ) );
formatString.Format( L"%d %s", statusReadOnly, statusString );
outString += formatString;
}
if( statusRecreate > 0 ) {
INSERT_SEPARATOR
WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_RECREATE, ( statusRecreate != 1 ), statusString ) );
formatString.Format( L"%d %s", statusRecreate, statusString );
outString += formatString;
}
if( statusRO > 0 ) {
INSERT_SEPARATOR
WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_ERROR_RO, ( statusRO != 1 ), statusString ) );
formatString.Format( L"%d %s", statusRO, statusString );
outString += formatString;
}
if( statusRW > 0 ) {
INSERT_SEPARATOR
WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_ERROR_RW, ( statusRW != 1 ), statusString ) );
formatString.Format( L"%d %s", statusRW, statusString );
outString += formatString;
}
if( statusMissing > 0 ) {
INSERT_SEPARATOR
WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_ERROR_MISSING, ( statusMissing != 1 ), statusString ) );
formatString.Format( L"%d %s", statusMissing, statusString );
outString += formatString;
}
} WsbCatch( hr );
return( hr );
}
HRESULT
RsGetCopyMultiStatusString(
IN USHORT statusNone,
IN USHORT statusError,
IN USHORT statusOutSync,
IN USHORT statusInSync,
OUT CString &outString
)
{
HRESULT hr = S_OK;
try {
outString = L"";
CString statusString;
CString formatString;
WsbAffirmHr( RsGetCopyStatusStringVerb( RS_MEDIA_COPY_STATUS_INSYNC, ( statusInSync != 1), statusString ) );
formatString.Format( L"%d %s, ", statusInSync, statusString );
outString += formatString;
WsbAffirmHr( RsGetCopyStatusStringVerb( RS_MEDIA_COPY_STATUS_OUTSYNC, ( statusOutSync != 1), statusString ) );
formatString.Format( L"%d %s, ", statusOutSync, statusString );
outString += formatString;
WsbAffirmHr( RsGetCopyStatusStringVerb( RS_MEDIA_COPY_STATUS_NONE, ( statusNone != 1), statusString ) );
formatString.Format( L"%d %s, ", statusNone, statusString );
outString += formatString;
WsbAffirmHr( RsGetCopyStatusStringVerb( RS_MEDIA_COPY_STATUS_ERROR, ( statusError != 1 ), statusString ) );
formatString.Format( L"%d %s, ", statusError, statusString );
outString += formatString;
WsbAffirmHr( RsGetCopyStatusStringVerb( RS_MEDIA_COPY_STATUS_MISSING, ( statusError != 1 ), statusString ) );
formatString.Format( L"%d %s", statusError, statusString );
outString += formatString;
} WsbCatch (hr);
return hr;
}
HRESULT
RsCreateAndRunFsaJob(
IN HSM_JOB_DEF_TYPE jobType,
IN IHsmServer *pHsmServer,
IN IFsaResource *pFsaResource,
IN BOOL ShowMsg
)
///////////////////////////////////////////////////////////////////////
//
// RsCreateAndRunFsaJob
//
// Creates a job in the engine of the given type, since scanning of a
// resource is required by the job, and since the job is partitioned
// across the Remote Storage major components. Puts the job in the
// NT Task Scheduler and runs it now via a call to the Engine's CreateTask()
// method. The Task Scheduler task is Disabled, so it will not be run
// according to a schedule.
//
//
{
WsbTraceIn( L"RsCreateAndRunFsaJob", L"jobType = <%d>", jobType );
HRESULT hr = S_OK;
CComPtr<IWsbCreateLocalObject> pLocalObject;
CComPtr<IHsmJob> pExistJob;
CComPtr<IHsmJob> pNewJob;
CWsbStringPtr pszExistJobName;
try {
WsbAssertPointer( pFsaResource );
WsbAssertPointer( pHsmServer );
//
// First check to see if volume is available. If not, return
// S_FALSE
//
HRESULT hrAvailable = pFsaResource->IsAvailable( );
WsbAffirmHr( hrAvailable );
HRESULT hrDeletePending = pFsaResource->IsDeletePending( );
WsbAffirmHr( hrDeletePending );
WsbAffirm( ( S_OK == hrAvailable ) && ( S_OK != hrDeletePending ), S_FALSE );
//
// Get the volume name
//
CWsbStringPtr szWsbVolumeName;
WsbAffirmHr( pFsaResource->GetName( &szWsbVolumeName, 0 ) );
//
// Create a job name
//
CString jobName;
RsCreateJobName( jobType, pFsaResource, jobName );
//
// Exit with an error if a job of this name is active already
//
if (S_OK == pHsmServer->FindJobByName( (LPWSTR)(LPCWSTR)jobName, &pExistJob)) {
if (S_OK == pExistJob->IsActive()) {
WsbThrow(JOB_E_ALREADYACTIVE);
}
}
//
// Inform the user, then create the job in the Engine, finally create
// and start the job in the NT Task Scheduler.
//
CString szJobType;
WsbAffirmHr( RsGetJobTypeString( jobType, szJobType ) );
CWsbStringPtr computerName;
WsbAffirmHr( pHsmServer->GetName( &computerName ) );
CString message;
AfxFormatString2( message, IDS_RUN_JOB, jobName, computerName );
if( !ShowMsg || ( AfxMessageBox( message, MB_ICONINFORMATION | MB_OKCANCEL |
MB_DEFBUTTON2 ) == IDOK ) ) {
//
// Get the one and only (for Sakkara) storage pool Id
//
GUID storagePoolId;
WsbAffirmHr( RsGetStoragePoolId( pHsmServer, &storagePoolId ) );
//
// Get a CreateLocalobject interface with which to create the job
//
WsbAffirmHr( RsQueryInterface( pHsmServer, IWsbCreateLocalObject, pLocalObject ) );
//
// Create the new job in the engine
//
WsbAffirmHr( pLocalObject->CreateInstance( CLSID_CHsmJob, IID_IHsmJob, (void**) &pNewJob ) );
WsbAffirmHr( pNewJob->InitAs(
(LPWSTR)(LPCWSTR)jobName, NULL, jobType, storagePoolId,
pHsmServer, TRUE, pFsaResource));
//
// Get the jobs collection from the engine
//
CComPtr<IWsbIndexedCollection> pJobs;
WsbAffirmHr( pHsmServer->GetJobs( &pJobs ) );
//
// If any jobs exist with this name, delete them
//
ULONG cCount;
WsbAffirmHr (pJobs->GetEntries( &cCount ) );
for( UINT i = 0; i < cCount; i++ ) {
pExistJob.Release( );
WsbAffirmHr( pJobs->At( i, IID_IHsmJob, (void **) &pExistJob ) );
WsbAffirmHr( pExistJob->GetName( &pszExistJobName, 0 ) );
if( pszExistJobName.IsEqual( jobName ) ) {
WsbAffirmHr( pJobs->RemoveAndRelease( pExistJob ) );
i--; cCount--;
}
}
//
// Add the new job to the engine collection
//
WsbAffirmHr( pJobs->Add( pNewJob ) );
//
// Set up to call the Engine to create an entry in NT Task Scheduler
//
// Create the parameter string to the program NT Scheduler
// will run (for Sakkara this is RsLaunch).
//
CString szParameters;
szParameters.Format( L"run \"%ls\"", jobName );
//
// Create the comment string for the NT Scheduler entry
//
CString commentString;
AfxFormatString2( commentString, IDS_GENERIC_JOB_COMMENT, szJobType, szWsbVolumeName);
//
// Declare and initialize the schedule components passed to
// the engine. Since this task is Disabled these are simply
// set to 0 (COM requires populating all arguments).
//
TASK_TRIGGER_TYPE jobTriggerType = TASK_TIME_TRIGGER_ONCE;
WORD jobStartHour = 0;
WORD jobStartMinute = 0;
//
// Indicate this is a Disabled task
//
BOOL scheduledJob = FALSE;
//
// Create and run the task
//
WsbAffirmHr( pHsmServer->CreateTask( jobName, szParameters,
commentString, jobTriggerType,
jobStartHour, jobStartMinute,
scheduledJob ) );
}
} WsbCatch( hr );
WsbTraceOut( L"RsCreateAndRunFsaJob", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
RsCreateAndRunDirectFsaJob(
IN HSM_JOB_DEF_TYPE jobType,
IN IHsmServer *pHsmServer,
IN IFsaResource *pFsaResource,
IN BOOL waitJob
)
///////////////////////////////////////////////////////////////////////
//
// RsCreateAndRunFsaJob
//
// Creates a job in the engine of the given type and run it.
// Wait for the job if required.
// Notes:
// 1) This job is not created and ran through the Task Scheduler
// 2) Most of the code is taken from StartJob in clivol.cpp
// In the future we should consider using this code instead of replicating
//
{
WsbTraceIn( L"RsCreateAndRunDirectFsaJob", L"jobType = <%d>", jobType );
HRESULT hr = S_OK;
try {
CComPtr<IHsmJob> pJob;
CString jobName;
// Create job name
WsbAffirmHr(RsCreateJobName(jobType, pFsaResource, jobName));
// If job exists - use it, otherwize, craete and add an appropriate job object
hr = pHsmServer->FindJobByName((LPWSTR)(LPCWSTR)jobName, &pJob);
if (S_OK == hr) {
// Job already exists
} else if (WSB_E_NOTFOUND == hr) {
// No such job yet
CComPtr<IWsbCreateLocalObject> pCreateObj;
CComPtr<IWsbIndexedCollection> pJobs;
CComPtr<IWsbIndexedCollection> pCollection;
CComPtr<IHsmStoragePool> pStoragePool;
GUID poolId;
ULONG count;
hr = S_OK;
pJob = 0;
// Create and add the job
WsbAffirmHr(pHsmServer->QueryInterface(IID_IWsbCreateLocalObject, (void**) &pCreateObj));
WsbAffirmHr(pCreateObj->CreateInstance(CLSID_CHsmJob, IID_IHsmJob, (void**) &pJob));
WsbAffirmHr(pHsmServer->GetStoragePools(&pCollection));
WsbAffirmHr(pCollection->GetEntries(&count));
WsbAffirm(1 == count, E_FAIL);
WsbAffirmHr(pCollection->At(0, IID_IHsmStoragePool, (void **)&pStoragePool));
WsbAffirmHr(pStoragePool->GetId(&poolId));
WsbAffirmHr(pJob->InitAs((LPWSTR)(LPCWSTR)jobName, NULL, jobType,
poolId, pHsmServer, TRUE, pFsaResource));
WsbAffirmHr(pHsmServer->GetJobs(&pJobs));
WsbAffirmHr(pJobs->Add(pJob));
} else {
// Other error - abort
WsbThrow(hr);
}
// Start the job
WsbAffirmHr(pJob->Start());
// Wait if required
if (waitJob) {
WsbAffirmHr(pJob->WaitUntilDone());
}
} WsbCatch(hr);
WsbTraceOut( L"RsCreateAndRunDirectFsaJob", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
RsCancelDirectFsaJob(
IN HSM_JOB_DEF_TYPE jobType,
IN IHsmServer *pHsmServer,
IN IFsaResource *pFsaResource
)
///////////////////////////////////////////////////////////////////////
//
// RsCancelDirectFsaJob
//
// Cancel a job that was previously ran with RsCreateAndRunDirectFsaJob
// Notes:
// 1) This job is not cancelled through the Task Scheduler
// 2) Most of the code is taken from CancelJob in clivol.cpp
// In the future we should consider using this code instead of replicating
//
{
WsbTraceIn( L"RsCancelDirectFsaJob", L"jobType = <%d>", jobType );
HRESULT hr = S_OK;
try {
CComPtr<IHsmJob> pJob;
CString jobName;
// Create job name
WsbAffirmHr(RsCreateJobName(jobType, pFsaResource, jobName));
// If job exists, try to cancel it
hr = pHsmServer->FindJobByName((LPWSTR)(LPCWSTR)jobName, &pJob);
if (S_OK == hr) {
// Cancel (we don't care if it's actually running or not)
WsbAffirmHr(pJob->Cancel(HSM_JOB_PHASE_ALL));
} else if (WSB_E_NOTFOUND == hr) {
// No such job, for sure it is not running...
hr = S_OK;
} else {
// Other error - abort
WsbThrow(hr);
}
} WsbCatch(hr);
WsbTraceOut( L"RsCancelDirectFsaJob", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
RsCreateJobName(
IN HSM_JOB_DEF_TYPE jobType,
IN IFsaResource * pResource,
OUT CString& jobName
)
/////////////////////////////////////////////////////////////////////////////////
//
// RsCreateJobName
//
// Creates a job name for a volume type job
//
//
{
WsbTraceIn( L"RsCreateJobName", L"jobType = <%d>", jobType );
HRESULT hr = S_OK;
try {
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString jobTypeString;
RsGetJobTypeString( jobType, jobTypeString );
CWsbStringPtr path;
WsbAffirmHr( pResource->GetUserFriendlyName( &path, 0 ) );
// For now, ignore the path if it's not a drive letter
size_t pathLen = wcslen(path);
if ((pathLen != 3) || (path[1] != L':')) {
path = L"";
}
CString volumeString;
if( path.IsEqual ( L"" ) ) {
//
// No drive letter - use the volume name and serial number instead
//
ULONG serial;
CWsbStringPtr name;
WsbAffirmHr( pResource->GetName( &name, 0 ) );
WsbAffirmHr( pResource->GetSerial( &serial ) );
if( name.IsEqual( L"" ) ) {
//
// No name, no drive letter - just have serial number
//
volumeString.Format( L"%8.8lx", serial );
} else {
volumeString.Format( L"%ls-%8.8lx", (OLECHAR*)name, serial );
}
} else {
path[1] = L'\0';
volumeString = path;
}
AfxFormatString2( jobName, IDS_JOB_NAME_PREFIX, jobTypeString, volumeString );
} WsbCatch (hr);
WsbTraceOut( L"RsCreateJobName", L"hr = <%ls>, jobName = <%ls>", WsbHrAsString( hr ), (LPCWSTR)jobName );
return( hr );
}
HRESULT
RsGetJobTypeString(
IN HSM_JOB_DEF_TYPE jobType,
OUT CString& szJobType
)
{
WsbTraceIn( L"RsGetJobTypeString", L"jobType = <%d>", jobType );
HRESULT hr = S_OK;
try {
switch( jobType ) {
case HSM_JOB_DEF_TYPE_MANAGE:
szJobType.LoadString( IDS_JOB_MANAGE );
break;
case HSM_JOB_DEF_TYPE_RECALL:
szJobType.LoadString( IDS_JOB_RECALL );
break;
case HSM_JOB_DEF_TYPE_TRUNCATE:
szJobType.LoadString( IDS_JOB_TRUNCATE );
break;
case HSM_JOB_DEF_TYPE_UNMANAGE:
szJobType.LoadString( IDS_JOB_UNMANAGE );
break;
case HSM_JOB_DEF_TYPE_FULL_UNMANAGE:
szJobType.LoadString( IDS_JOB_FULL_UNMANAGE );
break;
case HSM_JOB_DEF_TYPE_QUICK_UNMANAGE:
szJobType.LoadString( IDS_JOB_QUICK_UNMANAGE );
break;
case HSM_JOB_DEF_TYPE_VALIDATE:
szJobType.LoadString( IDS_JOB_VALIDATE );
break;
default:
WsbAssert( FALSE, E_INVALIDARG );
}
} WsbCatch ( hr );
WsbTraceOut( L"RsGetJobTypeString", L"hr = <%ls>, szJobType = <%ls>", WsbHrAsString( hr ), (LPCWSTR)szJobType );
return( hr );
}
HRESULT
RsCreateAndRunMediaCopyJob(
IN IHsmServer * pHsmServer,
IN UINT SetNum,
IN BOOL ShowMsg
)
///////////////////////////////////////////////////////////////////////
//
// RsCreateAndRunMediaCopyJob
//
// Creates and runs a task to synchronize (update) a specified copy set.
// Since the Media Copy Job is run via a single Engine method (there is no
// partitioning of the task across major components) and no scanning of
// files/resources/etc is required to run it, this method does not create
// a job in the Engine. It only creates a task in the NT Task Scheduler and
// runs it now via a call to the Engine's CreateTask() method. The Task
// Scheduler task is Disabled, so it will not be run according to a schedule.
//
//
{
WsbTraceIn( L"RsCreateAndRunMediaCopyJob", L"SetNum = <%u>", SetNum );
HRESULT hr = S_OK;
try {
WsbAssertPointer( pHsmServer );
// Create the task name to put in the scheduler
CString jobName, message;
jobName.Format( IDS_JOB_MEDIA_COPY_TITLE, SetNum );
CWsbStringPtr computerName;
WsbAffirmHr( pHsmServer->GetName( &computerName ) );
AfxFormatString2( message, IDS_RUN_JOB, jobName, computerName );
if( !ShowMsg || ( AfxMessageBox( message, MB_ICONINFORMATION |
MB_OKCANCEL ) == IDOK ) ) {
// Set up to call the Engine to create an entry in NT Task Scheduler
// Create the parameter string to the program NT Scheduler
// will run (for Sakkara this is RsLaunch)
CString szParameters;
szParameters.Format( L"sync %d", SetNum );
// Create the comment string for the NT Scheduler entry
CString commentString;
commentString.Format( IDS_MEDIA_COPY_JOB_COMMENT, SetNum );
// Declare and initialize the schedule components passed to
// the engine. Since this task is Disabled these are simply
// set to 0 (COM requires populating all arguments).
TASK_TRIGGER_TYPE jobTriggerType = TASK_TIME_TRIGGER_ONCE;
WORD jobStartHour = 0;
WORD jobStartMinute = 0;
// Indicate this is a Disabled task
BOOL scheduledJob = FALSE;
// Create and run the task
WsbAffirmHr( pHsmServer->CreateTask( jobName, szParameters,
commentString, jobTriggerType,
jobStartHour, jobStartMinute,
scheduledJob ) );
}
} WsbCatch (hr);
WsbTraceOut( L"RsCreateAndRunMediaCopyJob", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
RsCreateAndRunMediaRecreateJob(
IN IHsmServer * pHsmServer,
IN IMediaInfo * pMediaInfo,
IN REFGUID MediaId,
IN CString & MediaDescription,
IN SHORT CopyToUse
)
///////////////////////////////////////////////////////////////////////
//
// RsCreateAndRunMediaRecreateJob
//
// Creates and runs a task to recreate the master of a piece of media.
// Since the Re-create Master Job is run via a single Engine method (there
// is no partitioning of the task across major components) and no scanning
// of files/resources/etc is required to run it, this method does not create
// a job in the Engine. It only creates a task in the NT Task Scheduler and
// runs it now via a call to the Engine's CreateTask() method. The Task
// Scheduler task is Disabled, so it will not be run according to a schedule.
//
//
{
WsbTraceIn(
L"RsCreateAndRunMediaRecreateJob", L"MediaId = <%ls>, Media Description = <%ls>, CopyToUse = <%hd>",
WsbGuidAsString( MediaId ), (LPCWSTR)MediaDescription, CopyToUse );
HRESULT hr = S_OK;
try {
WsbAssertPointer( pHsmServer );
WsbAssertPointer( pMediaInfo );
// Create the task name to put in the scheduler
CString jobName, message;
AfxFormatString1( jobName, IDS_JOB_MEDIA_RECREATE_TITLE, MediaDescription );
CWsbStringPtr computerName;
WsbAffirmHr( pHsmServer->GetName( &computerName ) );
AfxFormatString2( message, IDS_RUN_JOB, jobName, computerName );
if( IDOK == AfxMessageBox( message, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2 ) ) {
// Set up to call the Engine to create an entry in NT Task Scheduler
// Create the parameter string to the program NT Scheduler
// will run (for Sakkara this is RsLaunch). First convert
// the input MediaId GUID to a string since it is used in
// the job parameter string.
CWsbStringPtr stringId( MediaId );
CString szParameters;
szParameters.Format( L"recreate -i %ls -c %hd", (WCHAR*)stringId, CopyToUse );
// Create the comment string for the NT Scheduler entry
CString commentString;
commentString.LoadString( IDS_MEDIA_RECREATE_JOB_COMMENT );
// Declare and initialize the schedule components passed to
// the engine. Since this task is Disabled these are simply
// set to 0 (COM requires populating all arguments).
TASK_TRIGGER_TYPE jobTriggerType = TASK_TIME_TRIGGER_ONCE;
WORD jobStartHour = 0;
WORD jobStartMinute = 0;
// Indicate this is a Disabled task
BOOL scheduledJob = FALSE;
// The Re-create Master job requires the Recreate state of the master
// media that will be re-created to have been set. Do so here since
// the user has already confirmed they want to run this job. (The
// UI already has the Engine's Segment database open.)
WsbAffirmHr( pMediaInfo->SetRecreate( TRUE ) );
WsbAffirmHr( pMediaInfo->Write() );
// Create and run the task
WsbAffirmHr( pHsmServer->CreateTask( jobName, szParameters,
commentString, jobTriggerType,
jobStartHour, jobStartMinute,
scheduledJob ) );
}
} WsbCatch (hr);
WsbTraceOut( L"RsCreateAndRunMediaRecreateJob", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
RsGetStoragePoolId(
IN IHsmServer *pHsmServer,
OUT GUID *pStoragePoolId
)
{
WsbTraceIn( L"RsGetStoragePoolId", L"pHsmServer = <0x%p>, pStoragePoolId = <0x%p>", pHsmServer, pStoragePoolId );
HRESULT hr = S_OK;
try {
CComPtr <IHsmStoragePool> pStoragePool;
WsbAffirmHr( RsGetStoragePool( pHsmServer, &pStoragePool ) );
//
// Get the GUID of the storage pool
//
WsbAffirmHr( pStoragePool->GetId( pStoragePoolId ) );
} WsbCatch( hr );
WsbTraceOut( L"RsGetStoragePoolId", L"hr = <%ls>, *pStoragePoolId = <%ls>", WsbHrAsString( hr ), WsbPtrToGuidAsString( pStoragePoolId ) );
return( hr );
}
HRESULT
RsGetStoragePool(
IN IHsmServer *pHsmServer,
OUT IHsmStoragePool **ppStoragePool
)
{
WsbTraceIn( L"RsGetStoragePool", L"pHsmServer = <0x%p>, ppStoragePool = <0x%p>", pHsmServer, ppStoragePool );
ULONG count;
HRESULT hr = S_OK;
try {
CComPtr <IWsbIndexedCollection> pCollection;
//
// Get the storage pools collection. There should only be one member.
//
WsbAffirmHr( pHsmServer->GetStoragePools( &pCollection ) );
WsbAffirmHr( pCollection->GetEntries( &count ) );
WsbAffirm( 1 == count, E_FAIL );
WsbAffirmHr( pCollection->At( 0, IID_IHsmStoragePool, (void **) ppStoragePool ) );
} WsbCatch( hr );
WsbTraceOut( L"RsGetStoragePool", L"hr = <%ls>, *pStoragePoolId = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppStoragePool ) );
return( hr );
}
HRESULT
RsGetInitialLVColumnProps(
int IdWidths,
int IdTitles,
CString **pColumnWidths,
CString **pColumnTitles,
int *pColumnCount
)
{
HRESULT hr = S_OK;
CString szResource;
OLECHAR* szData;
int colCount = 0;
int colWidths = 0;
int colTitles = 0;
int i = 0;
try {
if ( !pColumnWidths ) {
// Caller asked us to return number of columns
colCount = 0;
szResource.LoadString (IdTitles);
szData = szResource.GetBuffer( 0 );
szData = wcstok( szData, L":" );
while( szData ) {
colCount++;
szData = wcstok( NULL, L":" );
}
} else {
// Properites Widths
colWidths = 0;
szResource.LoadString (IdWidths);
szData = szResource.GetBuffer( 0 );
szData = wcstok( szData, L":" );
while( szData ) {
pColumnWidths[colWidths++] = new CString( szData );
szData = wcstok( NULL, L":" );
}
// Properites Titles
colTitles = 0;
szResource.LoadString (IdTitles);
szData = szResource.GetBuffer( 0 );
szData = wcstok( szData, L":" );
while( szData ) {
pColumnTitles[colTitles++] = new CString( szData );
szData = wcstok( NULL, L":" );
}
WsbAffirm( ( colTitles == colWidths ), E_FAIL );
colCount = colTitles;
}
*pColumnCount = colCount;
} WsbCatch (hr);
return hr;
}
HRESULT
RsServerSaveAll(
IN IUnknown * pUnkServer
)
{
WsbTraceIn( L"RsServerSaveAll", L"" );
HRESULT hr = S_OK;
try {
CComPtr<IWsbServer> pServer;
WsbAffirmHr( RsQueryInterface( pUnkServer, IWsbServer, pServer ) );
WsbAffirmHr( pServer->SaveAll( ) );
} WsbCatch( hr )
WsbTraceOut( L"RsServerSaveAll", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
RsGetVolumeDisplayName(
IFsaResource * pResource,
CString & DisplayName
)
{
WsbTraceIn( L"RsGetVolumeDisplayName", L"" );
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
try {
WsbAffirmPointer( pResource );
CWsbStringPtr label;
CWsbStringPtr userName;
WsbAffirmHr( pResource->GetName( &label, 0 ) );
WsbAffirmHr( pResource->GetUserFriendlyName( &userName, 0 ) );
// The user name is a drive letter.
if( userName.IsEqual( L"" ) ) {
if( label.IsEqual( L"" ) ) {
if (S_OK == pResource->IsAvailable()) {
DisplayName.LoadString( IDS_UNLABELED_VOLUME );
} else {
CString str1, str2;
str1.LoadString( IDS_UNLABELED_VOLUME );
str2.LoadString( IDS_VOL_NOT_AVAILABLE );
DisplayName.Format( L"%ls (%ls)", str1.GetBuffer(0), str2.GetBuffer(0) );
}
} else {
// If it's not a drive letter we use the label.
if (S_OK == pResource->IsAvailable()) {
DisplayName.Format( L"%ls", (WCHAR*)label );
} else {
CString str2;
str2.LoadString( IDS_VOL_NOT_AVAILABLE );
DisplayName.Format( L"%ls (%ls)", (WCHAR*)label, str2.GetBuffer(0) );
}
}
} else {
userName[(int)(wcslen(userName)-1)] = 0;
// The user name is a drive letter or a mount point path with a trailing backslash
// If the label is "", it's ignored in the formatting.
DisplayName.Format( L"%ls (%ls)", (WCHAR*)label, (WCHAR*)userName );
}
} WsbCatch( hr )
WsbTraceOut( L"RsGetVolumeDisplayName", L"hr = <%ls>, DisplayName = <%ls>", WsbHrAsString( hr ), (LPCWSTR)DisplayName );
return( hr );
}
// Temporary version that for unlabeled volumes w/ drive-letter puts in the
// size and free space
HRESULT
RsGetVolumeDisplayName2(
IFsaResource * pResource,
CString & DisplayName
)
{
WsbTraceIn( L"RsGetVolumeDisplayName2", L"" );
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
try {
WsbAffirmPointer( pResource );
CWsbStringPtr label;
CWsbStringPtr userName;
WsbAffirmHr( pResource->GetName( &label, 0 ) );
WsbAffirmHr( pResource->GetUserFriendlyName( &userName, 0 ) );
// The user name is a drive letter.
if( userName.IsEqual ( L"" ) ) {
if( label.IsEqual ( L"" ) ) {
LONGLONG totalSpace = 0;
LONGLONG freeSpace = 0;
LONGLONG premigrated = 0;
LONGLONG truncated = 0;
WsbAffirmHr( pResource->GetSizes( &totalSpace, &freeSpace, &premigrated, &truncated ) );
CString totalString, freeString;
RsGuiFormatLongLong4Char( totalSpace, totalString );
RsGuiFormatLongLong4Char( freeSpace, freeString );
AfxFormatString2( DisplayName, IDS_UNLABELED_VOLUME2, totalString, freeString );
} else {
// If it's not a drive letter we use the label.
DisplayName.Format( L"%ls", (WCHAR*)label );
}
} else {
userName[(int)(wcslen(userName)-1)] = 0;
// The user name is a drive letter or a mount point path with a trailing backslash
// If the label is "", it's ignored in the formatting.
DisplayName.Format( L"%ls (%ls)", (WCHAR*)label, (WCHAR*)userName );
}
} WsbCatch( hr )
WsbTraceOut( L"RsGetVolumeDisplayName2", L"hr = <%ls>, DisplayName = <%ls>", WsbHrAsString( hr ), (LPCWSTR)DisplayName );
return( hr );
}
HRESULT
RsGetVolumeSortKey(
IFsaResource * pResource,
CString & DisplayName
)
{
WsbTraceIn( L"RsGetVolumeSortKey", L"" );
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
try {
WsbAffirmPointer( pResource );
CWsbStringPtr label;
CWsbStringPtr userName;
WsbAffirmHr( pResource->GetName( &label, 0 ) );
WsbAffirmHr( pResource->GetUserFriendlyName( &userName, 0 ) );
DisplayName.Format( L"%ls %ls", (WCHAR*)userName, (WCHAR*)label );
} WsbCatch( hr )
WsbTraceOut( L"RsGetVolumeSortKey", L"hr = <%ls>, DisplayName = <%ls>", WsbHrAsString( hr ), (LPCWSTR)DisplayName );
return( hr );
}
HRESULT
RsIsVolumeAvailable(
IFsaResource * pResource
)
{
WsbTraceIn( L"RsIsVolumeAvailable", L"" );
HRESULT hr = S_OK;
try {
WsbAffirmPointer( pResource );
hr = pResource->IsAvailable();
} WsbCatch( hr )
WsbTraceOut( L"RsIsVolumeAvailable", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
RsIsWhiteOnBlack(
)
{
WsbTraceIn( L"RsIsWhiteOnBlack", L"" );
HRESULT hr = S_FALSE;
#define RS_CONTRAST_LIMIT 173
//
// Look to see if button background is within RS_CONTRAST_LIMIT
// units of black.
// Note that full white has a distance of 256 * sqrt(3) = 443
// Use Euclidean distance but compare before taking root
//
DWORD face3d = ::GetSysColor( COLOR_3DFACE );
DWORD blackDelta = GetRValue( face3d ) * GetRValue( face3d ) +
GetGValue( face3d ) * GetGValue( face3d ) +
GetBValue( face3d ) * GetBValue( face3d );
if( blackDelta < RS_CONTRAST_LIMIT * RS_CONTRAST_LIMIT ) {
hr = S_OK;
}
WsbTraceOut( L"RsIsWhiteOnBlack", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}
HRESULT
RsIsRmsErrorNotReady(
HRESULT HrError
)
{
WsbTraceIn( L"RsIsRmsErrorNotReady", L"" );
HRESULT hr = S_FALSE;
try {
switch( HrError ) {
case RMS_E_NOT_READY_SERVER_STARTING:
case RMS_E_NOT_READY_SERVER_STARTED:
case RMS_E_NOT_READY_SERVER_INITIALIZING:
case RMS_E_NOT_READY_SERVER_STOPPING:
case RMS_E_NOT_READY_SERVER_STOPPED:
case RMS_E_NOT_READY_SERVER_DISABLED:
case RMS_E_NOT_READY_SERVER_LOCKED:
hr = S_OK;
}
} WsbCatch( hr );
WsbTraceOut( L"RsIsRmsErrorNotReady", L"hr = <%ls>", WsbHrAsString( hr ) );
return( hr );
}