4975 lines
189 KiB
C++
4975 lines
189 KiB
C++
/*++
|
||
|
||
© 1998 Seagate Software, Inc. All rights reserved
|
||
|
||
Module Name:
|
||
|
||
RmsNTMS.cpp
|
||
|
||
Abstract:
|
||
|
||
Implementation of CRmsNTMS
|
||
|
||
Author:
|
||
|
||
Brian Dodd [brian] 14-May-1997
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "stdafx.h"
|
||
|
||
#include "RmsServr.h"
|
||
#include "RmsNTMS.h"
|
||
|
||
typedef struct RmsNTMSSearchHandle {
|
||
WCHAR FindName[NTMS_OBJECTNAME_LENGTH];
|
||
NTMS_GUID FindId;
|
||
DWORD FindType;
|
||
LPNTMS_GUID Objects;
|
||
DWORD NumberOfObjects;
|
||
DWORD MaxObjects;
|
||
DWORD Next;
|
||
DWORD LastError;
|
||
} RMS_NTMS_SEARCH_HANDLE, *LPRMS_NTMS_SEARCH_HANDLE;
|
||
|
||
#define ADD_ACE_MASK_BITS 1
|
||
#define REMOVE_ACE_MASK_BITS 2
|
||
|
||
//
|
||
// We use application name in RSM interface for media pool name.
|
||
// Media pool name is an identifier of the media pool in RSM, therefore, we cannot allow
|
||
// this string to be localized. Localizing this string would create another pool after
|
||
// installing a foreign language MUI.
|
||
//
|
||
#define REMOTE_STORAGE_APP_NAME OLESTR("Remote Storage")
|
||
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// IRmsNTMS implementation
|
||
|
||
/*
|
||
HINSTANCE hInstDll;
|
||
typedef DWORD (*FunctionName)( void );
|
||
FunctionName FunctionNameFn;
|
||
hInstDll = LoadLibrary( "dll" );
|
||
FunctionNameFn = (FunctionName) GetProcAddress( hInstDll, "FunctionName" );
|
||
result = (FunctionNameFn)();
|
||
*/
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::FinalConstruct(void)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
CComObjectRoot::FinalConstruct
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = this;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::FinalConstruct"), OLESTR(""));
|
||
|
||
m_pLibGuids = NULL;
|
||
m_dwNofLibs = 0;
|
||
|
||
try {
|
||
WsbAffirmHr(CComObjectRoot::FinalConstruct());
|
||
|
||
WsbAffirmHr( changeState( RmsNtmsStateStarting ));
|
||
|
||
m_SessionHandle = INVALID_HANDLE_VALUE;
|
||
m_IsRmsConfiguredForNTMS = FALSE;
|
||
m_IsNTMSRegistered = FALSE;
|
||
m_Name = RMS_NTMS_OBJECT_NAME;
|
||
m_Description = RMS_NTMS_OBJECT_DESCRIPTION;
|
||
|
||
if ( S_OK == getNtmsSupportFromRegistry(NULL) ) {
|
||
m_IsRmsConfiguredForNTMS = TRUE;
|
||
}
|
||
|
||
HKEY hKeyMachine = 0;
|
||
HKEY hKey = 0;
|
||
|
||
if ( S_OK == WsbOpenRegistryKey(NULL, RMS_NTMS_REGISTRY_STRING, KEY_QUERY_VALUE, &hKeyMachine, &hKey) ) {
|
||
WsbCloseRegistryKey (&hKeyMachine, &hKey);
|
||
m_IsNTMSRegistered = TRUE;
|
||
}
|
||
|
||
// Failure precedence.
|
||
WsbAffirm(m_IsRmsConfiguredForNTMS, RMS_E_NOT_CONFIGURED_FOR_NTMS);
|
||
WsbAffirm(m_IsNTMSRegistered, RMS_E_NTMS_NOT_REGISTERED);
|
||
|
||
WsbAffirmHr( changeState( RmsNtmsStateStarted ));
|
||
|
||
} WsbCatchAndDo(hr,
|
||
pObject->Disable( hr );
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_CONNECTION_NOT_ESABLISHED, 0, NULL, WsbHrAsString(hr), NULL);
|
||
|
||
// Always construct!
|
||
hr = S_OK;
|
||
);
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::FinalConstruct"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::FinalRelease(void)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
CComObjectRoot::FinalRelease
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::FinalRelease"), OLESTR(""));
|
||
|
||
try {
|
||
|
||
WsbAffirmHr( changeState( RmsNtmsStateStopping ));
|
||
|
||
endSession();
|
||
|
||
if (m_pLibGuids) {
|
||
WsbFree(m_pLibGuids);
|
||
}
|
||
|
||
CComObjectRoot::FinalRelease();
|
||
|
||
WsbAffirmHr( changeState( RmsNtmsStateStopped ));
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::FinalRelease"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::IsInstalled(void)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
try {
|
||
|
||
if ( !m_IsEnabled ) {
|
||
|
||
if ( !m_IsNTMSRegistered ) {
|
||
// check again... NTMS can get registered at anytime.
|
||
HKEY hKeyMachine = 0;
|
||
HKEY hKey = 0;
|
||
|
||
WsbAffirm(S_OK == WsbOpenRegistryKey(NULL, RMS_NTMS_REGISTRY_STRING, KEY_QUERY_VALUE, &hKeyMachine, &hKey), RMS_E_NTMS_NOT_REGISTERED);
|
||
WsbCloseRegistryKey (&hKeyMachine, &hKey);
|
||
|
||
m_IsNTMSRegistered = TRUE;
|
||
|
||
CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = this;
|
||
pObject->Enable();
|
||
|
||
// now need to initialize
|
||
WsbAffirmHr(InitializeInAnotherThread());
|
||
}
|
||
|
||
WsbAffirm(m_IsRmsConfiguredForNTMS, RMS_E_NOT_CONFIGURED_FOR_NTMS);
|
||
WsbAffirm(m_IsNTMSRegistered, RMS_E_NTMS_NOT_REGISTERED);
|
||
|
||
}
|
||
|
||
} WsbCatch(hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::Initialize(void)
|
||
{
|
||
HRESULT hr = E_FAIL;
|
||
CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = this;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::Initialize"), OLESTR(""));
|
||
|
||
try {
|
||
|
||
WsbAffirmHr( changeState( RmsNtmsStateInitializing ));
|
||
|
||
if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
|
||
WsbAffirmHr(beginSession());
|
||
}
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
|
||
//
|
||
// Create Remote Storage specific NTMS media pools
|
||
//
|
||
|
||
WsbAffirmHr( createMediaPools() );
|
||
|
||
//
|
||
// Report on other NTMS objects of interest
|
||
//
|
||
|
||
HANDLE hFind = NULL;
|
||
NTMS_OBJECTINFORMATION objectInfo;
|
||
|
||
hr = findFirstNtmsObject( NTMS_MEDIA_TYPE, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
|
||
while( S_OK == hr ) {
|
||
reportNtmsObjectInformation( &objectInfo );
|
||
hr = findNextNtmsObject( hFind, &objectInfo );
|
||
}
|
||
findCloseNtmsObject( hFind );
|
||
|
||
hr = findFirstNtmsObject( NTMS_CHANGER, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
|
||
while( S_OK == hr ) {
|
||
reportNtmsObjectInformation( &objectInfo );
|
||
hr = findNextNtmsObject( hFind, &objectInfo );
|
||
}
|
||
findCloseNtmsObject( hFind );
|
||
|
||
hr = findFirstNtmsObject( NTMS_CHANGER_TYPE, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
|
||
while( S_OK == hr ) {
|
||
reportNtmsObjectInformation( &objectInfo );
|
||
hr = findNextNtmsObject( hFind, &objectInfo );
|
||
}
|
||
findCloseNtmsObject( hFind );
|
||
|
||
hr = findFirstNtmsObject( NTMS_DRIVE, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
|
||
while( S_OK == hr ) {
|
||
reportNtmsObjectInformation( &objectInfo );
|
||
hr = findNextNtmsObject( hFind, &objectInfo );
|
||
}
|
||
findCloseNtmsObject( hFind );
|
||
|
||
hr = findFirstNtmsObject( NTMS_DRIVE_TYPE, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
|
||
while( S_OK == hr ) {
|
||
reportNtmsObjectInformation( &objectInfo );
|
||
hr = findNextNtmsObject( hFind, &objectInfo );
|
||
}
|
||
findCloseNtmsObject( hFind );
|
||
|
||
WsbAffirmHr( changeState( RmsNtmsStateReady ));
|
||
hr = S_OK;
|
||
|
||
} WsbCatchAndDo(hr,
|
||
pObject->Disable( hr );
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_INITIALIZATION_FAILED, 0, NULL, WsbHrAsString(hr), NULL );
|
||
);
|
||
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::Initialize"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::findFirstNtmsObject(
|
||
IN DWORD objectType,
|
||
IN REFGUID containerId,
|
||
IN WCHAR *objectName,
|
||
IN REFGUID objectId,
|
||
OUT HANDLE *hFindObject,
|
||
OUT LPNTMS_OBJECTINFORMATION pFindObjectData
|
||
)
|
||
{
|
||
|
||
HRESULT hr = E_FAIL;
|
||
|
||
try {
|
||
int maxObjects = 16; // Initial size of object id array to allocate
|
||
|
||
LPRMS_NTMS_SEARCH_HANDLE pFind;
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
DWORD errCode;
|
||
DWORD numberOfObjects = maxObjects;
|
||
LPNTMS_GUID pId = ( containerId == GUID_NULL ) ? NULL : (GUID *)&containerId;
|
||
LPNTMS_GUID pObjects = NULL;
|
||
NTMS_OBJECTINFORMATION objectInfo;
|
||
|
||
WsbAssertPointer( hFindObject );
|
||
|
||
|
||
if ( INVALID_HANDLE_VALUE == hSession ) {
|
||
WsbThrow( E_UNEXPECTED );
|
||
}
|
||
|
||
*hFindObject = NULL;
|
||
|
||
memset( &objectInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
pObjects = (LPNTMS_GUID)WsbAlloc( maxObjects*sizeof(NTMS_GUID) );
|
||
WsbAffirmPointer( pObjects );
|
||
|
||
// NTMS - enumerate all objects of the given type
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
errCode = EnumerateNtmsObject( hSession, pId, pObjects, &numberOfObjects, objectType, 0 );
|
||
|
||
if ( (ERROR_OBJECT_NOT_FOUND == errCode) || (0 == numberOfObjects) ) { // Don't count on NTMS returning the correct errCode
|
||
WsbThrow( RMS_E_NTMS_OBJECT_NOT_FOUND );
|
||
}
|
||
else if ( ERROR_INSUFFICIENT_BUFFER == errCode ) {
|
||
|
||
while ( ERROR_INSUFFICIENT_BUFFER == errCode ) {
|
||
// Allocate a new buffer, and retry.
|
||
WsbTrace(OLESTR("CRmsNTMS::findFirstNtmsObject - Reallocating for %d objects @1.\n"), numberOfObjects);
|
||
maxObjects = numberOfObjects;
|
||
LPVOID pTemp = WsbRealloc( pObjects, maxObjects*sizeof(NTMS_GUID) );
|
||
if( !pTemp ) {
|
||
WsbFree( pObjects );
|
||
WsbThrow( E_OUTOFMEMORY );
|
||
}
|
||
pObjects = (LPNTMS_GUID)pTemp;
|
||
|
||
// NTMS - enumerate all objects of the given type
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
errCode = EnumerateNtmsObject( hSession, pId, pObjects, &numberOfObjects, objectType, 0 );
|
||
}
|
||
}
|
||
WsbAffirmNoError( errCode );
|
||
|
||
HANDLE hTemp = (HANDLE)WsbAlloc( sizeof( RMS_NTMS_SEARCH_HANDLE) );
|
||
*hFindObject = hTemp;
|
||
WsbAffirmPointer( *hFindObject );
|
||
|
||
pFind = (LPRMS_NTMS_SEARCH_HANDLE)*hFindObject;
|
||
|
||
// Initialize the search handle
|
||
if ( objectName ) {
|
||
wcscpy( pFind->FindName, objectName );
|
||
}
|
||
else {
|
||
wcscpy( pFind->FindName, OLESTR("") );
|
||
}
|
||
|
||
pFind->FindId = objectId;
|
||
pFind->FindType = objectType;
|
||
pFind->Objects = pObjects;
|
||
pFind->NumberOfObjects = numberOfObjects;
|
||
pFind->MaxObjects = maxObjects;
|
||
pFind->Next = 0;
|
||
pFind->LastError = NO_ERROR;
|
||
|
||
BOOL bFound = FALSE;
|
||
|
||
while( pFind->Next < pFind->NumberOfObjects ) {
|
||
|
||
objectInfo.dwType = pFind->FindType;
|
||
objectInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
|
||
// NTMS - Get object information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
|
||
errCode = GetNtmsObjectInformation( hSession, &pObjects[pFind->Next++], &objectInfo );
|
||
pFind->LastError = errCode;
|
||
|
||
// Media Pools require special handling because they contain other Media Pools
|
||
if ( (NTMS_MEDIA_POOL == pFind->FindType) &&
|
||
(objectInfo.Info.MediaPool.dwNumberOfMediaPools > 0) ) {
|
||
|
||
DWORD numberToAdd = objectInfo.Info.MediaPool.dwNumberOfMediaPools;
|
||
do {
|
||
numberOfObjects = pFind->NumberOfObjects + numberToAdd;
|
||
|
||
// Allocate a new buffer, and retry.
|
||
WsbTrace(OLESTR("CRmsNTMS::findFirstNtmsObject - Reallocating for %d objects @2.\n"), numberOfObjects);
|
||
maxObjects = numberOfObjects;
|
||
pObjects = (LPNTMS_GUID)WsbRealloc( pFind->Objects, maxObjects*sizeof(NTMS_GUID) );
|
||
WsbAffirmAlloc( pObjects );
|
||
pFind->Objects = pObjects;
|
||
|
||
// NTMS - enumerate all objects of the given type
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
errCode = EnumerateNtmsObject( hSession,
|
||
&objectInfo.ObjectGuid, &pObjects[pFind->NumberOfObjects],
|
||
&numberToAdd, pFind->FindType, 0 );
|
||
} while ( ERROR_INSUFFICIENT_BUFFER == errCode ) ;
|
||
|
||
if ( NO_ERROR == errCode ) {
|
||
pFind->NumberOfObjects += numberToAdd;
|
||
pFind->MaxObjects = maxObjects;
|
||
}
|
||
else {
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
WsbAffirmNoError(errCode);
|
||
}
|
||
}
|
||
|
||
if ( NO_ERROR == pFind->LastError ) {
|
||
|
||
// Now see if it is the one we're looking for
|
||
|
||
if ( GUID_NULL != pFind->FindId ) {
|
||
|
||
if ( pFind->FindId == objectInfo.ObjectGuid ) { // Match the GUID
|
||
|
||
bFound = TRUE;
|
||
if ( pFindObjectData != NULL ) {
|
||
memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
}
|
||
break;
|
||
|
||
}
|
||
}
|
||
else if ( wcslen( pFind->FindName ) > 0 ) { // Match the Name
|
||
|
||
if ( 0 == wcscmp( pFind->FindName, objectInfo.szName ) ) {
|
||
|
||
bFound = TRUE;
|
||
if ( pFindObjectData != NULL ) {
|
||
memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
}
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
}
|
||
else { // Any GUID or Name
|
||
|
||
bFound = TRUE;
|
||
if ( pFindObjectData != NULL ) {
|
||
memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
}
|
||
break;
|
||
|
||
}
|
||
|
||
}
|
||
else {
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("GetNTMSObjectInformation"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
WsbThrow( RMS_E_NTMS_OBJECT_NOT_FOUND );
|
||
}
|
||
|
||
}
|
||
|
||
hr = ( bFound ) ? S_OK : RMS_E_NTMS_OBJECT_NOT_FOUND;
|
||
|
||
} WsbCatch(hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::findNextNtmsObject(
|
||
IN HANDLE hFindObject,
|
||
OUT LPNTMS_OBJECTINFORMATION pFindObjectData
|
||
)
|
||
{
|
||
HRESULT hr = E_FAIL;
|
||
|
||
try {
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
DWORD errCode;
|
||
|
||
LPRMS_NTMS_SEARCH_HANDLE pFind = (LPRMS_NTMS_SEARCH_HANDLE)hFindObject;
|
||
|
||
LPNTMS_GUID pObjects = pFind->Objects;
|
||
|
||
NTMS_OBJECTINFORMATION objectInfo;
|
||
|
||
if ( INVALID_HANDLE_VALUE == hSession ) {
|
||
WsbThrow( E_UNEXPECTED );
|
||
}
|
||
|
||
BOOL bFound = FALSE;
|
||
|
||
while( pFind->Next < pFind->NumberOfObjects ) {
|
||
|
||
objectInfo.dwType = pFind->FindType;
|
||
objectInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
|
||
// NTMS - get object information of next object
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
|
||
errCode = GetNtmsObjectInformation( hSession, &pObjects[pFind->Next++], &objectInfo );
|
||
pFind->LastError = errCode;
|
||
|
||
// Media Pools require special handling because they contain other Media Pools
|
||
if ( (NTMS_MEDIA_POOL == pFind->FindType) &&
|
||
(objectInfo.Info.MediaPool.dwNumberOfMediaPools > 0) ) {
|
||
|
||
DWORD maxObjects;
|
||
DWORD numberOfObjects;
|
||
DWORD numberToAdd = objectInfo.Info.MediaPool.dwNumberOfMediaPools;
|
||
do {
|
||
numberOfObjects = pFind->NumberOfObjects + numberToAdd;
|
||
|
||
// Allocate a new buffer, and retry.
|
||
WsbTrace(OLESTR("CRmsNTMS::findNextNtmsObject - Reallocating for %d objects.\n"), numberOfObjects);
|
||
maxObjects = numberOfObjects;
|
||
pObjects = (LPNTMS_GUID)WsbRealloc( pFind->Objects, maxObjects*sizeof(NTMS_GUID) );
|
||
WsbAffirmAlloc( pObjects );
|
||
pFind->Objects = pObjects;
|
||
|
||
// NTMS - enumerate all objects of the given type
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
errCode = EnumerateNtmsObject( hSession,
|
||
&objectInfo.ObjectGuid, &pObjects[pFind->NumberOfObjects],
|
||
&numberToAdd, pFind->FindType, 0 );
|
||
} while ( ERROR_INSUFFICIENT_BUFFER == errCode ) ;
|
||
|
||
if ( NO_ERROR == errCode ) {
|
||
pFind->NumberOfObjects += numberToAdd;
|
||
pFind->MaxObjects = maxObjects;
|
||
}
|
||
else {
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
WsbAffirmNoError(errCode);
|
||
}
|
||
}
|
||
|
||
if ( NO_ERROR == pFind->LastError ) {
|
||
|
||
// Now see if it is the one we're looking for
|
||
|
||
if ( GUID_NULL != pFind->FindId ) {
|
||
|
||
if ( pFind->FindId == objectInfo.ObjectGuid ) { // Match the GUID
|
||
|
||
bFound = TRUE;
|
||
if ( pFindObjectData != NULL ) {
|
||
memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
}
|
||
break;
|
||
|
||
}
|
||
}
|
||
else if ( wcslen( pFind->FindName ) > 0 ) { // Match the Name
|
||
|
||
if ( 0 == wcscmp( pFind->FindName, objectInfo.szName ) ) {
|
||
|
||
bFound = TRUE;
|
||
if ( pFindObjectData != NULL ) {
|
||
memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
}
|
||
break;
|
||
|
||
}
|
||
|
||
}
|
||
else { // Any GUID or Name
|
||
|
||
bFound = TRUE;
|
||
if ( pFindObjectData != NULL ) {
|
||
memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
}
|
||
break;
|
||
|
||
}
|
||
|
||
}
|
||
else {
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("GetNTMSObjectInformation"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
WsbThrow( RMS_E_NTMS_OBJECT_NOT_FOUND );
|
||
}
|
||
}
|
||
|
||
hr = (bFound) ? S_OK : RMS_E_NTMS_OBJECT_NOT_FOUND;
|
||
|
||
} WsbCatch(hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::findCloseNtmsObject(
|
||
IN HANDLE hFindObject)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
try {
|
||
|
||
WsbAffirmPointer(hFindObject); // We don't need to assert here... It's possible to call
|
||
// findCloseNtmsObject even if nothing was found with
|
||
// findFirstNtmsObject. Skip the free step.
|
||
WsbFree(((LPRMS_NTMS_SEARCH_HANDLE)hFindObject)->Objects);
|
||
WsbFree(hFindObject);
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::reportNtmsObjectInformation(
|
||
IN LPNTMS_OBJECTINFORMATION pObjectInfo)
|
||
{
|
||
|
||
HRESULT hr = S_OK;
|
||
|
||
static DWORD lastTypeReported = 0;
|
||
|
||
try {
|
||
WsbAssertPointer( pObjectInfo );
|
||
|
||
BOOL bHeaders = (lastTypeReported == pObjectInfo->dwType) ? FALSE : TRUE;
|
||
|
||
lastTypeReported = pObjectInfo->dwType;
|
||
|
||
// Output a header to trace file
|
||
|
||
if ( bHeaders ) {
|
||
switch ( pObjectInfo->dwType ) {
|
||
|
||
case NTMS_UNKNOWN:
|
||
case NTMS_OBJECT:
|
||
WsbTrace( OLESTR("!!! WARNING !!! - CRmsServer::reportNtmsObjectInformation: report for NTMS object type: %d is not available.\n") );
|
||
break;
|
||
|
||
case NTMS_CHANGER:
|
||
break;
|
||
|
||
case NTMS_CHANGER_TYPE:
|
||
break;
|
||
|
||
case NTMS_COMPUTER:
|
||
WsbTrace( OLESTR("!!! WARNING !!! - CRmsServer::reportNtmsObjectInformation: report for NTMS object type: %d is not available.\n") );
|
||
break;
|
||
|
||
case NTMS_DRIVE:
|
||
case NTMS_DRIVE_TYPE:
|
||
break;
|
||
|
||
case NTMS_IEDOOR:
|
||
case NTMS_IEPORT:
|
||
WsbTrace( OLESTR("!!! WARNING !!! - CRmsServer::reportNtmsObjectInformation: report for NTMS object type: %d is not available.\n") );
|
||
break;
|
||
|
||
case NTMS_LIBRARY:
|
||
break;
|
||
|
||
case NTMS_LIBREQUEST:
|
||
case NTMS_LOGICAL_MEDIA:
|
||
WsbTrace( OLESTR("!!! WARNING !!! - CRmsServer::reportNtmsObjectInformation: report for NTMS object type: %d is not available.\n") );
|
||
break;
|
||
|
||
case NTMS_MEDIA_POOL:
|
||
WsbTrace( OLESTR("GUID Enabl Type Media Type GUID Parent GUID A-Pol D-Pol Allocate Physical Logical Pools Name / Description\n") );
|
||
WsbTrace( OLESTR("====================================== ===== ==== ====================================== ====================================== ===== ===== ======== ======== ======== ===== ========================================\n") );
|
||
break;
|
||
|
||
case NTMS_MEDIA_TYPE:
|
||
|
||
WsbTrace( OLESTR("GUID Enabl Type Sides RW Name / Description\n") );
|
||
WsbTrace( OLESTR("====================================== ===== ==== ===== == ========================================\n") );
|
||
break;
|
||
|
||
case NTMS_PARTITION:
|
||
break;
|
||
|
||
case NTMS_PHYSICAL_MEDIA:
|
||
case NTMS_STORAGESLOT:
|
||
case NTMS_OPREQUEST:
|
||
default:
|
||
WsbTrace( OLESTR("!!! WARNING !!! - CRmsServer::reportNtmsObjectInformation: report for object type: %d is not supported\n") );
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Convert SYSTEMTIME to FILETIME for output.
|
||
|
||
SYSTEMTIME sCreated, sModified;
|
||
FILETIME fCreated, fModified;
|
||
|
||
sCreated = pObjectInfo->Created;
|
||
sModified = pObjectInfo->Modified;
|
||
|
||
SystemTimeToFileTime(&sCreated, &fCreated);
|
||
SystemTimeToFileTime(&sModified, &fModified);
|
||
|
||
|
||
switch ( pObjectInfo->dwType ) {
|
||
|
||
case NTMS_UNKNOWN:
|
||
case NTMS_OBJECT:
|
||
break;
|
||
|
||
case NTMS_CHANGER:
|
||
|
||
WsbTrace(OLESTR("Changer %d Information:\n"), pObjectInfo->Info.Changer.Number );
|
||
WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
|
||
WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
|
||
WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
|
||
WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
|
||
WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
|
||
WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
|
||
WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
|
||
WsbTrace(OLESTR(" Number......... %-d\n"), pObjectInfo->Info.Changer.Number );
|
||
WsbTrace(OLESTR(" Changer Type... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Changer.ChangerType) );
|
||
WsbTrace(OLESTR(" Serial Number.. <%-ls>\n"), pObjectInfo->Info.Changer.szSerialNumber );
|
||
WsbTrace(OLESTR(" Revision....... <%-ls>\n"), pObjectInfo->Info.Changer.szRevision );
|
||
WsbTrace(OLESTR(" Device Name.... <%-ls>\n"), pObjectInfo->Info.Changer.szDeviceName );
|
||
WsbTrace(OLESTR(" SCSI Port...... %-d\n"), pObjectInfo->Info.Changer.ScsiPort );
|
||
WsbTrace(OLESTR(" SCSI Bus....... %-d\n"), pObjectInfo->Info.Changer.ScsiBus );
|
||
WsbTrace(OLESTR(" SCSI Target.... %-d\n"), pObjectInfo->Info.Changer.ScsiTarget );
|
||
WsbTrace(OLESTR(" SCSI Lun....... %-d\n"), pObjectInfo->Info.Changer.ScsiLun );
|
||
WsbTrace(OLESTR(" Library....... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Changer.Library) );
|
||
|
||
break;
|
||
|
||
case NTMS_CHANGER_TYPE:
|
||
WsbTrace(OLESTR("Changer Type Information:\n") );
|
||
WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
|
||
WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
|
||
WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
|
||
WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
|
||
WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
|
||
WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
|
||
WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
|
||
WsbTrace(OLESTR(" Vendor......... <%-ls>\n"), pObjectInfo->Info.ChangerType.szVendor );
|
||
WsbTrace(OLESTR(" Product........ <%-ls>\n"), pObjectInfo->Info.ChangerType.szProduct );
|
||
WsbTrace(OLESTR(" Device Type.... %-d\n"), pObjectInfo->Info.ChangerType.DeviceType );
|
||
break;
|
||
|
||
case NTMS_COMPUTER:
|
||
break;
|
||
|
||
case NTMS_DRIVE:
|
||
WsbTrace(OLESTR("Drive %d Information:\n"), pObjectInfo->Info.Drive.Number );
|
||
WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
|
||
WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
|
||
WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
|
||
WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
|
||
WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
|
||
WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
|
||
WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
|
||
WsbTrace(OLESTR(" Number......... %-d\n"), pObjectInfo->Info.Drive.Number );
|
||
WsbTrace(OLESTR(" State.......... %-d\n"), pObjectInfo->Info.Drive.State );
|
||
WsbTrace(OLESTR(" Drive Type..... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Drive.DriveType) );
|
||
WsbTrace(OLESTR(" Device Name.... <%-ls>\n"), pObjectInfo->Info.Drive.szDeviceName );
|
||
WsbTrace(OLESTR(" Serial Number.. <%-ls>\n"), pObjectInfo->Info.Drive.szSerialNumber );
|
||
WsbTrace(OLESTR(" Revision....... <%-ls>\n"), pObjectInfo->Info.Drive.szRevision );
|
||
WsbTrace(OLESTR(" SCSI Port...... %-d\n"), pObjectInfo->Info.Drive.ScsiPort );
|
||
WsbTrace(OLESTR(" SCSI Bus....... %-d\n"), pObjectInfo->Info.Drive.ScsiBus );
|
||
WsbTrace(OLESTR(" SCSI Target.... %-d\n"), pObjectInfo->Info.Drive.ScsiTarget );
|
||
WsbTrace(OLESTR(" SCSI Lun....... %-d\n"), pObjectInfo->Info.Drive.ScsiLun );
|
||
WsbTrace(OLESTR(" Mount Count.... %-d\n"), pObjectInfo->Info.Drive.dwMountCount );
|
||
WsbTrace(OLESTR(" Last Cleaned... %02d/%02d/%02d %02d:%02d:%02d.%03d\n"),
|
||
pObjectInfo->Info.Drive.LastCleanedTs.wMonth,
|
||
pObjectInfo->Info.Drive.LastCleanedTs.wDay,
|
||
pObjectInfo->Info.Drive.LastCleanedTs.wYear,
|
||
pObjectInfo->Info.Drive.LastCleanedTs.wHour,
|
||
pObjectInfo->Info.Drive.LastCleanedTs.wMinute,
|
||
pObjectInfo->Info.Drive.LastCleanedTs.wSecond,
|
||
pObjectInfo->Info.Drive.LastCleanedTs.wMilliseconds );
|
||
WsbTrace(OLESTR(" Partition...... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Drive.SavedPartitionId) );
|
||
WsbTrace(OLESTR(" Library........ %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Drive.Library) );
|
||
break;
|
||
|
||
case NTMS_DRIVE_TYPE:
|
||
WsbTrace(OLESTR("Drive Type Information:\n") );
|
||
WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
|
||
WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
|
||
WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
|
||
WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
|
||
WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
|
||
WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
|
||
WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
|
||
WsbTrace(OLESTR(" Vendor......... <%-ls>\n"), pObjectInfo->Info.DriveType.szVendor );
|
||
WsbTrace(OLESTR(" Product........ <%-ls>\n"), pObjectInfo->Info.DriveType.szProduct );
|
||
WsbTrace(OLESTR(" Number of Heads %-d\n"), pObjectInfo->Info.DriveType.NumberOfHeads );
|
||
WsbTrace(OLESTR(" Device Type.... %-d\n"), pObjectInfo->Info.DriveType.DeviceType );
|
||
break;
|
||
|
||
case NTMS_IEDOOR:
|
||
case NTMS_IEPORT:
|
||
break;
|
||
|
||
case NTMS_LIBRARY:
|
||
WsbTrace(OLESTR("Library Information:\n") );
|
||
WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
|
||
WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
|
||
WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
|
||
WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
|
||
WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
|
||
WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
|
||
WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
|
||
WsbTrace(OLESTR(" Library Type... %-d\n"), pObjectInfo->Info.Library.LibraryType );
|
||
WsbTrace(OLESTR(" CleanerSlot.... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Library.CleanerSlot) );
|
||
WsbTrace(OLESTR(" CleanerSlotD... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Library.CleanerSlotDefault) );
|
||
WsbTrace(OLESTR(" Can Clean...... %-ls\n"), WsbBoolAsString(pObjectInfo->Info.Library.LibrarySupportsDriveCleaning) );
|
||
WsbTrace(OLESTR(" Has Bar Code... %-ls\n"), WsbBoolAsString(pObjectInfo->Info.Library.BarCodeReaderInstalled) );
|
||
WsbTrace(OLESTR(" Inventory Method %-d\n"), pObjectInfo->Info.Library.InventoryMethod );
|
||
WsbTrace(OLESTR(" Cleans Remaining %-d\n"), pObjectInfo->Info.Library.dwCleanerUsesRemaining );
|
||
WsbTrace(OLESTR(" Drives......... %-d (%d)\n"),
|
||
pObjectInfo->Info.Library.dwNumberOfDrives,
|
||
pObjectInfo->Info.Library.FirstDriveNumber);
|
||
WsbTrace(OLESTR(" Slots.......... %-d (%d)\n"),
|
||
pObjectInfo->Info.Library.dwNumberOfSlots,
|
||
pObjectInfo->Info.Library.FirstSlotNumber);
|
||
WsbTrace(OLESTR(" Doors.......... %-d (%d)\n"),
|
||
pObjectInfo->Info.Library.dwNumberOfDoors,
|
||
pObjectInfo->Info.Library.FirstDoorNumber);
|
||
WsbTrace(OLESTR(" Ports.......... %-d (%d)\n"),
|
||
pObjectInfo->Info.Library.dwNumberOfPorts,
|
||
pObjectInfo->Info.Library.FirstPortNumber);
|
||
WsbTrace(OLESTR(" Changers....... %-d (%d)\n"),
|
||
pObjectInfo->Info.Library.dwNumberOfChangers,
|
||
pObjectInfo->Info.Library.FirstChangerNumber);
|
||
WsbTrace(OLESTR(" Media Count.... %-d\n"), pObjectInfo->Info.Library.dwNumberOfMedia );
|
||
WsbTrace(OLESTR(" Media Types.... %-d\n"), pObjectInfo->Info.Library.dwNumberOfMediaTypes );
|
||
WsbTrace(OLESTR(" Requests....... %-d\n"), pObjectInfo->Info.Library.dwNumberOfLibRequests );
|
||
break;
|
||
|
||
case NTMS_LIBREQUEST:
|
||
case NTMS_LOGICAL_MEDIA:
|
||
break;
|
||
|
||
case NTMS_MEDIA_POOL:
|
||
{
|
||
// We need some temporaries since WsbGuidAsString() uses static memory to store string.
|
||
CWsbStringPtr g1 = pObjectInfo->ObjectGuid;
|
||
CWsbStringPtr g2 = pObjectInfo->Info.MediaPool.MediaType;
|
||
CWsbStringPtr g3 = pObjectInfo->Info.MediaPool.Parent;
|
||
|
||
WsbTrace( OLESTR("%ls %5ls %4d %ls %ls %5d %5d %8d %8d %8d %5d <%ls> / <%ls>\n"),
|
||
(WCHAR *)g1,
|
||
WsbBoolAsString(pObjectInfo->Enabled),
|
||
pObjectInfo->Info.MediaPool.PoolType,
|
||
(WCHAR *)g2,
|
||
(WCHAR *)g3,
|
||
pObjectInfo->Info.MediaPool.AllocationPolicy,
|
||
pObjectInfo->Info.MediaPool.DeallocationPolicy,
|
||
pObjectInfo->Info.MediaPool.dwMaxAllocates,
|
||
pObjectInfo->Info.MediaPool.dwNumberOfPhysicalMedia,
|
||
pObjectInfo->Info.MediaPool.dwNumberOfLogicalMedia,
|
||
pObjectInfo->Info.MediaPool.dwNumberOfMediaPools,
|
||
pObjectInfo->szName,
|
||
pObjectInfo->szDescription );
|
||
}
|
||
break;
|
||
|
||
case NTMS_MEDIA_TYPE:
|
||
WsbTrace( OLESTR("%ls %5ls %4d %5d %2d <%ls> / <%ls>\n"),
|
||
WsbGuidAsString(pObjectInfo->ObjectGuid),
|
||
WsbBoolAsString(pObjectInfo->Enabled),
|
||
pObjectInfo->Info.MediaType.MediaType,
|
||
pObjectInfo->Info.MediaType.NumberOfSides,
|
||
pObjectInfo->Info.MediaType.ReadWriteCharacteristics,
|
||
pObjectInfo->szName,
|
||
pObjectInfo->szDescription );
|
||
break;
|
||
|
||
case NTMS_PARTITION:
|
||
WsbTrace(OLESTR("Partion Information:\n") );
|
||
WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
|
||
WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
|
||
WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
|
||
WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
|
||
WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
|
||
WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
|
||
WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
|
||
WsbTrace(OLESTR(" PhysicalMedia.. %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Partition.PhysicalMedia));
|
||
WsbTrace(OLESTR(" LogicalMedia... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Partition.LogicalMedia));
|
||
WsbTrace(OLESTR(" State.......... %-d\n"), pObjectInfo->Info.Partition.State);
|
||
WsbTrace(OLESTR(" Side........... %-d\n"), pObjectInfo->Info.Partition.Side);
|
||
WsbTrace(OLESTR(" OmidLabelIdLen %-d\n"), pObjectInfo->Info.Partition.dwOmidLabelIdLength);
|
||
WsbTrace(OLESTR(" OmidLableId:\n"));
|
||
WsbTraceBuffer(pObjectInfo->Info.Partition.dwOmidLabelIdLength, pObjectInfo->Info.Partition.OmidLabelId);
|
||
WsbTrace(OLESTR(" OmidLabelType.. %-ls\n"), pObjectInfo->Info.Partition.szOmidLabelType);
|
||
WsbTrace(OLESTR(" OmidLabelInfo.. %-ls\n"), pObjectInfo->Info.Partition.szOmidLabelInfo);
|
||
WsbTrace(OLESTR(" MountCount..... %-d\n"), pObjectInfo->Info.Partition.dwMountCount);
|
||
WsbTrace(OLESTR(" AllocateCount.. %-d\n"), pObjectInfo->Info.Partition.dwAllocateCount);
|
||
WsbTrace(OLESTR(" Capacity....... %-I64d\n"), pObjectInfo->Info.Partition.Capacity.QuadPart);
|
||
break;
|
||
|
||
case NTMS_PHYSICAL_MEDIA:
|
||
case NTMS_STORAGESLOT:
|
||
case NTMS_OPREQUEST:
|
||
default:
|
||
break;
|
||
}
|
||
|
||
} WsbCatch(hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::getNtmsSupportFromRegistry(
|
||
OUT DWORD *pNTMSSupportValue)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Determines if NTMS flag is set in the Registry.
|
||
|
||
Arguments:
|
||
|
||
pNTMSSupportValue - Receives the actual value of the regstry key value. Any non-zero
|
||
values indicates NTMS support.
|
||
|
||
Return Values:
|
||
|
||
S_OK - NTMS support flag is on.
|
||
S_FALSE - NTMS support flag is off.
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD val = RMS_DEFAULT_NTMS_SUPPORT;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::getNtmsSupportFromRegistry"), OLESTR(""));
|
||
|
||
try {
|
||
DWORD sizeGot;
|
||
const int cDataSizeToGet = 100;
|
||
OLECHAR dataString[cDataSizeToGet];
|
||
OLECHAR *stopString;
|
||
|
||
//
|
||
// Get the value. If the key doesn't exists, the default value is used.
|
||
//
|
||
|
||
try {
|
||
|
||
WsbAffirmHrOk(WsbEnsureRegistryKeyExists(NULL, RMS_REGISTRY_STRING));
|
||
WsbAffirmHrOk(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_NTMS_SUPPORT,
|
||
dataString, cDataSizeToGet, &sizeGot));
|
||
val = wcstoul(dataString, &stopString, 10);
|
||
|
||
} WsbCatch(hr);
|
||
|
||
if (pNTMSSupportValue != NULL) {
|
||
*pNTMSSupportValue = val;
|
||
}
|
||
|
||
hr = (val) ? S_OK : S_FALSE;
|
||
|
||
} WsbCatchAndDo( hr,
|
||
hr = S_FALSE;
|
||
);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::getNtmsSupportFromRegistry"), OLESTR("hr = <%ls>, val = <%ld>"), WsbHrAsString(hr), val);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::beginSession(void)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
CRmsNTMS::beginSession
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
WsbTraceIn( OLESTR("CRmsNTMS::beginSession"), OLESTR("") );
|
||
|
||
try {
|
||
|
||
WsbAffirmHrOk(IsInstalled());
|
||
WsbAffirmHrOk(endSession()); // clear the old session
|
||
WsbAffirmHrOk(waitUntilReady()); // starts a new session
|
||
//WsbAffirmHrOk(waitForScratchPool());
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::beginSession"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::endSession(void)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
CRmsNTMS::endSession
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
WsbTraceIn( OLESTR("CRmsNTMS::endSession"), OLESTR("") );
|
||
|
||
try {
|
||
|
||
if ( m_SessionHandle != INVALID_HANDLE_VALUE ) {
|
||
// NTMS - Close session
|
||
WsbTraceAlways(OLESTR("CloseNtmsSession()\n"));
|
||
WsbAffirmNoError(CloseNtmsSession(m_SessionHandle));
|
||
}
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_CONNECTION_UNAVAIL:
|
||
case ERROR_INVALID_HANDLE:
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("CloseNtmsSession"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
);
|
||
|
||
m_SessionHandle = INVALID_HANDLE_VALUE;
|
||
hr = S_OK;
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::endSession"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::waitUntilReady(void)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
WsbTraceIn(OLESTR("CRmsNTMS::waitUntilReady"), OLESTR(""));
|
||
|
||
try {
|
||
|
||
int retry = 360; // number of retries
|
||
|
||
// Retrieve the NotificationWaitTime parameter
|
||
DWORD size;
|
||
OLECHAR tmpString[256];
|
||
DWORD notificationWaitTime = RMS_DEFAULT_NOTIFICATION_WAIT_TIME;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_NOTIFICATION_WAIT_TIME, tmpString, 256, &size))) {
|
||
notificationWaitTime = wcstol(tmpString, NULL, 10);
|
||
WsbTrace(OLESTR("NotificationWaitTime is %d milliseconds.\n"), notificationWaitTime);
|
||
}
|
||
|
||
|
||
do {
|
||
// NTMS - Open session
|
||
WsbTraceAlways(OLESTR("OpenNtmsSession()\n"));
|
||
|
||
CWsbStringPtr appName;
|
||
WsbAffirmHr(appName.LoadFromRsc(_Module.m_hInst, IDS_PRODUCT_NAME));
|
||
|
||
m_SessionHandle = OpenNtmsSession(NULL, (WCHAR *) appName, 0);
|
||
if ( m_SessionHandle != INVALID_HANDLE_VALUE ) {
|
||
break;
|
||
}
|
||
else {
|
||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_NOT_READY:
|
||
if ( retry > 0 ) {
|
||
WsbTrace(OLESTR("Waiting for NTMS to come ready - Seconds remaining before timeout: %d\n"), retry*notificationWaitTime/1000);
|
||
Sleep(notificationWaitTime);
|
||
hr = S_OK;
|
||
}
|
||
else {
|
||
//
|
||
// This is the last try, so log the failure.
|
||
//
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_CONNECTION_NOT_ESABLISHED,
|
||
0, NULL, WsbHrAsString(hr), NULL);
|
||
WsbThrow(RMS_E_NTMS_NOT_CONNECTED);
|
||
}
|
||
break;
|
||
|
||
case ERROR_INVALID_COMPUTERNAME:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NO_NETWORK:
|
||
case ERROR_NOT_CONNECTED:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_CONNECTION_NOT_ESABLISHED,
|
||
0, NULL, WsbHrAsString(hr), NULL);
|
||
WsbThrow(hr);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("OpenNtmsSession"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
WsbThrow(hr);
|
||
break;
|
||
}
|
||
}
|
||
} while( retry-- > 0 ) ;
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::waitUntilReady"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::waitForScratchPool(void)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
DWORD err2 = NO_ERROR;
|
||
DWORD err3 = NO_ERROR;
|
||
HANDLE hNotify = INVALID_HANDLE_VALUE;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::waitForScratchPool"), OLESTR(""));
|
||
|
||
try {
|
||
|
||
int retry = 60; // number of retries
|
||
|
||
// Retrieve the NotificationWaitTime parameter
|
||
DWORD size;
|
||
OLECHAR tmpString[256];
|
||
DWORD notificationWaitTime = RMS_DEFAULT_NOTIFICATION_WAIT_TIME;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_NOTIFICATION_WAIT_TIME, tmpString, 256, &size))) {
|
||
notificationWaitTime = wcstol(tmpString, NULL, 10);
|
||
WsbTrace(OLESTR("NotificationWaitTime is %d milliseconds.\n"), notificationWaitTime);
|
||
}
|
||
|
||
if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
|
||
WsbThrow(E_UNEXPECTED);
|
||
}
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
|
||
NTMS_OBJECTINFORMATION objectInfo;
|
||
NTMS_OBJECTINFORMATION scratchInfo;
|
||
NTMS_NOTIFICATIONINFORMATION notifyInfo;
|
||
HANDLE hFind = NULL;
|
||
|
||
BOOL bFound = FALSE;
|
||
|
||
// TODO: We really should wait around until all libraries are classified.
|
||
DWORD mediaCount = 0;
|
||
|
||
hr = findFirstNtmsObject( NTMS_LIBRARY, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
|
||
while( S_OK == hr ) {
|
||
reportNtmsObjectInformation( &objectInfo );
|
||
mediaCount += objectInfo.Info.Library.dwNumberOfMedia;
|
||
hr = findNextNtmsObject( hFind, &objectInfo );
|
||
}
|
||
findCloseNtmsObject( hFind );
|
||
|
||
if ( 0 == mediaCount) {
|
||
WsbThrow( RMS_E_NTMS_OBJECT_NOT_FOUND );
|
||
}
|
||
|
||
/*
|
||
// First see if there is any media to be classified, if not we don't bother waiting around for
|
||
// nothing to happen.
|
||
hr = findFirstNtmsObject( NTMS_PHYSICAL_MEDIA, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
|
||
WsbAffirmHrOk( hr );
|
||
findCloseNtmsObject( hFind );
|
||
*/
|
||
|
||
// NTMS - Open notification channel
|
||
WsbTraceAlways(OLESTR("OpenNtmsNotification()\n"));
|
||
hNotify = OpenNtmsNotification(hSession, NTMS_MEDIA_POOL);
|
||
if ( INVALID_HANDLE_VALUE == hNotify ) {
|
||
err1 = GetLastError();
|
||
WsbAffirmNoError(err1);
|
||
WsbThrow(E_UNEXPECTED);
|
||
}
|
||
|
||
do {
|
||
err2 = NO_ERROR;
|
||
//
|
||
// Count the number of NTMS Scratch pools, and if
|
||
// there are more than one, we return. If not,
|
||
// we wait until the root level scratch pool object
|
||
// is updated.
|
||
//
|
||
// More that one scratch media pools implies that at
|
||
// least one unit of media was classified. We don't
|
||
// know until we complete the initialization if it
|
||
// was one of the media types supported by RemoteStorage.
|
||
//
|
||
int count = 0;
|
||
|
||
hr = findFirstNtmsObject( NTMS_MEDIA_POOL, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
|
||
while( S_OK == hr ) {
|
||
if ( NTMS_POOLTYPE_SCRATCH == objectInfo.Info.MediaPool.PoolType ) {
|
||
count++;
|
||
if ( count == 1 ) {
|
||
// Assueme this is the rool pool and one we'll check on for updates
|
||
// If the assumption is wrong count will end up > 1.
|
||
memcpy(&scratchInfo, &objectInfo, sizeof(NTMS_OBJECTINFORMATION));
|
||
}
|
||
}
|
||
hr = findNextNtmsObject( hFind, &objectInfo );
|
||
}
|
||
findCloseNtmsObject( hFind );
|
||
|
||
if ( count > 1 ) {
|
||
bFound = TRUE;
|
||
hr = S_OK;
|
||
break; // Normal exit.
|
||
}
|
||
|
||
if ( count == 0 ) {
|
||
WsbThrow(E_UNEXPECTED);
|
||
}
|
||
|
||
// Just one scratch pool detected... wait until a media-type specific pool
|
||
// is added root scratch pool. This will show up as an update to the root
|
||
// scratch pool.
|
||
|
||
do {
|
||
|
||
WsbTrace(OLESTR("Waiting for NTMS scratch pool - Seconds remaining before timeout: %d\n"), retry*notificationWaitTime/1000);
|
||
|
||
// NTMS - Wait for notification
|
||
WsbTraceAlways(OLESTR("WaitForNtmsNotification()\n"));
|
||
err2 = WaitForNtmsNotification(hNotify, ¬ifyInfo, notificationWaitTime);
|
||
if ( NO_ERROR == err2 ) {
|
||
//
|
||
// Note: With this notification mechanism, chances
|
||
// are slim that we got notified on the object we really
|
||
// care about.
|
||
//
|
||
WsbTrace(OLESTR("Processing: <%d> %ls\n"), notifyInfo.dwOperation, WsbGuidAsString(notifyInfo.ObjectId));
|
||
if ( notifyInfo.ObjectId != scratchInfo.ObjectGuid ) {
|
||
WsbTrace(OLESTR("Wrong object, try again...\n"));
|
||
continue; // skip this one
|
||
}
|
||
else {
|
||
if ( NTMS_OBJ_UPDATE != notifyInfo.dwOperation ) {
|
||
WsbTrace(OLESTR("Wrong operation, try again...\n"));
|
||
continue; // skip this one
|
||
}
|
||
else {
|
||
WsbTrace(OLESTR("Scratch pool update detected.\n"));
|
||
break; // A scratch pool may have inserted, go check it out...
|
||
}
|
||
}
|
||
}
|
||
else if ( ERROR_TIMEOUT != err2 && ERROR_NO_DATA != err2 ) {
|
||
WsbAffirmNoError(err2);
|
||
}
|
||
retry--;
|
||
} while( (retry > 0) && (!bFound) );
|
||
} while( (retry > 0) && (!bFound) );
|
||
|
||
// NTMS - Close notification channel
|
||
WsbTraceAlways(OLESTR("CloseNtmsNotification()\n"));
|
||
err3 = CloseNtmsNotification(hNotify);
|
||
WsbAffirmNoError(err3);
|
||
|
||
if ( !bFound ) {
|
||
hr = RMS_E_RESOURCE_UNAVAILABLE;
|
||
}
|
||
|
||
} WsbCatchAndDo(hr,
|
||
|
||
if ( hNotify != INVALID_HANDLE_VALUE ) {
|
||
// NTMS - Close notification channel
|
||
WsbTraceAlways(OLESTR("CloseNtmsNotification()\n"));
|
||
err3 = CloseNtmsNotification(hNotify);
|
||
}
|
||
|
||
if (err1 != NO_ERROR) {
|
||
// OpenNtmsNotification
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("OpenNtmsNotification"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("OpenNtmsNotification"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
if (err2 != NO_ERROR) {
|
||
// WaitForNtmsNotification
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_TIMEOUT:
|
||
case ERROR_NO_DATA:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("WaitForNtmsNotification"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("WaitForNtmsNotification"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
if (err3 != NO_ERROR) {
|
||
// CloseNtmsNotification
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case ERROR_DATABASE_FAILURE:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("CloseNtmsNotification"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("CloseNtmsNotification"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::waitForScratchPool"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::storageMediaTypeToRmsMedia(
|
||
IN NTMS_MEDIATYPEINFORMATION *pMediaTypeInfo,
|
||
OUT RmsMedia *pTranslatedMediaType)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
DWORD size;
|
||
OLECHAR tmpString[256];
|
||
|
||
// Media type is the main criteria
|
||
WsbAssertPointer(pMediaTypeInfo);
|
||
STORAGE_MEDIA_TYPE mediaType = (STORAGE_MEDIA_TYPE)(pMediaTypeInfo->MediaType);
|
||
|
||
DWORD tapeEnabled = RMS_DEFAULT_TAPE;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_TAPE, tmpString, 256, &size))) {
|
||
// Get the value.
|
||
tapeEnabled = wcstol(tmpString, NULL, 10);
|
||
}
|
||
|
||
DWORD opticalEnabled = RMS_DEFAULT_OPTICAL;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_OPTICAL, tmpString, 256, &size))) {
|
||
// Get the value.
|
||
opticalEnabled = wcstol(tmpString, NULL, 10);
|
||
}
|
||
|
||
DWORD dvdEnabled = RMS_DEFAULT_DVD;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_DVD, tmpString, 256, &size))) {
|
||
// Get the value.
|
||
dvdEnabled = wcstol(tmpString, NULL, 10);
|
||
}
|
||
|
||
switch ( mediaType ) {
|
||
|
||
case DDS_4mm: // Tape - DAT DDS1,2,... (all vendors) (0x20)
|
||
*pTranslatedMediaType = (tapeEnabled) ? RmsMedia4mm : RmsMediaUnknown;
|
||
break;
|
||
|
||
case MiniQic: // Tape - miniQIC Tape
|
||
case Travan: // Tape - Travan TR-1,2,3,...
|
||
case QIC: // Tape - QIC
|
||
*pTranslatedMediaType = RmsMediaUnknown;
|
||
break;
|
||
|
||
case MP_8mm: // Tape - 8mm Exabyte Metal Particle
|
||
case AME_8mm: // Tape - 8mm Exabyte Advanced Metal Evap
|
||
case AIT1_8mm: // Tape - 8mm Sony AIT1
|
||
*pTranslatedMediaType = (tapeEnabled) ? RmsMedia8mm : RmsMediaUnknown;
|
||
break;
|
||
|
||
case DLT: // Tape - DLT Compact IIIxt: IV
|
||
*pTranslatedMediaType = (tapeEnabled) ? RmsMediaDLT : RmsMediaUnknown;
|
||
break;
|
||
|
||
case NCTP: // Tape - Philips NCTP
|
||
case IBM_3480: // Tape - IBM 3480
|
||
case IBM_3490E: // Tape - IBM 3490E
|
||
case IBM_Magstar_3590: // Tape - IBM Magstar 3590
|
||
case IBM_Magstar_MP: // Tape - IBM Magstar MP
|
||
case STK_DATA_D3: // Tape - STK Data D3
|
||
case SONY_DTF: // Tape - Sony DTF
|
||
case DV_6mm: // Tape - 6mm Digital Video
|
||
case DMI: // Tape - Exabyte DMI and compatibles
|
||
case SONY_D2: // Tape - Sony D2S and D2L
|
||
case CLEANER_CARTRIDGE: // Cleaner - All Drive types that support Drive Cleaners
|
||
case CD_ROM: // Opt_Disk - CD
|
||
case CD_R: // Opt_Disk - CD-Recordable (Write Once)
|
||
case CD_RW: // Opt_Disk - CD-Rewriteable
|
||
case DVD_ROM: // Opt_Disk - DVD-ROM
|
||
case DVD_R: // Opt_Disk - DVD-Recordable (Write Once)
|
||
case MO_5_WO: // Opt_Disk - MO 5.25" Write Once
|
||
*pTranslatedMediaType = RmsMediaUnknown;
|
||
break;
|
||
|
||
case DVD_RW: // Opt_Disk - DVD-Rewriteable
|
||
*pTranslatedMediaType = (dvdEnabled) ? RmsMediaDVD : RmsMediaUnknown;
|
||
break;
|
||
|
||
case MO_5_RW: // Opt_Disk - MO 5.25" Rewriteable (not LIMDOW)
|
||
case MO_3_RW: // Opt_Disk - 3.5" Rewriteable MO Disk
|
||
case MO_5_LIMDOW: // Opt_Disk - MO 5.25" Rewriteable (LIMDOW)
|
||
case PC_5_RW: // Opt_Disk - Phase Change 5.25" Rewriteable
|
||
case PD_5_RW: // Opt_Disk - PhaseChange Dual Rewriteable
|
||
case PINNACLE_APEX_5_RW: // Opt_Disk - Pinnacle Apex 4.6GB Rewriteable Optical
|
||
case NIKON_12_RW: // Opt_Disk - Nikon 12" Rewriteable
|
||
*pTranslatedMediaType = (opticalEnabled) ? RmsMediaOptical : RmsMediaUnknown;
|
||
break;
|
||
|
||
case PC_5_WO: // Opt_Disk - Phase Change 5.25" Write Once Optical
|
||
case ABL_5_WO: // Opt_Disk - Ablative 5.25" Write Once Optical
|
||
*pTranslatedMediaType = RmsMediaUnknown;
|
||
break;
|
||
|
||
case SONY_12_WO: // Opt_Disk - Sony 12" Write Once
|
||
case PHILIPS_12_WO: // Opt_Disk - Philips/LMS 12" Write Once
|
||
case HITACHI_12_WO: // Opt_Disk - Hitachi 12" Write Once
|
||
case CYGNET_12_WO: // Opt_Disk - Cygnet/ATG 12" Write Once
|
||
case KODAK_14_WO: // Opt_Disk - Kodak 14" Write Once
|
||
case MO_NFR_525: // Opt_Disk - Near Field Recording (Terastor)
|
||
case IOMEGA_ZIP: // Mag_Disk - Iomega Zip
|
||
case IOMEGA_JAZ: // Mag_Disk - Iomega Jaz
|
||
case SYQUEST_EZ135: // Mag_Disk - Syquest EZ135
|
||
case SYQUEST_EZFLYER: // Mag_Disk - Syquest EzFlyer
|
||
case SYQUEST_SYJET: // Mag_Disk - Syquest SyJet
|
||
case AVATAR_F2: // Mag_Disk - 2.5" Floppy
|
||
*pTranslatedMediaType = RmsMediaUnknown;
|
||
break;
|
||
|
||
case RemovableMedia: // This is reported on stand-alone optical drives.
|
||
default:
|
||
// Check RSM characteristics for Rewriteable Disk
|
||
if ((pMediaTypeInfo->ReadWriteCharacteristics == NTMS_MEDIARW_REWRITABLE) &&
|
||
(pMediaTypeInfo->DeviceType == FILE_DEVICE_DISK)) {
|
||
*pTranslatedMediaType = (opticalEnabled) ? RmsMediaOptical : RmsMediaUnknown;
|
||
} else {
|
||
// Not a rewritable disk and not one of the supported tape types...
|
||
*pTranslatedMediaType = RmsMediaUnknown;
|
||
}
|
||
break;
|
||
}
|
||
|
||
if ((*pTranslatedMediaType == RmsMediaUnknown) &&
|
||
(pMediaTypeInfo->DeviceType == FILE_DEVICE_TAPE)) {
|
||
// Check in the Registry whether there are additional tapes that we need to support
|
||
ULONG *pTypes= NULL;
|
||
ULONG uTypes = 0;
|
||
|
||
if (SUCCEEDED(WsbGetRegistryValueUlongAsMultiString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_ADDITIONAL_TAPE, &pTypes, &uTypes))) {
|
||
// Compare Registry types to the media type we have
|
||
for (ULONG u=0; u<uTypes; u++) {
|
||
if ((STORAGE_MEDIA_TYPE)(pTypes[u]) == mediaType) {
|
||
// Support it !!
|
||
WsbTraceAlways(OLESTR("CRmsNTMS::storageMediaTypeToRmsMedia: Registry asks to support tape type %lu\n"),
|
||
pTypes[u]);
|
||
|
||
*pTranslatedMediaType = RmsMediaTape;
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (pTypes != NULL) {
|
||
WsbFree(pTypes);
|
||
pTypes = NULL;
|
||
}
|
||
}
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::createMediaPools(void)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::createMediaPools"), OLESTR(""));
|
||
|
||
try {
|
||
|
||
HANDLE hSession;
|
||
NTMS_GUID rootPoolId = GUID_NULL;
|
||
|
||
if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
|
||
WsbAffirmHr(beginSession());
|
||
}
|
||
|
||
hSession = m_SessionHandle;
|
||
|
||
try {
|
||
|
||
// NTMS - Create Application Media Pool.
|
||
WsbTraceAlways(OLESTR("CreateNtmsMediaPool()\n"));
|
||
|
||
WsbAffirmNoError(CreateNtmsMediaPool(hSession, REMOTE_STORAGE_APP_NAME, NULL, NTMS_OPEN_ALWAYS, NULL, &rootPoolId));
|
||
|
||
// Now set access permissions on the pool: turn off ordinary users access
|
||
WsbAffirmHrOk(setPoolDACL(&rootPoolId, DOMAIN_ALIAS_RID_USERS, REMOVE_ACE_MASK_BITS,NTMS_USE_ACCESS | NTMS_MODIFY_ACCESS | NTMS_CONTROL_ACCESS));
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch(HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_NAME:
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
case ERROR_ALREADY_EXISTS:
|
||
case ERROR_ACCESS_DENIED:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_DATABASE_FULL:
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("CreateNtmsMediaPool"), OLESTR(""),
|
||
WsbHrAsString(hr),
|
||
NULL );
|
||
break;
|
||
default:
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("CreateNtmsMediaPool"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr),
|
||
NULL );
|
||
break;
|
||
}
|
||
WsbThrow(hr);
|
||
);
|
||
|
||
//
|
||
// Only one of the following should be executed, comment out the other.
|
||
//
|
||
WsbAffirmHr( createMediaPoolForEveryMediaType(rootPoolId) ); // New way
|
||
/*
|
||
WsbAffirmHr( replicateScratchMediaPool(rootPoolId) ); // Old way
|
||
*/
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::createMediaPools"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::replicateScratchMediaPool(
|
||
IN REFGUID /*rootPoolId*/)
|
||
{
|
||
HRESULT hr = E_FAIL;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::replicateScratchMediaPool"), OLESTR(""));
|
||
|
||
try {
|
||
|
||
HANDLE hSession;
|
||
DWORD errCode;
|
||
NTMS_OBJECTINFORMATION mediaTypeInfo;
|
||
NTMS_OBJECTINFORMATION mediaPoolInfo;
|
||
HANDLE hFind = NULL;
|
||
NTMS_GUID poolId = GUID_NULL;
|
||
|
||
|
||
if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
|
||
WsbAffirmHr(beginSession());
|
||
}
|
||
|
||
hSession = m_SessionHandle;
|
||
|
||
// For each media pool in the scratch pool create an application specific pool.
|
||
|
||
hr = findFirstNtmsObject( NTMS_MEDIA_POOL, GUID_NULL, NULL, GUID_NULL, &hFind, &mediaPoolInfo);
|
||
while( S_OK == hr ) {
|
||
reportNtmsObjectInformation( &mediaPoolInfo );
|
||
poolId = GUID_NULL;
|
||
|
||
try {
|
||
|
||
// Set up application specific NTMS Media Pools. One for each compatible type.
|
||
//
|
||
// To get here we had to already detect a media-type specific scratch pool
|
||
// in waitForScratchPool()
|
||
|
||
if ( NTMS_POOLTYPE_SCRATCH == mediaPoolInfo.Info.MediaPool.PoolType &&
|
||
0 == mediaPoolInfo.Info.MediaPool.dwNumberOfMediaPools ) {
|
||
|
||
// This is a base level scratch media pool.
|
||
// Create a similar pool for application specific use.
|
||
|
||
CWsbStringPtr name = REMOTE_STORAGE_APP_NAME;
|
||
name.Append( OLESTR("\\") );
|
||
name.Append( mediaPoolInfo.szName );
|
||
|
||
NTMS_GUID mediaTypeId = mediaPoolInfo.Info.MediaPool.MediaType;
|
||
|
||
// We need more information about the media type.
|
||
|
||
memset( &mediaTypeInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
mediaTypeInfo.dwType = NTMS_MEDIA_TYPE;
|
||
mediaTypeInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
|
||
// NTMS - Get Media Pool Information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
|
||
errCode = GetNtmsObjectInformation( hSession, &mediaTypeId, &mediaTypeInfo );
|
||
if ( errCode != NO_ERROR ) {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
// Translate the NTMS media type into something understood by RMS
|
||
RmsMedia translatedMediaType;
|
||
storageMediaTypeToRmsMedia(&(mediaTypeInfo.Info.MediaType), &translatedMediaType);
|
||
|
||
if ( translatedMediaType != RmsMediaUnknown ) {
|
||
|
||
// This something that Remote Storage can deal with
|
||
|
||
CWsbBstrPtr mediaSetName = RMS_UNDEFINED_STRING;
|
||
CWsbBstrPtr mediaSetDesc = RMS_UNDEFINED_STRING;
|
||
BOOL mediaSetIsEnabled = FALSE;
|
||
|
||
// NTMS - Create Application Media Pool.
|
||
WsbTraceAlways(OLESTR("CreateNtmsMediaPool()\n"));
|
||
errCode = CreateNtmsMediaPool( hSession, (WCHAR *) name, &mediaTypeId, NTMS_CREATE_NEW, NULL, &poolId );
|
||
|
||
if ( ERROR_ALREADY_EXISTS == errCode ) {
|
||
|
||
// We still need the poolId of the existing pool.
|
||
|
||
// NTMS - Create Application Media Pool.
|
||
WsbTraceAlways(OLESTR("CreateNtmsMediaPool()\n"));
|
||
errCode = CreateNtmsMediaPool( hSession, (WCHAR *)name, &mediaTypeId, NTMS_OPEN_EXISTING, NULL, &poolId );
|
||
if ( errCode != NO_ERROR ) {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("CreateNtmsMediaPool"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
NTMS_OBJECTINFORMATION mediaPoolInfo;
|
||
|
||
memset( &mediaPoolInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
|
||
mediaPoolInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
|
||
// NTMS - Get Media Pool Information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
|
||
errCode = GetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
|
||
if ( errCode != NO_ERROR ) {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
}
|
||
|
||
// Save relevant info
|
||
mediaSetName = mediaPoolInfo.szName;
|
||
mediaSetDesc = mediaPoolInfo.szDescription;
|
||
mediaSetIsEnabled = mediaPoolInfo.Enabled;
|
||
|
||
}
|
||
else if ( NO_ERROR == errCode ) {
|
||
|
||
memset( &mediaPoolInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
|
||
mediaPoolInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
|
||
// NTMS - Get Media Pool Information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
|
||
errCode = GetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
|
||
if ( errCode != NO_ERROR ) {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
WsbAssert( NTMS_POOLTYPE_APPLICATION == mediaPoolInfo.Info.MediaPool.PoolType, E_UNEXPECTED );
|
||
|
||
// Set media pool parameters
|
||
|
||
// Aallocation/deallocation policy
|
||
mediaPoolInfo.Info.MediaPool.AllocationPolicy = NTMS_ALLOCATE_FROMSCRATCH;
|
||
mediaPoolInfo.Info.MediaPool.DeallocationPolicy = 0;
|
||
|
||
// Max number of allocates per media
|
||
mediaPoolInfo.Info.MediaPool.dwMaxAllocates = 5;// Just a few... we automatically
|
||
// deallocate media if there's
|
||
// problem with scratch mount
|
||
// operation.
|
||
// NOTE: This can be overridden using
|
||
// the NTMS GUI.
|
||
|
||
// NTMS - Set Media Pool Information.
|
||
WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
|
||
errCode = SetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
|
||
if ( errCode != NO_ERROR ) {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("SetNtmsObjectInformation"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
// Save relevant info
|
||
mediaSetName = mediaPoolInfo.szName;
|
||
mediaSetDesc = mediaPoolInfo.szDescription;
|
||
mediaSetIsEnabled = mediaPoolInfo.Enabled;
|
||
|
||
}
|
||
else {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("CreateNtmsMediaPool"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
// Now we have an NTMS media pool for our specific use. Now expose it
|
||
// through the RMS interface by creating a CRmsMediaSet.
|
||
|
||
if ( poolId != GUID_NULL ) {
|
||
CComPtr<IRmsMediaSet> pMediaSet;
|
||
|
||
// Find the RmsMediaSet with the same id, or create a new one.
|
||
CComQIPtr<IRmsServer, &IID_IRmsServer> pServer = g_pServer;
|
||
WsbAffirmHr( pServer->CreateObject( poolId, CLSID_CRmsMediaSet, IID_IRmsMediaSet, RmsOpenAlways, (void **)&pMediaSet ) );
|
||
|
||
WsbTrace(OLESTR("CRmsNTMS::replicateScratchMediaPool - type %d CRmsMediaSet created.\n"), translatedMediaType);
|
||
|
||
WsbAffirmHr( pMediaSet->SetMediaSetType( RmsMediaSetNTMS ) );
|
||
WsbAffirmHr( pMediaSet->SetMediaSupported( translatedMediaType ) );
|
||
|
||
CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = pMediaSet;
|
||
WsbTrace(OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType - MediaSet: <%ls/%ls>; Enabled: %ls\n"),
|
||
WsbQuickString(WsbStringAsString(mediaSetName)),
|
||
WsbQuickString(WsbStringAsString(mediaSetDesc)),
|
||
WsbQuickString(WsbBoolAsString(mediaSetIsEnabled)));
|
||
WsbAffirmHr(pObject->SetName(mediaSetName));
|
||
WsbAffirmHr(pObject->SetDescription(mediaSetDesc));
|
||
if (!mediaSetIsEnabled) {
|
||
WsbAffirmHr(pObject->Disable(E_FAIL));
|
||
}
|
||
|
||
if (S_OK == IsMediaCopySupported(poolId)) {
|
||
WsbAffirmHr( pMediaSet->SetIsMediaCopySupported(TRUE));
|
||
}
|
||
hr = pMediaSet->IsMediaCopySupported();
|
||
|
||
WsbTrace(OLESTR("CRmsNTMS::replicateScratchMediaPool - media copies are %ls.\n"),
|
||
(S_OK == pMediaSet->IsMediaCopySupported()) ? OLESTR("enabled") : OLESTR("disabled"));
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
} WsbCatch(hr);
|
||
|
||
hr = findNextNtmsObject( hFind, &mediaPoolInfo );
|
||
} // while finding media pools
|
||
findCloseNtmsObject( hFind );
|
||
|
||
hr = S_OK;
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::replicateScratchMediaPool"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::createMediaPoolForEveryMediaType(
|
||
IN REFGUID /*rootPoolId*/)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType"), OLESTR(""));
|
||
|
||
try {
|
||
DWORD errCode;
|
||
|
||
if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
|
||
WsbAffirmHr(beginSession());
|
||
}
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
|
||
HANDLE hFindLib = NULL;
|
||
NTMS_OBJECTINFORMATION libraryInfo;
|
||
|
||
BOOL bSupportedLib = FALSE;
|
||
m_dwNofLibs = 0;
|
||
|
||
hr = findFirstNtmsObject( NTMS_LIBRARY, GUID_NULL, NULL, GUID_NULL, &hFindLib, &libraryInfo);
|
||
while( S_OK == hr ) {
|
||
bSupportedLib = FALSE;
|
||
|
||
reportNtmsObjectInformation( &libraryInfo );
|
||
|
||
if (libraryInfo.Info.Library.dwNumberOfMediaTypes > 0) {
|
||
|
||
HANDLE hFindType = NULL;
|
||
NTMS_OBJECTINFORMATION mediaTypeInfo;
|
||
|
||
hr = findFirstNtmsObject( NTMS_MEDIA_TYPE, libraryInfo.ObjectGuid, NULL, GUID_NULL, &hFindType, &mediaTypeInfo);
|
||
while( S_OK == hr ) {
|
||
//
|
||
// Create an application Media Pool for each type
|
||
//
|
||
|
||
NTMS_GUID poolId;
|
||
|
||
// This is a base level scratch media pool.
|
||
// Create a similar pool for application specific use.
|
||
|
||
CWsbStringPtr name = REMOTE_STORAGE_APP_NAME;
|
||
name.Append( OLESTR("\\") );
|
||
name.Append( mediaTypeInfo.szName );
|
||
|
||
NTMS_GUID mediaTypeId = mediaTypeInfo.ObjectGuid;
|
||
|
||
// Translate the NTMS media type into something understood by RMS
|
||
RmsMedia translatedMediaType;
|
||
storageMediaTypeToRmsMedia(&(mediaTypeInfo.Info.MediaType), &translatedMediaType);
|
||
|
||
if ( translatedMediaType != RmsMediaUnknown ) {
|
||
|
||
// This something that Remote Storage can deal with
|
||
|
||
CWsbBstrPtr mediaSetName = RMS_UNDEFINED_STRING;
|
||
CWsbBstrPtr mediaSetDesc = RMS_UNDEFINED_STRING;
|
||
BOOL mediaSetIsEnabled = FALSE;
|
||
|
||
// NTMS - Create Application Media Pool.
|
||
WsbTraceAlways(OLESTR("CreateNtmsMediaPool(<%ls>) - Try New.\n"), (WCHAR *) name);
|
||
errCode = CreateNtmsMediaPool( hSession, (WCHAR *) name, &mediaTypeId, NTMS_CREATE_NEW, NULL, &poolId );
|
||
|
||
if ( ERROR_ALREADY_EXISTS == errCode ) {
|
||
WsbTraceAlways(OLESTR("MediaPool <%ls> already exists.\n"), (WCHAR *) name);
|
||
|
||
// We still need the poolId of the existing pool.
|
||
|
||
// NTMS - Create Application Media Pool.
|
||
WsbTraceAlways(OLESTR("CreateNtmsMediaPool(<%ls>) - Try Existing.\n"), (WCHAR *) name);
|
||
errCode = CreateNtmsMediaPool( hSession, (WCHAR *)name, &mediaTypeId, NTMS_OPEN_EXISTING, NULL, &poolId );
|
||
if ( errCode != NO_ERROR ) {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("CreateNtmsMediaPool"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
WsbTraceAlways(OLESTR("Media Pool %ls detected.\n"), WsbGuidAsString(poolId));
|
||
|
||
NTMS_OBJECTINFORMATION mediaPoolInfo;
|
||
|
||
memset( &mediaPoolInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
|
||
mediaPoolInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
|
||
// NTMS - Get Media Pool Information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
|
||
errCode = GetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
|
||
if ( errCode != NO_ERROR ) {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
// Save relevant info
|
||
mediaSetName = mediaPoolInfo.szName;
|
||
mediaSetDesc = mediaPoolInfo.szDescription;
|
||
mediaSetIsEnabled = mediaPoolInfo.Enabled;
|
||
|
||
}
|
||
else if ( NO_ERROR == errCode ) {
|
||
WsbTraceAlways(OLESTR("MediaPool <%ls> created.\n"), (WCHAR *) name);
|
||
|
||
NTMS_OBJECTINFORMATION mediaPoolInfo;
|
||
|
||
memset( &mediaPoolInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
|
||
mediaPoolInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
|
||
// NTMS - Get Media Pool Information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
|
||
errCode = GetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
|
||
if ( errCode != NO_ERROR ) {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
WsbAssert( NTMS_POOLTYPE_APPLICATION == mediaPoolInfo.Info.MediaPool.PoolType, E_UNEXPECTED );
|
||
|
||
// Set media pool parameters
|
||
|
||
// Aallocation/deallocation policy
|
||
mediaPoolInfo.Info.MediaPool.AllocationPolicy = NTMS_ALLOCATE_FROMSCRATCH;
|
||
mediaPoolInfo.Info.MediaPool.DeallocationPolicy = 0;
|
||
|
||
// Max number of allocates per media
|
||
mediaPoolInfo.Info.MediaPool.dwMaxAllocates = 0;// Unlimited... we automatically
|
||
// deallocate media if there's
|
||
// problem with scratch mount
|
||
// operation.
|
||
// TODO: Verify that NTMS always allocates
|
||
// media with the lowest allocation
|
||
// count.
|
||
// NOTE: This can be overridden using
|
||
// the NTMS GUI.
|
||
|
||
// NTMS - Set Media Pool Information.
|
||
WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
|
||
errCode = SetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
|
||
if ( errCode != NO_ERROR ) {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("SetNtmsObjectInformation"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
// Save relevant info
|
||
mediaSetName = mediaPoolInfo.szName;
|
||
mediaSetDesc = mediaPoolInfo.szDescription;
|
||
mediaSetIsEnabled = mediaPoolInfo.Enabled;
|
||
}
|
||
else {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("CreateNtmsMediaPool"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
// Now set access permissions on the pool: turn off ordinary users access
|
||
WsbAffirmHrOk(setPoolDACL(&poolId, DOMAIN_ALIAS_RID_USERS, REMOVE_ACE_MASK_BITS,NTMS_USE_ACCESS | NTMS_MODIFY_ACCESS | NTMS_CONTROL_ACCESS));
|
||
|
||
|
||
// Now we have an NTMS media pool for our specific use. Now expose it
|
||
// through the RMS interface by creating a CRmsMediaSet.
|
||
|
||
if ( poolId != GUID_NULL ) {
|
||
|
||
//
|
||
// Add to CRmsMediaSet collection
|
||
//
|
||
|
||
CComPtr<IRmsMediaSet> pMediaSet;
|
||
|
||
// Find the CRmsMediaSet with the same id, or create a new one.
|
||
CComQIPtr<IRmsServer, &IID_IRmsServer> pServer = g_pServer;
|
||
WsbAffirmHr( pServer->CreateObject( poolId, CLSID_CRmsMediaSet, IID_IRmsMediaSet, RmsOpenAlways, (void **)&pMediaSet ) );
|
||
|
||
WsbTrace(OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType - type %d CRmsMediaSet established.\n"), translatedMediaType);
|
||
|
||
WsbAffirmHr( pMediaSet->SetMediaSetType( RmsMediaSetNTMS ) );
|
||
WsbAffirmHr( pMediaSet->SetMediaSupported( translatedMediaType ) );
|
||
|
||
CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = pMediaSet;
|
||
WsbTrace(OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType - MediaSet: <%ls/%ls> %ls; Enabled: %ls\n"),
|
||
WsbQuickString(WsbStringAsString(mediaSetName)),
|
||
WsbQuickString(WsbStringAsString(mediaSetDesc)),
|
||
WsbQuickString(WsbGuidAsString(poolId)),
|
||
WsbQuickString(WsbBoolAsString(mediaSetIsEnabled)));
|
||
WsbAffirmHr(pObject->SetName(mediaSetName));
|
||
WsbAffirmHr(pObject->SetDescription(mediaSetDesc));
|
||
if (!mediaSetIsEnabled) {
|
||
WsbAffirmHr(pObject->Disable(E_FAIL));
|
||
}
|
||
|
||
if (S_OK == IsMediaCopySupported(poolId)) {
|
||
WsbAffirmHr( pMediaSet->SetIsMediaCopySupported(TRUE));
|
||
}
|
||
hr = pMediaSet->IsMediaCopySupported();
|
||
|
||
WsbTrace(OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType - media copies are %ls.\n"),
|
||
(S_OK == pMediaSet->IsMediaCopySupported()) ? OLESTR("enabled") : OLESTR("disabled"));
|
||
|
||
}
|
||
|
||
// The library has a supported media type
|
||
bSupportedLib = TRUE;
|
||
}
|
||
hr = findNextNtmsObject( hFindType, &mediaTypeInfo );
|
||
}
|
||
findCloseNtmsObject( hFindType );
|
||
}
|
||
|
||
// Check if the library has supported media type
|
||
if (bSupportedLib) {
|
||
// Add library GUI to the libraries list
|
||
// (Realloc one item each time since we don't expect many items)
|
||
m_dwNofLibs++;
|
||
LPVOID pTemp = WsbRealloc(m_pLibGuids, m_dwNofLibs*sizeof(NTMS_GUID));
|
||
if (!pTemp) {
|
||
WsbThrow(E_OUTOFMEMORY);
|
||
}
|
||
m_pLibGuids = (LPNTMS_GUID)pTemp;
|
||
m_pLibGuids[m_dwNofLibs-1] = libraryInfo.ObjectGuid;
|
||
}
|
||
|
||
// Continue library enumeration
|
||
hr = findNextNtmsObject( hFindLib, &libraryInfo );
|
||
}
|
||
findCloseNtmsObject( hFindLib );
|
||
|
||
hr = S_OK;
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::Allocate(
|
||
IN REFGUID fromMediaSet,
|
||
IN REFGUID prevSideId,
|
||
IN OUT LONGLONG *pFreeSpace,
|
||
IN BSTR displayName,
|
||
IN DWORD dwOptions,
|
||
OUT IRmsCartridge **ppCartridge)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::Allocate
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
DWORD err2 = NO_ERROR;
|
||
DWORD err3 = NO_ERROR;
|
||
DWORD err4 = NO_ERROR;
|
||
DWORD err5 = NO_ERROR;
|
||
DWORD err6 = NO_ERROR;
|
||
DWORD err7 = NO_ERROR;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::Allocate"), OLESTR("<%ls> <%ls> <%ls> <%ls> <0x%08x"),
|
||
WsbGuidAsString(fromMediaSet), WsbGuidAsString(prevSideId),
|
||
WsbPtrToLonglongAsString(pFreeSpace), WsbStringAsString(displayName), dwOptions);
|
||
|
||
try {
|
||
WsbAssert(fromMediaSet != GUID_NULL, E_INVALIDARG);
|
||
WsbAssertPointer(ppCartridge);
|
||
|
||
// Retrieve the AllocateWaitTime and RequestWaitTime parameters
|
||
DWORD size;
|
||
OLECHAR tmpString[256];
|
||
DWORD allocateWaitTime;
|
||
DWORD requestWaitTime;
|
||
|
||
BOOL bShortTimeout = ( dwOptions & RMS_SHORT_TIMEOUT ) ? TRUE : FALSE;
|
||
|
||
if (bShortTimeout) {
|
||
allocateWaitTime = RMS_DEFAULT_SHORT_WAIT_TIME;
|
||
requestWaitTime = RMS_DEFAULT_SHORT_WAIT_TIME;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_SHORT_WAIT_TIME, tmpString, 256, &size))) {
|
||
allocateWaitTime = wcstol(tmpString, NULL, 10);
|
||
requestWaitTime = wcstol(tmpString, NULL, 10);
|
||
WsbTrace(OLESTR("allocateWaitTime (Short) is %d milliseconds.\n"), allocateWaitTime);
|
||
WsbTrace(OLESTR("RequestWaitTime (Short) is %d milliseconds.\n"), requestWaitTime);
|
||
}
|
||
} else {
|
||
allocateWaitTime = RMS_DEFAULT_ALLOCATE_WAIT_TIME;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_ALLOCATE_WAIT_TIME, tmpString, 256, &size))) {
|
||
allocateWaitTime = wcstol(tmpString, NULL, 10);
|
||
WsbTrace(OLESTR("AllocateWaitTime is %d milliseconds.\n"), allocateWaitTime);
|
||
}
|
||
requestWaitTime = RMS_DEFAULT_REQUEST_WAIT_TIME;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_REQUEST_WAIT_TIME, tmpString, 256, &size))) {
|
||
requestWaitTime = wcstol(tmpString, NULL, 10);
|
||
WsbTrace(OLESTR("RequestWaitTime is %d milliseconds.\n"), requestWaitTime);
|
||
}
|
||
}
|
||
|
||
// Special error recovery to handle when NTMS is down, or was cycled.
|
||
do {
|
||
hr = S_OK;
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
NTMS_GUID setId = fromMediaSet;
|
||
NTMS_GUID partId = GUID_NULL;
|
||
NTMS_GUID *pPartId = NULL;
|
||
NTMS_GUID requestId;
|
||
|
||
err1 = NO_ERROR;
|
||
err2 = NO_ERROR;
|
||
err3 = NO_ERROR;
|
||
err4 = NO_ERROR;
|
||
err5 = NO_ERROR;
|
||
err6 = NO_ERROR;
|
||
err7 = NO_ERROR;
|
||
|
||
try {
|
||
|
||
// Look for a specific media ourselves if:
|
||
// 1. A specific capacity is required AND
|
||
// 2. We do not try to allocate a second side
|
||
if (pFreeSpace && (prevSideId == GUID_NULL)) {
|
||
if (*pFreeSpace > 0) {
|
||
int retry = 3; // Give the operator 3 chances to get it right!
|
||
do {
|
||
// We need to allocate a unit of media that matches the capacity specified.
|
||
//
|
||
// Enumerate the partitions in the scratch pool of the same type as
|
||
// specified to find a capatible unit of media
|
||
//
|
||
|
||
// First find the media type we looking for
|
||
NTMS_OBJECTINFORMATION mediaPoolInfo;
|
||
NTMS_OBJECTINFORMATION partitionInfo;
|
||
HANDLE hFindPool = NULL;
|
||
HANDLE hFindPart = NULL;
|
||
BOOL bFound = FALSE;
|
||
NTMS_GUID scratchPoolId;
|
||
|
||
err1 = NO_ERROR;
|
||
err2 = NO_ERROR;
|
||
err3 = NO_ERROR;
|
||
err4 = NO_ERROR;
|
||
err5 = NO_ERROR;
|
||
err6 = NO_ERROR;
|
||
err7 = NO_ERROR;
|
||
|
||
// First look in our pool for scratch media of the correct size
|
||
|
||
hr = findFirstNtmsObject(NTMS_PARTITION, setId, NULL, GUID_NULL, &hFindPart, &partitionInfo);
|
||
while(S_OK == hr) {
|
||
reportNtmsObjectInformation(&partitionInfo);
|
||
if ((TRUE == partitionInfo.Enabled) &&
|
||
(NTMS_READY == partitionInfo.dwOperationalState) &&
|
||
(NTMS_PARTSTATE_AVAILABLE == partitionInfo.Info.Partition.State) &&
|
||
(partitionInfo.Info.Partition.Capacity.QuadPart >= *pFreeSpace)) {
|
||
|
||
NTMS_GUID physicalPartMediaId = partitionInfo.Info.Partition.PhysicalMedia;
|
||
try {
|
||
// Check if the media is online and enabled
|
||
NTMS_OBJECTINFORMATION mediaPartInfo;
|
||
mediaPartInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
mediaPartInfo.dwType = NTMS_PHYSICAL_MEDIA;
|
||
|
||
// NTMS - Get physical media information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
|
||
WsbAffirmNoError( GetNtmsObjectInformation( hSession, &physicalPartMediaId, &mediaPartInfo ) );
|
||
|
||
// Check location type, if enabled & if all new
|
||
if ( (mediaPartInfo.Info.PhysicalMedia.LocationType != NTMS_UNKNOWN)
|
||
&& (mediaPartInfo.Enabled) ) {
|
||
|
||
// Ensure that ALL sides are not allocated yet
|
||
hr = EnsureAllSidesNotAllocated(physicalPartMediaId);
|
||
|
||
if (S_OK == hr) {
|
||
// We'll use this unit of media.
|
||
// Save parameterers required for Allocate.
|
||
bFound = TRUE;
|
||
partId = partitionInfo.ObjectGuid;
|
||
pPartId = &partId;
|
||
break;
|
||
} else if (S_FALSE != hr) {
|
||
WsbAffirmHr(hr);
|
||
}
|
||
}
|
||
|
||
} WsbCatchAndDo (hr,
|
||
WsbTraceAlways(OLESTR("CRmsNTMS::Allocate: Failed to check media <%ls> hr = <%ls>\n"),
|
||
WsbGuidAsString(physicalPartMediaId), WsbHrAsString(hr));
|
||
hr = S_OK;
|
||
)
|
||
}
|
||
|
||
hr = findNextNtmsObject(hFindPart, &partitionInfo);
|
||
} // while finding media pools
|
||
|
||
findCloseNtmsObject(hFindPart);
|
||
hr = S_OK;
|
||
|
||
if (!bFound) {
|
||
|
||
// Now try the Scratch Pool
|
||
|
||
memset(&mediaPoolInfo, 0, sizeof(NTMS_OBJECTINFORMATION));
|
||
|
||
mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
|
||
mediaPoolInfo.dwSize = sizeof(NTMS_OBJECTINFORMATION);
|
||
|
||
// NTMS - Get Media Pool Information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_MEDIA_POOL)\n"));
|
||
err3 = GetNtmsObjectInformation(hSession, &setId, &mediaPoolInfo);
|
||
WsbAffirmNoError( err3 );
|
||
|
||
// Save the media type for the media pool
|
||
NTMS_GUID mediaTypeId = mediaPoolInfo.Info.MediaPool.MediaType;
|
||
|
||
// Find the scratch pool with the same media type
|
||
hr = findFirstNtmsObject(NTMS_MEDIA_POOL, GUID_NULL, NULL, GUID_NULL, &hFindPool, &mediaPoolInfo);
|
||
while(S_OK == hr) {
|
||
if ((NTMS_POOLTYPE_SCRATCH == mediaPoolInfo.Info.MediaPool.PoolType) &&
|
||
(mediaTypeId == mediaPoolInfo.Info.MediaPool.MediaType)) {
|
||
// This is a base level scratch media pool for type we're looking for.
|
||
scratchPoolId = mediaPoolInfo.ObjectGuid;
|
||
|
||
hr = findFirstNtmsObject(NTMS_PARTITION, scratchPoolId, NULL, GUID_NULL, &hFindPart, &partitionInfo);
|
||
while(S_OK == hr) {
|
||
reportNtmsObjectInformation(&partitionInfo);
|
||
if ((TRUE == partitionInfo.Enabled) &&
|
||
(NTMS_READY == partitionInfo.dwOperationalState) &&
|
||
(NTMS_PARTSTATE_AVAILABLE == partitionInfo.Info.Partition.State) &&
|
||
(partitionInfo.Info.Partition.Capacity.QuadPart >= *pFreeSpace)) {
|
||
|
||
// Check if the media is online and enabled
|
||
DWORD errPart = NO_ERROR;
|
||
NTMS_OBJECTINFORMATION mediaPartInfo;
|
||
NTMS_GUID physicalPartMediaId = partitionInfo.Info.Partition.PhysicalMedia;
|
||
mediaPartInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
mediaPartInfo.dwType = NTMS_PHYSICAL_MEDIA;
|
||
|
||
// NTMS - Get physical media information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
|
||
errPart = GetNtmsObjectInformation( hSession, &physicalPartMediaId, &mediaPartInfo );
|
||
|
||
// Ignore error here, just don't use this partition
|
||
if (errPart == NO_ERROR) {
|
||
|
||
// Check location type and if enabled
|
||
if ( (mediaPartInfo.Info.PhysicalMedia.LocationType != NTMS_UNKNOWN)
|
||
&& (mediaPartInfo.Enabled) ) {
|
||
// We'll use this unit of media.
|
||
// Save parameterers required for Allocate.
|
||
bFound = TRUE;
|
||
partId = partitionInfo.ObjectGuid;
|
||
pPartId = &partId;
|
||
break;
|
||
}
|
||
} else {
|
||
WsbTraceAlways(OLESTR("CRmsNTMS::Allocate: Failed to get object info for media <%ls> hr = <%ls>\n"),
|
||
WsbGuidAsString(physicalPartMediaId), WsbHrAsString(HRESULT_FROM_WIN32(errPart)));
|
||
}
|
||
}
|
||
hr = findNextNtmsObject(hFindPart, &partitionInfo);
|
||
} // while finding media pools
|
||
findCloseNtmsObject(hFindPart);
|
||
hr = S_OK;
|
||
break;
|
||
}
|
||
hr = findNextNtmsObject(hFindPool, &mediaPoolInfo);
|
||
} // while finding media pools
|
||
findCloseNtmsObject(hFindPool);
|
||
hr = S_OK;
|
||
}
|
||
|
||
if (bFound) {
|
||
break;
|
||
}
|
||
else {
|
||
OLECHAR * messageText = NULL;
|
||
WCHAR *stringArr[2];
|
||
WCHAR capString[40];
|
||
|
||
WsbShortSizeFormat64(*pFreeSpace, capString);
|
||
|
||
stringArr[0] = mediaPoolInfo.szName;
|
||
stringArr[1] = capString;
|
||
|
||
if (0 == FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||
LoadLibraryEx( WSB_FACILITY_PLATFORM_NAME, NULL, LOAD_LIBRARY_AS_DATAFILE ),
|
||
RMS_MESSAGE_SCRATCH_MEDIA_REQUEST, MAKELANGID ( LANG_NEUTRAL, SUBLANG_DEFAULT ),
|
||
(LPTSTR)&messageText, 0, (va_list *)stringArr)) {
|
||
WsbTrace(OLESTR("CRmsNTMS::Allocate: FormatMessage failed: %ls\n"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(GetLastError())));
|
||
}
|
||
|
||
// NTMS - Submit operator request
|
||
WsbTraceAlways(OLESTR("SubmitNtmsOperatorRequest()\n"));
|
||
err5 = SubmitNtmsOperatorRequest(hSession, NTMS_OPREQ_NEWMEDIA, messageText, &scratchPoolId, NULL, &requestId);
|
||
LocalFree(messageText);
|
||
WsbAffirmNoError(err5);
|
||
|
||
// NTMS - Wait for operator request
|
||
WsbTraceAlways(OLESTR("WaitForNtmsOperatorRequest()\n"));
|
||
err6 = WaitForNtmsOperatorRequest(hSession, &requestId, requestWaitTime);
|
||
//
|
||
// !!! NOTE !!! At the time of this writting WaitForNtmsOperatorRequest
|
||
// did not return ERROR_TIMEOUT.
|
||
//
|
||
if (ERROR_TIMEOUT == err6) {
|
||
// Best effort cleanup...
|
||
// NTMS - Cancel operator request
|
||
WsbTraceAlways(OLESTR("CancelNtmsOperatorRequest()\n"));
|
||
err7 = CancelNtmsOperatorRequest(hSession, &requestId);
|
||
}
|
||
WsbAffirmNoError(err6);
|
||
}
|
||
WsbAssertHrOk(hr);
|
||
|
||
// At this point the operator added a compatable unit of media...
|
||
// Verify until we're exceed the retry count.
|
||
retry--;
|
||
} while (retry > 0);
|
||
if (0 == retry) {
|
||
WsbThrow(RMS_E_SCRATCH_NOT_FOUND);
|
||
}
|
||
}
|
||
}
|
||
// NTMS - Allocate a unit of scratch media
|
||
WsbTraceAlways(OLESTR("AllocateNtmsMedia()\n"));
|
||
|
||
// Set additional allocation settings
|
||
DWORD dwAllocateOptions = 0;
|
||
NTMS_GUID mediaId = prevSideId;
|
||
if (mediaId == GUID_NULL) {
|
||
dwAllocateOptions |= NTMS_ALLOCATE_NEW;
|
||
} else {
|
||
// Allocating the second side: mediaId should hold the LMID of the first side
|
||
dwAllocateOptions |= NTMS_ALLOCATE_NEXT;
|
||
}
|
||
if (dwOptions & RMS_ALLOCATE_NO_BLOCK) {
|
||
dwAllocateOptions |= NTMS_ALLOCATE_ERROR_IF_UNAVAILABLE;
|
||
allocateWaitTime = 0;
|
||
}
|
||
|
||
err1 = AllocateNtmsMedia( hSession, &setId, pPartId, &mediaId,
|
||
dwAllocateOptions, allocateWaitTime, NULL );
|
||
WsbAffirmNoError( err1 );
|
||
|
||
// Now get/set the various information fields for the unit of media.
|
||
|
||
DWORD sideNo = 2;
|
||
NTMS_GUID side[2];
|
||
|
||
// NTMS - Enumerate the sides of a unit of media
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
err2 = EnumerateNtmsObject(hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0);
|
||
WsbAffirmNoError( err2 );
|
||
|
||
NTMS_OBJECTINFORMATION partitionInfo;
|
||
partitionInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
partitionInfo.dwType = NTMS_PARTITION;
|
||
|
||
// NTMS - Get partition information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
|
||
err3 = GetNtmsObjectInformation( hSession, &side[0], &partitionInfo );
|
||
WsbAffirmNoError( err3 );
|
||
|
||
NTMS_OBJECTINFORMATION mediaInfo;
|
||
NTMS_GUID physicalMediaId = partitionInfo.Info.Partition.PhysicalMedia;
|
||
mediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
mediaInfo.dwType = NTMS_PHYSICAL_MEDIA;
|
||
|
||
// NTMS - Get physical media information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
|
||
err3 = GetNtmsObjectInformation( hSession, &physicalMediaId, &mediaInfo );
|
||
WsbAffirmNoError( err3 );
|
||
|
||
NTMS_OBJECTINFORMATION logicalMediaInfo;
|
||
logicalMediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
logicalMediaInfo.dwType = NTMS_LOGICAL_MEDIA;
|
||
|
||
// NTMS - Get physical media information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_LOGICAL_MEDIA)\n"));
|
||
err3 = GetNtmsObjectInformation( hSession, &mediaId, &logicalMediaInfo );
|
||
WsbAffirmNoError( err3 );
|
||
|
||
// Save the capacity for the return arg.
|
||
if (pFreeSpace) {
|
||
*pFreeSpace = partitionInfo.Info.Partition.Capacity.QuadPart;
|
||
}
|
||
|
||
// Set name & description
|
||
CWsbStringPtr mediaDisplayName;
|
||
|
||
// Set new physical media name for first side
|
||
// Modify original name for second side
|
||
if ( !(dwAllocateOptions & NTMS_ALLOCATE_NEXT) ) {
|
||
mediaDisplayName = (WCHAR *)displayName;
|
||
} else {
|
||
WCHAR *dashPtr = wcsrchr((WCHAR *)displayName, L'-');
|
||
mediaDisplayName = mediaInfo.szName;
|
||
if (dashPtr) {
|
||
WsbAffirmHr(mediaDisplayName.Append(dashPtr));
|
||
}
|
||
}
|
||
|
||
// Set the Name to the displayName, only if there's no bar code.
|
||
if ( NTMS_BARCODESTATE_OK != mediaInfo.Info.PhysicalMedia.BarCodeState) {
|
||
wcscpy(mediaInfo.szName, mediaDisplayName);
|
||
wcscpy(partitionInfo.szName, (WCHAR *) displayName);
|
||
|
||
// NTMS doesn't allow dup logical media names. We set
|
||
// the name to the mediaId to keep it unique. The logical
|
||
// media name is not displayed in the Removable Storage UI.
|
||
|
||
wcscpy(logicalMediaInfo.szName, (WCHAR *) WsbGuidAsString(mediaId));
|
||
}
|
||
|
||
// Set the Description to the displayName
|
||
wcscpy(logicalMediaInfo.szDescription, (WCHAR *) displayName);
|
||
wcscpy(partitionInfo.szDescription, (WCHAR *) displayName);
|
||
wcscpy(mediaInfo.szDescription, (WCHAR *) mediaDisplayName);
|
||
|
||
// NTMS - Set partition information.
|
||
WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
|
||
err4 = SetNtmsObjectInformation( hSession, &side[0], &partitionInfo );
|
||
WsbAffirmNoError( err4 );
|
||
|
||
// NTMS - Set physical media information.
|
||
WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
|
||
err4 = SetNtmsObjectInformation( hSession, &physicalMediaId, &mediaInfo );
|
||
WsbAffirmNoError( err4 );
|
||
|
||
// NTMS - Set logical media information.
|
||
WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
|
||
err4 = SetNtmsObjectInformation( hSession, &mediaId, &logicalMediaInfo );
|
||
WsbAffirmNoError( err4 );
|
||
|
||
WsbAssertHrOk(FindCartridge(mediaId, ppCartridge));
|
||
WsbAssertHr((*ppCartridge)->SetStatus(RmsStatusScratch));
|
||
|
||
break;
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
|
||
case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
|
||
case RPC_S_CALL_FAILED: // Media Services crashed.
|
||
WsbAffirmHr(beginSession());
|
||
continue;
|
||
}
|
||
WsbThrow(hr);
|
||
);
|
||
} while(1);
|
||
|
||
} WsbCatchAndDo(hr,
|
||
if (err1 != NO_ERROR) {
|
||
// AllocateNtmsMedia
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_TIMEOUT:
|
||
case ERROR_MEDIA_UNAVAILABLE:
|
||
hr = RMS_E_SCRATCH_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_CANCELLED:
|
||
hr = RMS_E_CANCELLED;
|
||
break;
|
||
|
||
case ERROR_MEDIA_OFFLINE:
|
||
hr = RMS_E_MEDIA_OFFLINE;
|
||
break;
|
||
|
||
case ERROR_REQUEST_REFUSED:
|
||
hr = RMS_E_REQUEST_REFUSED;
|
||
break;
|
||
|
||
case ERROR_WRITE_PROTECT:
|
||
hr = RMS_E_WRITE_PROTECT;
|
||
break;
|
||
|
||
case ERROR_INVALID_MEDIA_POOL:
|
||
hr = RMS_E_MEDIASET_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_ACCESS_DENIED:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_DATABASE_FULL:
|
||
case ERROR_DEVICE_NOT_AVAILABLE:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_MEDIA:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("AllocateNtmsMedia"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("AllocateNtmsMedia"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err2 != NO_ERROR ) {
|
||
// EnumerateNtmsObject
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_INSUFFICIENT_BUFFER:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err3 != NO_ERROR) {
|
||
// GetNtmsObjectInformation
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err4 != NO_ERROR) {
|
||
// SetNtmsObjectInformation
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_ACCESS_DENIED:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_DATABASE_FULL:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
case ERROR_OBJECT_ALREADY_EXISTS: // bmd: 1/18/99 - Not documented, but NTMS doesn't allow dup logical media names.
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("SetNtmsObjectInformation"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("SetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err5 != NO_ERROR) {
|
||
// SubmitNtmsOperatorRequest
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_ACCESS_DENIED:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_CONNECTED:
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("SubmitNtmsOperatorRequest"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("SubmitNtmsOperatorRequest"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err6 != NO_ERROR) {
|
||
// WaitForNtmsOperatorRequest
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_TIMEOUT:
|
||
hr = RMS_E_TIMEOUT;
|
||
break;
|
||
|
||
case ERROR_CANCELLED:
|
||
hr = RMS_E_CANCELLED;
|
||
break;
|
||
|
||
case ERROR_REQUEST_REFUSED:
|
||
hr = RMS_E_REQUEST_REFUSED;
|
||
break;
|
||
|
||
case ERROR_ACCESS_DENIED:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_CONNECTED:
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("WaitForNtmsOperatorRequest"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("WaitForNtmsOperatorRequest"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::Allocate"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::Mount(
|
||
IN IRmsCartridge *pCart,
|
||
IN OUT IRmsDrive **ppDrive,
|
||
IN DWORD dwOptions OPTIONAL,
|
||
IN DWORD threadId OPTIONAL)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::Mount
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
DWORD err2 = NO_ERROR;
|
||
DWORD err3 = NO_ERROR;
|
||
DWORD err4 = NO_ERROR;
|
||
|
||
BOOL mediaMounted = FALSE;
|
||
|
||
BOOL bNoBlock = ( dwOptions & RMS_MOUNT_NO_BLOCK ) ? TRUE : FALSE;
|
||
|
||
// declared outside try block so it can be accessible throughout the method
|
||
DWORD sideNo = 2;
|
||
NTMS_GUID side[2];
|
||
|
||
WsbTraceIn( OLESTR("CRmsNTMS::Mount"), OLESTR("") );
|
||
|
||
try {
|
||
WsbAssertPointer(pCart);
|
||
|
||
CComPtr<IRmsDrive> pDrive;
|
||
|
||
// determine the timeout for the operator request
|
||
DWORD size;
|
||
OLECHAR tmpString[256];
|
||
BOOL bShortTimeout = ( dwOptions & RMS_SHORT_TIMEOUT ) ? TRUE : FALSE;
|
||
DWORD mountWaitTime;
|
||
if (bShortTimeout) {
|
||
mountWaitTime = RMS_DEFAULT_SHORT_WAIT_TIME;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_SHORT_WAIT_TIME, tmpString, 256, &size))) {
|
||
mountWaitTime = wcstol(tmpString, NULL, 10);
|
||
WsbTrace(OLESTR("MountWaitTime (Short) is %d milliseconds.\n"), mountWaitTime);
|
||
}
|
||
} else {
|
||
mountWaitTime = RMS_DEFAULT_MOUNT_WAIT_TIME;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_MOUNT_WAIT_TIME, tmpString, 256, &size))) {
|
||
mountWaitTime = wcstol(tmpString, NULL, 10);
|
||
WsbTrace(OLESTR("MountWaitTime is %d milliseconds.\n"), mountWaitTime);
|
||
}
|
||
}
|
||
|
||
NTMS_OBJECTINFORMATION driveInfo;
|
||
memset( &driveInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
// Special error recovery to handle when NTMS is down, or was cycled.
|
||
do {
|
||
hr = S_OK;
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
|
||
NTMS_GUID mediaId = GUID_NULL;
|
||
WsbAffirmHr(pCart->GetCartridgeId(&mediaId));
|
||
WsbAssert(mediaId != GUID_NULL, E_INVALIDARG);
|
||
|
||
err1 = NO_ERROR;
|
||
err2 = NO_ERROR;
|
||
err3 = NO_ERROR;
|
||
|
||
try {
|
||
|
||
// NTMS - enumerate the sides of a unit of media
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
err1 = EnumerateNtmsObject( hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0 );
|
||
WsbAffirmNoError( err1 );
|
||
|
||
DWORD count = 1;
|
||
NTMS_GUID driveId;
|
||
|
||
// NTMS - issue mount request
|
||
WsbTraceAlways(OLESTR("MountNtmsMedia()\n"));
|
||
DWORD dwOpt = NTMS_MOUNT_READ | NTMS_MOUNT_WRITE;
|
||
if (bNoBlock) {
|
||
dwOpt |= (NTMS_MOUNT_ERROR_NOT_AVAILABLE | NTMS_MOUNT_ERROR_OFFLINE);
|
||
}
|
||
if (dwOptions & RMS_USE_MOUNT_NO_DEADLOCK) {
|
||
/*
|
||
DEADLOCK AVOIDANCE: when RSM support for MountNtmsMediaDA is
|
||
in, the next line should be uncommented, and the other 2 lines
|
||
in this 'if' block should be removed.
|
||
err2 = MountNtmsMediaDA( hSession, &side[0], &driveId, count, dwOpt, NTMS_PRIORITY_NORMAL, mountWaitTime, NULL, &threadId, 1);
|
||
*/
|
||
UNREFERENCED_PARAMETER(threadId);
|
||
err2 = MountNtmsMedia( hSession, &side[0], &driveId, count, dwOpt, NTMS_PRIORITY_NORMAL, mountWaitTime, NULL);
|
||
} else {
|
||
err2 = MountNtmsMedia( hSession, &side[0], &driveId, count, dwOpt, NTMS_PRIORITY_NORMAL, mountWaitTime, NULL);
|
||
|
||
}
|
||
WsbAffirmNoError( err2 );
|
||
mediaMounted = TRUE;
|
||
|
||
//
|
||
// We now need two critical pieces of information. The Device name and
|
||
// the kind of media we just mounted. This gives use the essential information
|
||
// to create a data mover. Since we drill through NTMS to get this information
|
||
// we also create cartridge, drive objects.
|
||
//
|
||
|
||
driveInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
driveInfo.dwType = NTMS_DRIVE;
|
||
|
||
// NTMS - get drive information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_DRIVE)\n"));
|
||
err3 = GetNtmsObjectInformation( hSession, &driveId, &driveInfo );
|
||
WsbAffirmNoError( err3 );
|
||
break;
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
|
||
case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
|
||
case RPC_S_CALL_FAILED: // Media Services crashed.
|
||
WsbAffirmHr(beginSession());
|
||
continue;
|
||
}
|
||
WsbThrow(hr);
|
||
);
|
||
} while(1);
|
||
|
||
RmsMedia mediaType;
|
||
WsbAffirmHr(pCart->GetType((LONG *)&mediaType));
|
||
|
||
// Create Drive
|
||
WsbAssertHr(CoCreateInstance(CLSID_CRmsDrive, 0, CLSCTX_SERVER, IID_IRmsDrive, (void **)&pDrive));
|
||
|
||
CComQIPtr<IRmsChangerElement, &IID_IRmsChangerElement> pElmt = pDrive;
|
||
|
||
WsbAssertHr(pElmt->SetMediaSupported(mediaType));
|
||
|
||
CComQIPtr<IRmsDevice, &IID_IRmsDevice> pDevice = pDrive;
|
||
|
||
WsbAssertHr(pDevice->SetDeviceAddress(
|
||
(BYTE) driveInfo.Info.Drive.ScsiPort,
|
||
(BYTE) driveInfo.Info.Drive.ScsiBus,
|
||
(BYTE) driveInfo.Info.Drive.ScsiTarget,
|
||
(BYTE) driveInfo.Info.Drive.ScsiLun));
|
||
|
||
CWsbBstrPtr deviceName = driveInfo.Info.Drive.szDeviceName;
|
||
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
// Convert the NTMS device name to something usable.
|
||
//
|
||
switch (mediaType) {
|
||
case RmsMediaOptical:
|
||
case RmsMediaDVD:
|
||
case RmsMediaDisk:
|
||
{
|
||
// We need to convert \\.\PhysicalDriveN to something accessible by the file system.
|
||
WCHAR *szDriveLetter = NULL;
|
||
WCHAR *szVolumeName = NULL;
|
||
err4 = GetVolumesFromDrive( (WCHAR *)deviceName, &szVolumeName, &szDriveLetter );
|
||
if (szVolumeName) {
|
||
delete [] szVolumeName; // don't need it for now
|
||
}
|
||
if (NO_ERROR == err4) {
|
||
if (szDriveLetter) {
|
||
deviceName = szDriveLetter;
|
||
} else {
|
||
WsbTraceAlways(OLESTR("CRmsNTMS::Mount: GetVolumesFromDrive succeeded but output drive is NULL !!\n"));
|
||
WsbThrow(RMS_E_RESOURCE_UNAVAILABLE);
|
||
}
|
||
}
|
||
if (szDriveLetter) {
|
||
delete [] szDriveLetter;
|
||
}
|
||
WsbAffirmNoError( err4 );
|
||
WsbTrace(OLESTR("CRmsNTMS::Mount: device name after convert is %s\n"), (WCHAR *)deviceName);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
////////////////////////////////////////////////////////////////////////////////////////
|
||
|
||
WsbAssertHr(pDevice->SetDeviceName(deviceName));
|
||
|
||
WsbAssertHr(pCart->SetDrive(pDrive));
|
||
|
||
// Fill in the return arguments.
|
||
*ppDrive = pDrive;
|
||
pDrive->AddRef();
|
||
|
||
} WsbCatchAndDo(hr,
|
||
// Process the exception
|
||
if (err1 != NO_ERROR ) {
|
||
// EnumerateNtmsObject
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_INSUFFICIENT_BUFFER:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err2 != NO_ERROR) {
|
||
// MountNtmsMedia
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_TIMEOUT:
|
||
hr = RMS_E_CARTRIDGE_UNAVAILABLE;
|
||
break;
|
||
|
||
case ERROR_CANCELLED:
|
||
hr = RMS_E_CANCELLED;
|
||
break;
|
||
|
||
case ERROR_MEDIA_OFFLINE:
|
||
hr = RMS_E_MEDIA_OFFLINE;
|
||
if (bNoBlock) {
|
||
DWORD errSub = NO_ERROR;
|
||
|
||
try {
|
||
// Since we are not blocking for NTMS to ask the operator
|
||
// to mount the offline media, we do it ourselves
|
||
|
||
// create operator message
|
||
CWsbBstrPtr cartridgeName = "";
|
||
CWsbBstrPtr cartridgeDesc = "";
|
||
OLECHAR * messageText = NULL;
|
||
WCHAR *stringArr[2];
|
||
|
||
cartridgeName.Free();
|
||
WsbAffirmHr(pCart->GetName(&cartridgeName));
|
||
cartridgeDesc.Free();
|
||
WsbAffirmHr(pCart->GetDescription(&cartridgeDesc));
|
||
stringArr[0] = (WCHAR *) cartridgeName;
|
||
stringArr[1] = (WCHAR *) cartridgeDesc;
|
||
|
||
if (0 == FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||
LoadLibraryEx( WSB_FACILITY_PLATFORM_NAME, NULL, LOAD_LIBRARY_AS_DATAFILE ),
|
||
RMS_MESSAGE_OFFLINE_MEDIA_REQUEST, MAKELANGID ( LANG_NEUTRAL, SUBLANG_DEFAULT ),
|
||
(LPTSTR)&messageText, 0, (va_list *)stringArr)) {
|
||
WsbTrace(OLESTR("CRmsNTMS::Mount: FormatMessage failed: %ls\n"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(GetLastError())));
|
||
messageText = NULL;
|
||
}
|
||
|
||
NTMS_GUID mediaId = GUID_NULL;
|
||
NTMS_GUID libId = GUID_NULL;
|
||
NTMS_GUID requestId = GUID_NULL;
|
||
WsbAffirmHr(pCart->GetCartridgeId(&mediaId));
|
||
WsbAssert(mediaId != GUID_NULL, E_INVALIDARG);
|
||
|
||
// Library Id should be gathered here - need to clarify why
|
||
// does the GetHome return a null id !!!
|
||
// WsbAffirmHr(pCart->GetHome(NULL, &libId, NULL, NULL, NULL, NULL, NULL, NULL));
|
||
// WsbAssert(libId != GUID_NULL, E_INVALIDARG);
|
||
|
||
// submit operator request
|
||
errSub = SubmitNtmsOperatorRequest(m_SessionHandle, NTMS_OPREQ_MOVEMEDIA,
|
||
messageText, &mediaId, &libId, &requestId);
|
||
LocalFree(messageText);
|
||
WsbAffirmNoError (errSub);
|
||
|
||
} WsbCatchAndDo(hr,
|
||
// Process the error of the Corrective Action
|
||
if (errSub != NO_ERROR ) {
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("SubmitNtmsOperatorRequest"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
}
|
||
|
||
// place back the original mane error
|
||
hr = RMS_E_MEDIA_OFFLINE;
|
||
);
|
||
}
|
||
break;
|
||
|
||
case ERROR_REQUEST_REFUSED:
|
||
hr = RMS_E_REQUEST_REFUSED;
|
||
break;
|
||
|
||
case ERROR_WRITE_PROTECT:
|
||
hr = RMS_E_WRITE_PROTECT;
|
||
break;
|
||
|
||
case ERROR_INVALID_STATE:
|
||
case ERROR_INVALID_DRIVE: {
|
||
// when performing NTMS mount in non-blocking mode , this error may
|
||
// just mean that a corrective action such as drive cleaning should
|
||
// be performed before mounting (note that ONLY when not blocking,
|
||
// NTMS can not instruct corrective actions by itself)
|
||
if (bNoBlock) {
|
||
try {
|
||
CWsbBstrPtr cartridgeName = "";
|
||
CWsbBstrPtr cartridgeDesc = "";
|
||
cartridgeName.Free();
|
||
WsbAffirmHr(pCart->GetName(&cartridgeName));
|
||
cartridgeDesc.Free();
|
||
WsbAffirmHr(pCart->GetDescription(&cartridgeDesc));
|
||
WsbLogEvent(RMS_MESSAGE_DRIVE_NOT_AVAILABLE, 0, NULL,
|
||
(WCHAR *) cartridgeName, (WCHAR *) cartridgeDesc, NULL);
|
||
|
||
} WsbCatch(hr);
|
||
|
||
break;
|
||
}
|
||
}
|
||
case ERROR_RESOURCE_DISABLED: {
|
||
// Check if the the media (cartridge) is disabled - different error should
|
||
// be returned for media and for other resources (library, drive, etc.)
|
||
|
||
HRESULT hrOrg = hr;
|
||
DWORD errSub1 = NO_ERROR;
|
||
DWORD errSub2 = NO_ERROR;
|
||
try {
|
||
// get physical media information
|
||
NTMS_OBJECTINFORMATION objectInfo;
|
||
objectInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
objectInfo.dwType = NTMS_PARTITION;
|
||
WsbAssert(side[0] != GUID_NULL, E_INVALIDARG);
|
||
errSub1 = GetNtmsObjectInformation( m_SessionHandle, &side[0], &objectInfo );
|
||
WsbAffirmNoError (errSub1);
|
||
|
||
NTMS_GUID physicalMediaId = objectInfo.Info.Partition.PhysicalMedia;
|
||
WsbAssert(physicalMediaId != GUID_NULL, E_INVALIDARG);
|
||
objectInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
objectInfo.dwType = NTMS_PHYSICAL_MEDIA;
|
||
errSub2 = GetNtmsObjectInformation( m_SessionHandle, &physicalMediaId, &objectInfo );
|
||
WsbAffirmNoError (errSub2);
|
||
|
||
// set our dedicated error only if (physical) media is disabled
|
||
if (! objectInfo.Enabled) {
|
||
hr = RMS_E_CARTRIDGE_DISABLED;
|
||
}
|
||
|
||
} WsbCatchAndDo(hr,
|
||
// Process the error of the get-info requests
|
||
if (errSub1 != NO_ERROR ) {
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation (Partition)"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
} else if (errSub2 != NO_ERROR ) {
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation (Physical Media)"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
}
|
||
|
||
// place back the original mane error
|
||
hr = hrOrg;
|
||
);
|
||
break;
|
||
}
|
||
|
||
case ERROR_ACCESS_DENIED:
|
||
case ERROR_BUSY:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_DATABASE_FULL:
|
||
case ERROR_DRIVE_MEDIA_MISMATCH:
|
||
case ERROR_INVALID_LIBRARY:
|
||
case ERROR_INVALID_MEDIA:
|
||
case ERROR_NOT_ENOUGH_MEMORY: {
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("MountNtmsMedia"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
default: {
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("MountNtmsMedia"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else if (err3 != NO_ERROR) {
|
||
// GetNtmsObjectInformation
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
} else if (err4 != NO_ERROR) {
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetVolumesFromDrive"), OLESTR("Unexpected Failure: "),
|
||
WsbHrAsString(hr), NULL);
|
||
}
|
||
|
||
if (mediaMounted) {
|
||
// Something failed after the mount completed, so need to clean up...
|
||
// Dismount the media to release the resource before returning.
|
||
Dismount(pCart, FALSE);
|
||
}
|
||
);
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::Mount"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::Dismount(
|
||
IN IRmsCartridge *pCart, IN DWORD dwOptions)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::Dismount
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
DWORD err2 = NO_ERROR;
|
||
|
||
WsbTraceIn( OLESTR("CRmsNTMS::Dismount"), OLESTR("") );
|
||
|
||
try {
|
||
WsbAssertPointer(pCart);
|
||
|
||
do {
|
||
hr = S_OK;
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
|
||
NTMS_GUID mediaId = GUID_NULL;
|
||
WsbAffirmHr(pCart->GetCartridgeId(&mediaId));
|
||
WsbAssert(mediaId != GUID_NULL, E_INVALIDARG);
|
||
|
||
NTMS_GUID side[2];
|
||
DWORD sideNo = 2;
|
||
|
||
err1 = NO_ERROR;
|
||
err2 = NO_ERROR;
|
||
|
||
try {
|
||
|
||
// NTMS - enumerate the sides of a unit of media
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
err1 = EnumerateNtmsObject( hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0 );
|
||
WsbAffirmNoError( err1 );
|
||
|
||
// NTMS - dismount media
|
||
DWORD dwNtmsOptions = 0;
|
||
WsbTraceAlways(OLESTR("DismountNtmsMedia()\n"));
|
||
if (! ( dwOptions & RMS_DISMOUNT_IMMEDIATE )) {
|
||
dwNtmsOptions |= NTMS_DISMOUNT_DEFERRED;
|
||
}
|
||
err2 = DismountNtmsMedia( hSession, &side[0], 1, dwNtmsOptions );
|
||
#ifdef DBG
|
||
// TODO: Remove this trap for the unexpected ERROR_ACCESS_DENIED error.
|
||
WsbAssert(err2 != ERROR_ACCESS_DENIED, HRESULT_FROM_WIN32(err2));
|
||
#endif
|
||
WsbAffirmNoError( err2 );
|
||
|
||
// Since RSM Dismount is asyncronous, we may need to wait some arbitrary time,
|
||
// in order that when we come back, the media is really dismounted
|
||
if ( (dwOptions & RMS_DISMOUNT_DEFERRED_ONLY) && (!(dwOptions & RMS_DISMOUNT_IMMEDIATE)) ) {
|
||
CComQIPtr<IRmsServer, &IID_IRmsServer> pServer = g_pServer;
|
||
if (S_OK == pServer->IsReady()) {
|
||
DWORD size;
|
||
OLECHAR tmpString[256];
|
||
DWORD waitTime = RMS_DEFAULT_AFTER_DISMOUNT_WAIT_TIME;
|
||
if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_AFTER_DISMOUNT_WAIT_TIME, tmpString, 256, &size))) {
|
||
waitTime = wcstol(tmpString, NULL, 10);
|
||
WsbTrace(OLESTR("AfterDismountWaitTime is %d milliseconds.\n"), waitTime);
|
||
}
|
||
|
||
Sleep(waitTime);
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
|
||
case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
|
||
case RPC_S_CALL_FAILED: // Media Services crashed.
|
||
WsbAffirmHr(beginSession());
|
||
continue;
|
||
}
|
||
WsbThrow(hr);
|
||
);
|
||
} while(1);
|
||
|
||
|
||
} WsbCatchAndDo(hr,
|
||
if (err1 != NO_ERROR) {
|
||
// EnumerateNtmsObject
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
case ERROR_INSUFFICIENT_BUFFER:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err2 != NO_ERROR) {
|
||
// DismountNtmsMedia
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_MEDIA_OFFLINE:
|
||
hr = RMS_E_MEDIA_OFFLINE;
|
||
break;
|
||
|
||
case ERROR_TIMEOUT:
|
||
case ERROR_INVALID_MEDIA:
|
||
case ERROR_INVALID_LIBRARY:
|
||
case ERROR_DEVICE_NOT_AVAILABLE:
|
||
case ERROR_MEDIA_NOT_AVAILABLE:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
case ERROR_INVALID_STATE:
|
||
case ERROR_ACCESS_DENIED:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_DATABASE_FULL:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("DismountNtmsMedia"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("DismountNtmsMedia"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::Dismount"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::Deallocate(
|
||
IN IRmsCartridge *pCart)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::DeallocateMedia
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
DWORD err2 = NO_ERROR;
|
||
DWORD err3 = NO_ERROR;
|
||
DWORD err4 = NO_ERROR;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::Deallocate"), OLESTR(""));
|
||
|
||
try {
|
||
WsbAssertPointer(pCart);
|
||
|
||
do {
|
||
hr = S_OK;
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
|
||
NTMS_GUID mediaId = GUID_NULL;
|
||
WsbAffirmHr(pCart->GetCartridgeId(&mediaId));
|
||
WsbAssert(mediaId != GUID_NULL, E_INVALIDARG);
|
||
|
||
err1 = NO_ERROR;
|
||
err2 = NO_ERROR;
|
||
err3 = NO_ERROR;
|
||
err4 = NO_ERROR;
|
||
|
||
NTMS_OBJECTINFORMATION partitionInfo;
|
||
memset( &partitionInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
DWORD sideNo = 2;
|
||
NTMS_GUID side[2];
|
||
|
||
try {
|
||
// NTMS - enumerate the sides of a unit of media
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
err1 = EnumerateNtmsObject( hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0 );
|
||
WsbAffirmNoError( err1 );
|
||
|
||
// NTMS - get partition information
|
||
partitionInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
partitionInfo.dwType = NTMS_PARTITION;
|
||
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
|
||
err2 = GetNtmsObjectInformation( hSession, &side[0], &partitionInfo );
|
||
WsbAffirmNoError( err2 );
|
||
|
||
// NULL the Description
|
||
wcscpy(partitionInfo.szDescription, L"");
|
||
|
||
// NTMS - Set partition information.
|
||
WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
|
||
err3 = SetNtmsObjectInformation( hSession, &side[0], &partitionInfo );
|
||
WsbAffirmNoError( err3 );
|
||
|
||
// NTMS - deallocate media
|
||
WsbTraceAlways(OLESTR("DeallocateNtmsMedia()\n"));
|
||
err4 = DeallocateNtmsMedia( hSession, &mediaId, 0 );
|
||
WsbAffirmNoError( err4 );
|
||
|
||
break;
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
|
||
case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
|
||
case RPC_S_CALL_FAILED: // Media Services crashed.
|
||
WsbAffirmHr(beginSession());
|
||
continue;
|
||
}
|
||
WsbThrow(hr);
|
||
);
|
||
} while(1);
|
||
|
||
|
||
|
||
} WsbCatchAndDo(hr,
|
||
if (err1 != NO_ERROR ) {
|
||
// EnumerateNtmsObject
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
case ERROR_INSUFFICIENT_BUFFER:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err2 != NO_ERROR) {
|
||
// GetNtmsObjectInformation
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err3 != NO_ERROR) {
|
||
// SetNtmsObjectInformation
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_ACCESS_DENIED:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_DATABASE_FULL:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
case ERROR_OBJECT_ALREADY_EXISTS: // bmd: 1/18/99 - Not documented, but NTMS doesn't allow dup logical media names.
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("SetNtmsObjectInformation"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("SetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err4 != NO_ERROR) {
|
||
// DeallocateNtmsMedia
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_MEDIA:
|
||
//case ERROR_INVALID_PARTITION:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_DATABASE_FULL:
|
||
case ERROR_ACCESS_DENIED:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("DeallocateNtmsMedia"), OLESTR(""),
|
||
WsbHrAsString(hr),
|
||
NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("DeallocateNtmsMedia"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::Deallocate"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::UpdateOmidInfo(
|
||
IN REFGUID cartId,
|
||
IN BYTE *pBuffer,
|
||
IN LONG size,
|
||
IN LONG type)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::UpdateOmidInfo
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
|
||
WsbTraceIn( OLESTR("CRmsNTMS::UpdateOmidInfo"), OLESTR("<%ls> <0x%08x> <%d>"), WsbGuidAsString(cartId), pBuffer, size );
|
||
|
||
try {
|
||
WsbAssert(cartId != GUID_NULL, E_INVALIDARG);
|
||
WsbAssertPointer(pBuffer);
|
||
WsbAssert(size > 0, E_INVALIDARG);
|
||
|
||
WsbTraceBuffer(size, pBuffer);
|
||
|
||
do {
|
||
hr = S_OK;
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
NTMS_GUID mediaId = cartId;
|
||
|
||
err1 = NO_ERROR;
|
||
|
||
try {
|
||
|
||
// NTMS - update on media information.
|
||
WsbTraceAlways(OLESTR("UpdateNtmsOmidInfo()\n"));
|
||
switch((RmsOnMediaIdentifier)type) {
|
||
case RmsOnMediaIdentifierMTF:
|
||
err1 = UpdateNtmsOmidInfo(hSession, &mediaId, NTMS_OMID_TYPE_RAW_LABEL, size, pBuffer);
|
||
break;
|
||
case RmsOnMediaIdentifierWIN32:
|
||
WsbAssert(size == sizeof(NTMS_FILESYSTEM_INFO), E_UNEXPECTED);
|
||
err1 = UpdateNtmsOmidInfo(hSession, &mediaId, NTMS_OMID_TYPE_FILESYSTEM_INFO, size, pBuffer);
|
||
break;
|
||
default:
|
||
WsbThrow(E_UNEXPECTED);
|
||
}
|
||
WsbAffirmNoError( err1 );
|
||
break;
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
|
||
case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
|
||
case RPC_S_CALL_FAILED: // Media Services crashed.
|
||
WsbAffirmHr(beginSession());
|
||
continue;
|
||
}
|
||
WsbThrow(hr);
|
||
);
|
||
} while(1);
|
||
|
||
} WsbCatchAndDo(hr,
|
||
if (err1 != NO_ERROR) {
|
||
// UpdateNtmsOmidInfo
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_ACCESS_DENIED:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_MEDIA:
|
||
//case ERROR_INVALID_PARTITION:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_CONNECTED:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("UpdateNtmsOmidInfo"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("UpdateNtmsOmidInfo"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::UpdateOmidInfo"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::GetBlockSize(
|
||
IN REFGUID cartId,
|
||
OUT LONG *pBlockSize
|
||
)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::GetBlockSize
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::GetBlockSize"), OLESTR("<%ls> <x%08x>"), WsbGuidAsString(cartId), pBlockSize);
|
||
|
||
try {
|
||
WsbAssertPointer(pBlockSize);
|
||
|
||
do {
|
||
hr = S_OK;
|
||
err1 = NO_ERROR;
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
NTMS_GUID mediaId = cartId;
|
||
|
||
DWORD nBlockSize;
|
||
DWORD sizeOfBlockSize = sizeof(DWORD);
|
||
try {
|
||
|
||
err1 = GetNtmsObjectAttribute(hSession, &mediaId, NTMS_LOGICAL_MEDIA, OLESTR("BlockSize"), (LPVOID) &nBlockSize, &sizeOfBlockSize);
|
||
WsbAffirmNoError(err1);
|
||
*pBlockSize = (LONG) nBlockSize;
|
||
break;
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
|
||
case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
|
||
case RPC_S_CALL_FAILED: // Media Services crashed.
|
||
WsbAffirmHr(beginSession());
|
||
continue;
|
||
}
|
||
WsbThrow(hr);
|
||
);
|
||
} while(1);
|
||
|
||
} WsbCatchAndDo(hr,
|
||
if (err1 != NO_ERROR) {
|
||
// GetNtmsObjectAttribute
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND: // Don't log this error. Attribute doesn't
|
||
break; // exist for new media. We skip this error
|
||
// and let the caller deal with it.
|
||
|
||
case ERROR_DATABASE_FAILURE: // Log these errors.
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case ERROR_INSUFFICIENT_BUFFER:
|
||
case ERROR_NO_DATA:
|
||
case ERROR_INVALID_PARAMETER:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectAttribute"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectAttribute"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::GetBlockSize"), OLESTR("hr = <%ls>, BlockSize = <%d>"), WsbHrAsString(hr), *pBlockSize);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::SetBlockSize(
|
||
IN REFGUID cartId,
|
||
IN LONG blockSize
|
||
)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::SetBlockSize
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::SetBlockSize"), OLESTR("<%ls> <%d>"), WsbGuidAsString(cartId), blockSize);
|
||
|
||
try {
|
||
|
||
do {
|
||
hr = S_OK;
|
||
err1 = NO_ERROR;
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
NTMS_GUID mediaId = cartId;
|
||
|
||
DWORD nBlockSize = blockSize;
|
||
DWORD sizeOfBlockSize = sizeof(DWORD);
|
||
|
||
try {
|
||
|
||
err1 = SetNtmsObjectAttribute(hSession, &mediaId, NTMS_LOGICAL_MEDIA, OLESTR("BlockSize"), (LPVOID) &nBlockSize, sizeOfBlockSize);
|
||
WsbAffirmNoError(err1);
|
||
break;
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
|
||
case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
|
||
case RPC_S_CALL_FAILED: // Media Services crashed.
|
||
WsbAffirmHr(beginSession());
|
||
continue;
|
||
}
|
||
WsbThrow(hr);
|
||
);
|
||
} while(1);
|
||
|
||
} WsbCatchAndDo(hr,
|
||
if (err1 != NO_ERROR) {
|
||
// SetNtmsObjectAttribute
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INSUFFICIENT_BUFFER:
|
||
case ERROR_NOT_CONNECTED:
|
||
case ERROR_NO_DATA:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
case ERROR_INVALID_NAME:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("SetNtmsObjectAttribute"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("SetNtmsObjectAttribute"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::SetBlockSize"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::changeState(
|
||
IN LONG newState
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Changes the state of the NTMS object.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Values:
|
||
|
||
S_OK - Success.
|
||
|
||
--*/
|
||
{
|
||
|
||
HRESULT hr = S_OK;
|
||
WsbTraceIn(OLESTR("CRmsNTMS::changeState"), OLESTR("<%d>"), newState);
|
||
|
||
try {
|
||
|
||
CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = this;
|
||
WsbAssertPointer( pObject );
|
||
|
||
// TODO: Validate the state change
|
||
WsbAffirmHr(pObject->SetState(newState));
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::changeState"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::ExportDatabase(void)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
CRmsNTMS::ExportDatabase
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
|
||
WsbTraceIn( OLESTR("CRmsNTMS::ExportDatabase"), OLESTR(""));
|
||
|
||
try {
|
||
|
||
do {
|
||
hr = S_OK;
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
|
||
err1 = NO_ERROR;
|
||
|
||
try {
|
||
|
||
err1 = ExportNtmsDatabase(hSession);
|
||
WsbAffirmNoError(err1);
|
||
break;
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
|
||
case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
|
||
case RPC_S_CALL_FAILED: // Media Services crashed.
|
||
WsbAffirmHr(beginSession());
|
||
continue;
|
||
}
|
||
WsbThrow(hr);
|
||
);
|
||
} while(1);
|
||
|
||
} WsbCatchAndDo(hr,
|
||
if (err1 != NO_ERROR) {
|
||
// ExportNtmsDatabase
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_ACCESS_DENIED:
|
||
case ERROR_DATABASE_FAILURE:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("ExportNtmsDatabase"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("ExportNtmsDatabase"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::ExportDatabase"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::FindCartridge(
|
||
IN REFGUID cartId,
|
||
OUT IRmsCartridge **ppCartridge)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
CRmsNTMS::FindCartridge
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
DWORD err2 = NO_ERROR;
|
||
|
||
WsbTraceIn( OLESTR("CRmsNTMS::FindCartridge"), OLESTR("<%ls> <0x%08x>"), WsbGuidAsString(cartId), ppCartridge);
|
||
|
||
try {
|
||
WsbAssert(cartId != GUID_NULL, E_INVALIDARG);
|
||
WsbAssertPointer(ppCartridge);
|
||
|
||
NTMS_OBJECTINFORMATION partitionInfo;
|
||
memset( &partitionInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
NTMS_OBJECTINFORMATION mediaInfo;
|
||
memset( &mediaInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
NTMS_OBJECTINFORMATION mediaTypeInfo;
|
||
memset( &mediaTypeInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
NTMS_OBJECTINFORMATION libraryInfo;
|
||
memset( &libraryInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
NTMS_OBJECTINFORMATION logicalMediaInfo;
|
||
memset( &logicalMediaInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
RmsMedia translatedMediaType = RmsMediaUnknown;
|
||
|
||
// Special error recovery to handle when NTMS is down, or was cycled.
|
||
do {
|
||
hr = S_OK;
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
NTMS_GUID mediaId = cartId;
|
||
DWORD sideNo = 2;
|
||
NTMS_GUID side[2];
|
||
|
||
err1 = NO_ERROR;
|
||
err2 = NO_ERROR;
|
||
|
||
try {
|
||
|
||
// NTMS - enumerate the sides of a unit of media
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
err1 = EnumerateNtmsObject( hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0 );
|
||
WsbAffirmNoError( err1 );
|
||
|
||
// NTMS - get partition information
|
||
partitionInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
partitionInfo.dwType = NTMS_PARTITION;
|
||
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
|
||
err2 = GetNtmsObjectInformation( hSession, &side[0], &partitionInfo );
|
||
WsbAffirmNoError( err2 );
|
||
|
||
// NTMS - get physical media information
|
||
NTMS_GUID physicalMediaId = partitionInfo.Info.Partition.PhysicalMedia;
|
||
|
||
mediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
mediaInfo.dwType = NTMS_PHYSICAL_MEDIA;
|
||
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
|
||
err2 = GetNtmsObjectInformation( hSession, &physicalMediaId, &mediaInfo );
|
||
WsbAffirmNoError( err2);
|
||
|
||
// NTMS - get media type information
|
||
NTMS_GUID mediaTypeId = mediaInfo.Info.PhysicalMedia.MediaType;
|
||
|
||
mediaTypeInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
mediaTypeInfo.dwType = NTMS_MEDIA_TYPE;
|
||
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_MEDIA_TYPE)\n"));
|
||
err2 = GetNtmsObjectInformation( hSession, &mediaTypeId, &mediaTypeInfo );
|
||
WsbAffirmNoError( err2 );
|
||
|
||
// Translate the NTMS media type into something understood by RMS
|
||
storageMediaTypeToRmsMedia(&(mediaTypeInfo.Info.MediaType), &translatedMediaType);
|
||
|
||
// NTMS - get logical media information
|
||
logicalMediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
logicalMediaInfo.dwType = NTMS_LOGICAL_MEDIA;
|
||
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_LOGICAL_MEDIA)\n"));
|
||
err2 = GetNtmsObjectInformation( hSession, &mediaId, &logicalMediaInfo );
|
||
WsbAffirmNoError( err2 );
|
||
|
||
// NTMS - get library information
|
||
NTMS_GUID libraryId = mediaInfo.Info.PhysicalMedia.CurrentLibrary;
|
||
|
||
libraryInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
libraryInfo.dwType = NTMS_LIBRARY;
|
||
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_LIBRARY)\n"));
|
||
err2 = GetNtmsObjectInformation( hSession, &libraryId, &libraryInfo );
|
||
WsbAffirmNoError( err2 );
|
||
|
||
break;
|
||
|
||
} WsbCatchAndDo(hr,
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_CONNECTED:
|
||
case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running.
|
||
case RPC_S_CALL_FAILED_DNE: // Media Services is up; handle is not valid.
|
||
case RPC_S_CALL_FAILED: // Media Services crashed.
|
||
WsbAffirmHr(beginSession());
|
||
continue;
|
||
}
|
||
WsbThrow(hr);
|
||
);
|
||
} while(1);
|
||
|
||
// Create Cartridge
|
||
IRmsCartridge *pCart = 0;
|
||
WsbAssertHr(CoCreateInstance(CLSID_CRmsCartridge, 0, CLSCTX_SERVER,
|
||
IID_IRmsCartridge, (void **)&pCart));
|
||
|
||
// Fill in the object data
|
||
|
||
// The media Name is what is displaye by NTMS UI
|
||
CWsbBstrPtr name = mediaInfo.szName;
|
||
WsbAffirmHr(pCart->SetName(name));
|
||
|
||
// The partition Description is what is displayed by NTMS UI.
|
||
CWsbBstrPtr desc = partitionInfo.szDescription;
|
||
WsbAffirmHr(pCart->SetDescription(desc));
|
||
|
||
WsbAffirmHr(pCart->SetCartridgeId(cartId));
|
||
|
||
CWsbBstrPtr barCode = mediaInfo.Info.PhysicalMedia.szBarCode;
|
||
CWsbBstrPtr seqNo = mediaInfo.Info.PhysicalMedia.szSequenceNumber; // Not used
|
||
WsbAffirmHr(pCart->SetTagAndNumber(barCode, 0));
|
||
|
||
WsbAffirmHr(pCart->SetType((LONG) translatedMediaType));
|
||
|
||
switch (mediaInfo.Info.PhysicalMedia.MediaState) {
|
||
case NTMS_MEDIASTATE_IDLE:
|
||
case NTMS_MEDIASTATE_UNLOADED:
|
||
WsbAffirmHr(pCart->SetIsAvailable(TRUE));
|
||
break;
|
||
|
||
default:
|
||
WsbAffirmHr(pCart->SetIsAvailable(FALSE));
|
||
break;
|
||
}
|
||
|
||
RmsElement type = RmsElementUnknown;
|
||
|
||
if ( NTMS_LIBRARYTYPE_ONLINE == libraryInfo.Info.Library.LibraryType ) {
|
||
|
||
switch (mediaInfo.Info.PhysicalMedia.LocationType) {
|
||
case NTMS_STORAGESLOT:
|
||
type = RmsElementStorage;
|
||
break;
|
||
|
||
case NTMS_DRIVE:
|
||
type = RmsElementDrive;
|
||
break;
|
||
|
||
case NTMS_IEPORT:
|
||
type = RmsElementIEPort;
|
||
break;
|
||
|
||
case NTMS_CHANGER:
|
||
type = RmsElementChanger;
|
||
break;
|
||
|
||
default:
|
||
type = RmsElementUnknown;
|
||
break;
|
||
}
|
||
}
|
||
else if ( NTMS_LIBRARYTYPE_STANDALONE == libraryInfo.Info.Library.LibraryType ) {
|
||
|
||
switch (mediaInfo.Info.PhysicalMedia.LocationType) {
|
||
case NTMS_DRIVE:
|
||
type = RmsElementDrive;
|
||
break;
|
||
|
||
default:
|
||
type = RmsElementUnknown;
|
||
break;
|
||
}
|
||
} else {
|
||
type = RmsElementShelf;
|
||
}
|
||
|
||
WsbAffirmHr(pCart->SetLocation(type,
|
||
mediaInfo.Info.PhysicalMedia.CurrentLibrary,
|
||
logicalMediaInfo.Info.LogicalMedia.MediaPool,
|
||
0, 0, 0, 0, 0));
|
||
|
||
WsbAffirmHr(pCart->SetManagedBy((LONG)RmsMediaManagerNTMS));
|
||
|
||
WsbAssertHr(pCart->SetStatus(RmsStatusPrivate));
|
||
|
||
CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObj = pCart;
|
||
if (!mediaInfo.Enabled) {
|
||
WsbAffirmHr(pObj->Disable(RMS_E_CARTRIDGE_DISABLED));
|
||
}
|
||
|
||
CComQIPtr<IRmsStorageInfo, &IID_IRmsStorageInfo> pInfo = pCart;
|
||
WsbAffirmHr(pInfo->SetCapacity(partitionInfo.Info.Partition.Capacity.QuadPart));
|
||
|
||
WsbTrace(OLESTR("Cartridge id <name/desc>: %ls <%ls/%ls>\n"), WsbGuidAsString(cartId), (WCHAR *) name, (WCHAR *) desc);
|
||
WsbTrace(OLESTR("Cartridge <barCode/seqNo>: <%ls/%ls>\n"), (WCHAR *) barCode, (WCHAR *) seqNo );
|
||
WsbTrace(OLESTR("Cartridge Enabled: %ls\n"), WsbHrAsString(pObj->IsEnabled()));
|
||
WsbTrace(OLESTR("Cartridge type: %d\n"), translatedMediaType);
|
||
WsbTrace(OLESTR("Cartridge capacity: %I64d\n"), partitionInfo.Info.Partition.Capacity.QuadPart);
|
||
WsbTrace(OLESTR("Cartridge domain: %ls\n"), WsbGuidAsString(logicalMediaInfo.Info.LogicalMedia.MediaPool));
|
||
|
||
if (mediaInfo.Info.PhysicalMedia.MediaPool != logicalMediaInfo.Info.LogicalMedia.MediaPool) {
|
||
CWsbStringPtr idPhysical = mediaInfo.Info.PhysicalMedia.CurrentLibrary;
|
||
CWsbStringPtr idLogical = logicalMediaInfo.Info.LogicalMedia.MediaPool;
|
||
WsbTraceAlways(OLESTR("CRmsNTMS::FindCartridge - Media Pool Id mismatch %ls != %ls\n"), idPhysical, idLogical );
|
||
}
|
||
|
||
// Fill in the return argument.
|
||
*ppCartridge = pCart;
|
||
|
||
} WsbCatchAndDo( hr,
|
||
WsbTrace(OLESTR("CRmsNTMS::FindCartridge - %ls Not Found. hr = <%ls>\n"),WsbGuidAsString(cartId),WsbHrAsString(hr));
|
||
if (err1 != NO_ERROR ) {
|
||
// EnumerateNtmsObject
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
case ERROR_INSUFFICIENT_BUFFER:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err2 != NO_ERROR) {
|
||
// GetNtmsObjectInformation
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::FindCartridge"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::Suspend(void)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
CRmsNTMS::Suspend
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
WsbTraceIn( OLESTR("CRmsNTMS::Suspend"), OLESTR(""));
|
||
|
||
try {
|
||
|
||
WsbAffirmHr(changeState(RmsNtmsStateSuspending));
|
||
WsbAffirmHr(endSession());
|
||
WsbAffirmHr(changeState(RmsNtmsStateSuspended));
|
||
|
||
} WsbCatch(hr);
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::Suspend"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::Resume(void)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
CRmsNTMS::Resume
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
WsbTraceIn( OLESTR("CRmsNTMS::Resume"), OLESTR(""));
|
||
|
||
try {
|
||
|
||
WsbAffirmHr(changeState(RmsNtmsStateResuming));
|
||
WsbAffirmHr(beginSession());
|
||
WsbAffirmHr(changeState(RmsNtmsStateReady));
|
||
|
||
} WsbCatch(hr);
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::Resume"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::InitializeInAnotherThread(void)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
WsbTraceIn(OLESTR("CRmsNTMS::InitializeInAnotherThread"), OLESTR(""));
|
||
|
||
try {
|
||
|
||
DWORD threadId;
|
||
HANDLE hThread;
|
||
CComQIPtr<IRmsServer, &IID_IRmsServer> pServer = g_pServer;
|
||
WsbAffirmHr( pServer->ChangeState( RmsServerStateInitializing ));
|
||
WsbAffirmHandle(hThread = CreateThread(NULL, 1024, CRmsNTMS::InitializationThread, this, 0, &threadId));
|
||
CloseHandle(hThread);
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::InitializeInAnotherThread"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
DWORD WINAPI
|
||
CRmsNTMS::InitializationThread(
|
||
IN LPVOID pv)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
WsbTraceIn(OLESTR("CRmsNTMS::InitializationThread"), OLESTR(""));
|
||
|
||
|
||
try {
|
||
WsbAssertPointer(pv);
|
||
CRmsNTMS *pNTMS = (CRmsNTMS*)pv;
|
||
WsbAffirmHr(pNTMS->Initialize());
|
||
CComQIPtr<IRmsServer, &IID_IRmsServer> pServer = g_pServer;
|
||
WsbAffirmHr( pServer->ChangeState( RmsServerStateReady ));
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::InitializationThread"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::isReady(void)
|
||
{
|
||
|
||
HRESULT hr = S_OK;
|
||
|
||
try {
|
||
|
||
BOOL isEnabled;
|
||
HRESULT status;
|
||
RmsServerState state;
|
||
|
||
CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = this;
|
||
WsbAssertPointer( pObject );
|
||
|
||
WsbAffirmHr( isEnabled = pObject->IsEnabled());
|
||
WsbAffirmHr( pObject->GetState( (LONG *)&state ));
|
||
WsbAffirmHr( pObject->GetStatusCode( &status ));
|
||
|
||
if ( S_OK == isEnabled ) {
|
||
if ( RmsServerStateReady == state ) {
|
||
hr = S_OK;
|
||
}
|
||
else {
|
||
if ( S_OK == status ) {
|
||
WsbThrow(E_UNEXPECTED);
|
||
}
|
||
else {
|
||
WsbThrow(status);
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
if ( S_OK == status ) {
|
||
WsbThrow(E_UNEXPECTED);
|
||
}
|
||
else {
|
||
WsbThrow(status);
|
||
}
|
||
}
|
||
|
||
} WsbCatch(hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::setPoolDACL (
|
||
IN OUT NTMS_GUID *pPoolId,
|
||
IN DWORD subAuthority,
|
||
IN DWORD action,
|
||
IN DWORD mask)
|
||
|
||
{
|
||
|
||
HRESULT hr = S_OK;
|
||
WsbTraceIn(OLESTR("CRmsNTMS::SetPoolDACL"), OLESTR("%ls <%d> <%d> <%d>"), WsbGuidAsString(*pPoolId), subAuthority, action, mask);
|
||
|
||
PSID psidAccount = NULL;
|
||
PSECURITY_DESCRIPTOR psdRePoolSd = NULL;
|
||
|
||
try {
|
||
|
||
SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
|
||
DWORD errCode = NO_ERROR, sizeTry = 5, sizeReturned = 0;
|
||
PACL paclDis = NULL;
|
||
ACCESS_ALLOWED_ACE *pAce = NULL;
|
||
BOOL daclPresent = FALSE, daclDefaulted = FALSE;
|
||
HANDLE hSession = m_SessionHandle;
|
||
|
||
WsbAffirmStatus(AllocateAndInitializeSid(&ntauth, 2, SECURITY_BUILTIN_DOMAIN_RID, subAuthority, 0, 0, 0, 0, 0, 0, &psidAccount));
|
||
|
||
//Get the security descriptor for the pool
|
||
for (;;) {
|
||
if (psdRePoolSd != NULL) {
|
||
free(psdRePoolSd);
|
||
}
|
||
psdRePoolSd = (PSECURITY_DESCRIPTOR)malloc(sizeTry);
|
||
WsbAffirm(NULL != psdRePoolSd, E_OUTOFMEMORY);
|
||
|
||
errCode = GetNtmsObjectSecurity(hSession, pPoolId, NTMS_MEDIA_POOL, DACL_SECURITY_INFORMATION, psdRePoolSd, sizeTry, &sizeReturned);
|
||
|
||
if (errCode == ERROR_SUCCESS) {
|
||
break;
|
||
}
|
||
else if (errCode == ERROR_INSUFFICIENT_BUFFER) {
|
||
sizeTry = sizeReturned;
|
||
continue;
|
||
}
|
||
else {
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("GetNtmsObjectSecurity"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
WsbAffirmNoError(errCode);
|
||
}
|
||
}
|
||
|
||
// Get a pointer to the DACL
|
||
WsbAffirmStatus(GetSecurityDescriptorDacl(psdRePoolSd, &daclPresent, &paclDis, &daclDefaulted));
|
||
|
||
// Go through the DACL and change the mask of the ACE that matches the SID
|
||
for (DWORD i = 0;i < paclDis->AceCount; ++i) {
|
||
WsbAffirmStatus(GetAce(paclDis, i, (LPVOID*) &pAce));
|
||
if (EqualSid(psidAccount, &(pAce->SidStart))) {
|
||
if (action == ADD_ACE_MASK_BITS) {
|
||
pAce->Mask |= mask;
|
||
} else {
|
||
pAce->Mask &= ~mask;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Set the pool security descriptor
|
||
errCode = SetNtmsObjectSecurity(hSession, pPoolId, NTMS_MEDIA_POOL, DACL_SECURITY_INFORMATION, psdRePoolSd);
|
||
WsbAffirmNoError(errCode);
|
||
|
||
} WsbCatch(hr);
|
||
|
||
if (psdRePoolSd) {
|
||
free(psdRePoolSd);
|
||
}
|
||
|
||
if (psidAccount) {
|
||
FreeSid(psidAccount);
|
||
}
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::SetPoolDACL"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
CRmsNTMS::IsMediaCopySupported (
|
||
IN REFGUID mediaPoolId)
|
||
{
|
||
|
||
HRESULT hr = S_OK;
|
||
WsbTraceIn(OLESTR("CRmsNTMS::IsMediaCopySupported"), OLESTR("%ls"), WsbGuidAsString(mediaPoolId));
|
||
|
||
try {
|
||
|
||
// If we can find two drives that support this media type then
|
||
// the media copy operation is supported.
|
||
|
||
// For each drive known to NTMS we need to find what media types
|
||
// it supports. NTMS doesn't keep media type information for the
|
||
// drive, but assumes homogeneous drives in a library (per HighGound) -
|
||
// so detecting this is a bit convoluted.
|
||
|
||
// we'll search through each library and find the media types
|
||
// supported, and count the number of drives in the library.
|
||
|
||
if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
|
||
WsbAffirmHr(beginSession());
|
||
}
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
|
||
NTMS_OBJECTINFORMATION mediaPoolInfo;
|
||
NTMS_GUID poolId = mediaPoolId;
|
||
|
||
memset(&mediaPoolInfo, 0, sizeof(NTMS_OBJECTINFORMATION));
|
||
|
||
mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
|
||
mediaPoolInfo.dwSize = sizeof(NTMS_OBJECTINFORMATION);
|
||
|
||
// NTMS - Get Media Pool Information
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
|
||
DWORD errCode = GetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
|
||
if ( errCode != NO_ERROR ) {
|
||
|
||
WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"),
|
||
WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
|
||
NULL );
|
||
|
||
WsbThrow( E_UNEXPECTED );
|
||
|
||
}
|
||
|
||
NTMS_GUID mediaTypeId = mediaPoolInfo.Info.MediaPool.MediaType;
|
||
|
||
NTMS_OBJECTINFORMATION libInfo;
|
||
HANDLE hFindLib = NULL;
|
||
int driveCount = 0;
|
||
|
||
hr = findFirstNtmsObject( NTMS_LIBRARY,
|
||
GUID_NULL, NULL, GUID_NULL, &hFindLib, &libInfo);
|
||
while( S_OK == hr ) {
|
||
HANDLE hFindLib2 = NULL;
|
||
// now see if the library in which the drive is contained supported
|
||
// the specified media type
|
||
|
||
if ( libInfo.Info.Library.dwNumberOfDrives > 0 ) {
|
||
hr = findFirstNtmsObject( NTMS_MEDIA_TYPE,
|
||
libInfo.ObjectGuid, NULL, mediaTypeId, &hFindLib2, NULL);
|
||
WsbTrace(OLESTR("Searching <%ls> for media type and drives; hr = %ls (state = %d, enabled = %ls, drives = %d)\n"),
|
||
libInfo.szName, WsbHrAsString(hr),
|
||
libInfo.dwOperationalState,
|
||
WsbBoolAsString(libInfo.Enabled),
|
||
libInfo.Info.Library.dwNumberOfDrives);
|
||
if ((S_OK == hr) &&
|
||
((NTMS_READY == libInfo.dwOperationalState) ||
|
||
(NTMS_INITIALIZING == libInfo.dwOperationalState)) &&
|
||
(libInfo.Enabled)) {
|
||
|
||
driveCount += libInfo.Info.Library.dwNumberOfDrives;
|
||
}
|
||
findCloseNtmsObject( hFindLib2 );
|
||
}
|
||
|
||
hr = findNextNtmsObject( hFindLib, &libInfo );
|
||
}
|
||
findCloseNtmsObject( hFindLib );
|
||
|
||
hr = (driveCount > 1) ? S_OK : S_FALSE;
|
||
|
||
} WsbCatch(hr);
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::IsMediaCopySupported"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
|
||
return hr;
|
||
}
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::UpdateDrive(
|
||
IN IRmsDrive *pDrive)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::UpdateDrive
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
CComPtr<IRmsComObject> pObject;
|
||
GUID driveId;
|
||
DWORD err1 = NO_ERROR;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::UpdateDrive"), OLESTR(""));
|
||
|
||
try {
|
||
// get drive information
|
||
WsbAffirmHr(pDrive->QueryInterface(IID_IRmsComObject, (void **)&pObject));
|
||
WsbAffirmHr(pObject->GetObjectId(&driveId));
|
||
|
||
NTMS_OBJECTINFORMATION objectInfo;
|
||
objectInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
objectInfo.dwType = NTMS_DRIVE;
|
||
WsbAssert(driveId != GUID_NULL, E_INVALIDARG);
|
||
err1 = GetNtmsObjectInformation( m_SessionHandle, &driveId, &objectInfo );
|
||
WsbAffirmNoError (err1);
|
||
|
||
// Note: Currently, the method updates only the enable/disable state of the drive
|
||
// If required, the method may update more fields
|
||
if (objectInfo.Enabled) {
|
||
WsbAffirmHr(pObject->Enable());
|
||
} else {
|
||
WsbAffirmHr(pObject->Disable(S_OK));
|
||
}
|
||
|
||
} WsbCatchAndDo(hr,
|
||
// Process the error of the get-info request
|
||
if (err1 != NO_ERROR ) {
|
||
if (err1 == ERROR_OBJECT_NOT_FOUND) {
|
||
hr = RMS_E_NTMS_OBJECT_NOT_FOUND;
|
||
}
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation (Drive)"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
}
|
||
);
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::UpdateDrive"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
return(hr);
|
||
}
|
||
|
||
HRESULT
|
||
CRmsNTMS::GetNofAvailableDrives(
|
||
OUT DWORD* pdwNofDrives
|
||
)
|
||
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::GetNofAvailableDrives().
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::GetNofAvailableDrives"), OLESTR(""));
|
||
|
||
*pdwNofDrives = 0;
|
||
|
||
// Enumerate over all libraries that HSM uses
|
||
// (Outside the try block, since we want to continue if a failure occur on a specific library)
|
||
WsbTrace(OLESTR("CRmsNTMS::GetNofAvailableDrives: Total number of libraries is %lu\n"), m_dwNofLibs);
|
||
for (int j=0; j<(int)m_dwNofLibs; j++) {
|
||
|
||
LPNTMS_GUID pObjects = NULL;
|
||
DWORD errCode = NO_ERROR;
|
||
|
||
// get library id
|
||
GUID libId = m_pLibGuids[j];
|
||
|
||
try {
|
||
|
||
// Enumerate on all drives in the library
|
||
DWORD dwNofObjects = 16; // Initial size of object id array to allocate
|
||
int nRetry = 0;
|
||
|
||
// Allocate according to
|
||
pObjects = (LPNTMS_GUID)WsbAlloc( dwNofObjects*sizeof(NTMS_GUID) );
|
||
WsbAffirmPointer( pObjects );
|
||
|
||
// Enumerate all drives
|
||
do {
|
||
errCode = EnumerateNtmsObject(m_SessionHandle, &libId, pObjects, &dwNofObjects, NTMS_DRIVE, 0);
|
||
WsbTraceAlways(OLESTR("CRmsNTMS::GetNofAvailableDrives: Total number of drives is %lu\n"),
|
||
dwNofObjects);
|
||
nRetry++;
|
||
|
||
if ( (ERROR_OBJECT_NOT_FOUND == errCode) || (0 == dwNofObjects) ) { // Don't count on NTMS returning the correct errCode
|
||
// Not considered as an NTMS error, prevent logging by setting to NO_ERROR
|
||
errCode = NO_ERROR;
|
||
WsbThrow( RMS_E_NTMS_OBJECT_NOT_FOUND );
|
||
} else if (ERROR_INSUFFICIENT_BUFFER == errCode) {
|
||
// Don't retry more than 3 times
|
||
if (3 <= nRetry) {
|
||
WsbThrow(HRESULT_FROM_WIN32(errCode));
|
||
}
|
||
|
||
// Allocate a new buffer, and retry.
|
||
WsbTrace(OLESTR("CRmsNTMS::GetNofAvailableDrives: Reallocating buffer\n"));
|
||
LPVOID pTemp = WsbRealloc( pObjects, dwNofObjects*sizeof(NTMS_GUID) );
|
||
if (!pTemp) {
|
||
WsbThrow(E_OUTOFMEMORY);
|
||
}
|
||
pObjects = (LPNTMS_GUID)pTemp;
|
||
} else {
|
||
// Other unexpected error
|
||
WsbAffirmNoError(errCode);
|
||
}
|
||
|
||
} while (ERROR_INSUFFICIENT_BUFFER == errCode);
|
||
|
||
// go over all drives, get information and check availablity
|
||
for (int i = 0; i < (int)dwNofObjects; i++) {
|
||
|
||
GUID driveId = pObjects[i];
|
||
try {
|
||
NTMS_OBJECTINFORMATION objectInfo;
|
||
memset( &objectInfo, 0, sizeof(NTMS_OBJECTINFORMATION) );
|
||
objectInfo.dwSize = sizeof(NTMS_OBJECTINFORMATION);
|
||
objectInfo.dwType = NTMS_DRIVE;
|
||
WsbAssert(driveId != GUID_NULL, E_INVALIDARG);
|
||
errCode = GetNtmsObjectInformation(m_SessionHandle, &driveId, &objectInfo );
|
||
WsbAffirmNoError (errCode);
|
||
|
||
WsbTrace(OLESTR("CRmsNTMS::GetNofAvailableDrives: drive <%ls> enable/disable = %ls\n"),
|
||
WsbGuidAsString(driveId), WsbBoolAsString(objectInfo.Enabled));
|
||
|
||
if (objectInfo.Enabled) {
|
||
(*pdwNofDrives)++;
|
||
}
|
||
|
||
} WsbCatchAndDo(hr,
|
||
// Log error and go on to the next drive
|
||
if (errCode != NO_ERROR ) {
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation (Drive)"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
}
|
||
|
||
WsbTraceAlways(OLESTR("CRmsNTMS::GetNofAvailableDrives: Failed to get info for drive <%ls> hr = <%ls>\n"),
|
||
WsbGuidAsString(driveId), WsbHrAsString(hr));
|
||
hr = S_OK;
|
||
);
|
||
}
|
||
|
||
} WsbCatchAndDo(hr,
|
||
// Log error and go on to the next library
|
||
if (errCode != NO_ERROR ) {
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject (Drive)"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
}
|
||
|
||
WsbTraceAlways(OLESTR("CRmsNTMS::GetNofAvailableDrives: Failed to enumerate drives in library <%ls> hr = <%ls>\n"),
|
||
WsbGuidAsString(libId), WsbHrAsString(hr));
|
||
hr = S_OK;
|
||
);
|
||
|
||
if (pObjects) {
|
||
WsbFree(pObjects);
|
||
}
|
||
|
||
} // of for
|
||
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::GetNofAvailableDrives"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
return(hr);
|
||
}
|
||
|
||
HRESULT
|
||
CRmsNTMS::CheckSecondSide(
|
||
IN REFGUID firstSideId,
|
||
OUT BOOL *pbValid,
|
||
OUT GUID *pSecondSideId
|
||
)
|
||
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::CheckSecondSide().
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
DWORD err2 = NO_ERROR;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::CheckSecondSide"), OLESTR(""));
|
||
|
||
*pbValid = FALSE;
|
||
*pSecondSideId = GUID_NULL;
|
||
|
||
try {
|
||
|
||
WsbAssert(firstSideId != GUID_NULL, E_INVALIDARG);
|
||
WsbAssertPointer(pbValid);
|
||
WsbAssertPointer(pSecondSideId);
|
||
|
||
NTMS_OBJECTINFORMATION partitionInfo;
|
||
memset( &partitionInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
NTMS_OBJECTINFORMATION mediaInfo;
|
||
memset( &mediaInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
NTMS_GUID mediaId = firstSideId;
|
||
NTMS_GUID firstSidePartitionId;
|
||
NTMS_GUID side[2];
|
||
DWORD sideNo = 2;
|
||
|
||
|
||
// NTMS - get Partition from LMID
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
err1 = EnumerateNtmsObject(hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0);
|
||
WsbAffirmNoError(err1);
|
||
firstSidePartitionId = side[0];
|
||
|
||
// NTMS - get partition information (using size 0 - LMID relates 1:1 to Partition
|
||
partitionInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
partitionInfo.dwType = NTMS_PARTITION;
|
||
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
|
||
err2 = GetNtmsObjectInformation(hSession, &firstSidePartitionId, &partitionInfo);
|
||
WsbAffirmNoError(err2);
|
||
|
||
// NTMS - get physical media information
|
||
NTMS_GUID physicalMediaId = partitionInfo.Info.Partition.PhysicalMedia;
|
||
mediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
mediaInfo.dwType = NTMS_PHYSICAL_MEDIA;
|
||
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
|
||
err2 = GetNtmsObjectInformation(hSession, &physicalMediaId, &mediaInfo);
|
||
WsbAffirmNoError(err2);
|
||
|
||
// Check whether there are more than one side
|
||
if (mediaInfo.Info.PhysicalMedia.dwNumberOfPartitions > 1) {
|
||
// Enumerate physical meida - expect 2 sides here.
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
sideNo = 2;
|
||
err1 = EnumerateNtmsObject(hSession, &physicalMediaId, side, &sideNo, NTMS_PARTITION, 0);
|
||
WsbAffirmNoError(err1);
|
||
WsbAffirm(sideNo > 1, RMS_E_NOT_FOUND);
|
||
|
||
// Look for a side whos partition id is different from first side
|
||
for (DWORD i=0; i<sideNo; i++) {
|
||
if (firstSidePartitionId != side[i]) {
|
||
*pbValid = TRUE; // Valid second side found
|
||
|
||
// Get its LMID
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
|
||
err2 = GetNtmsObjectInformation(hSession, &side[i], &partitionInfo);
|
||
WsbAffirmNoError(err2);
|
||
|
||
*pSecondSideId = partitionInfo.Info.Partition.LogicalMedia;
|
||
}
|
||
}
|
||
} // of if two sides
|
||
|
||
} WsbCatchAndDo( hr,
|
||
WsbTrace(OLESTR("CRmsNTMS::CheckSecondSide - of %ls failed: hr = <%ls>\n"),WsbGuidAsString(firstSideId),WsbHrAsString(hr));
|
||
if (err1 != NO_ERROR ) {
|
||
// EnumerateNtmsObject
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
case ERROR_INSUFFICIENT_BUFFER:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR("Unexpected Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err2 != NO_ERROR) {
|
||
// GetNtmsObjectInformation
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR("Unexpected Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::CheckSecondSide"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
return(hr);
|
||
}
|
||
|
||
HRESULT
|
||
CRmsNTMS::EnsureAllSidesNotAllocated(
|
||
IN REFGUID mediaId
|
||
)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
DWORD err1 = NO_ERROR;
|
||
DWORD err2 = NO_ERROR;
|
||
|
||
WsbTraceIn(OLESTR("CRmsNTMS::EnsureAllSidesNotAllocated"), OLESTR(""));
|
||
|
||
try {
|
||
WsbAssert(mediaId != GUID_NULL, E_INVALIDARG);
|
||
|
||
NTMS_OBJECTINFORMATION partitionInfo;
|
||
memset( &partitionInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
NTMS_OBJECTINFORMATION mediaInfo;
|
||
memset( &mediaInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
|
||
|
||
HANDLE hSession = m_SessionHandle;
|
||
|
||
NTMS_GUID physicalMediaId = mediaId;
|
||
mediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
mediaInfo.dwType = NTMS_PHYSICAL_MEDIA;
|
||
partitionInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
|
||
partitionInfo.dwType = NTMS_PARTITION;
|
||
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
|
||
err2 = GetNtmsObjectInformation(hSession, &physicalMediaId, &mediaInfo);
|
||
WsbAffirmNoError(err2);
|
||
|
||
// Check whether there are more than one side
|
||
if (mediaInfo.Info.PhysicalMedia.dwNumberOfPartitions > 1) {
|
||
// Enumerate physical meida - expect 2 sides here.
|
||
NTMS_GUID side[2];
|
||
DWORD sideNo = 2;
|
||
WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
|
||
err1 = EnumerateNtmsObject(hSession, &physicalMediaId, side, &sideNo, NTMS_PARTITION, 0);
|
||
WsbAffirmNoError(err1);
|
||
|
||
// Look for a side which is allocated
|
||
for (DWORD i=0; i<sideNo; i++) {
|
||
WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
|
||
err2 = GetNtmsObjectInformation(hSession, &side[i], &partitionInfo);
|
||
WsbAffirmNoError(err2);
|
||
|
||
if (GUID_NULL != partitionInfo.Info.Partition.LogicalMedia) {
|
||
hr = S_FALSE;
|
||
break;
|
||
}
|
||
}
|
||
} // of if two sides
|
||
|
||
} WsbCatchAndDo( hr,
|
||
WsbTrace(OLESTR("CRmsNTMS::EnsureAllSidesNotAllocated - of %ls failed: hr = <%ls>\n"),WsbGuidAsString(mediaId),WsbHrAsString(hr));
|
||
if (err1 != NO_ERROR ) {
|
||
// EnumerateNtmsObject
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
case ERROR_INSUFFICIENT_BUFFER:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("EnumerateNtmsObject"), OLESTR("Unexpected Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
else if (err2 != NO_ERROR) {
|
||
// GetNtmsObjectInformation
|
||
switch (HRESULT_CODE(hr)) {
|
||
case ERROR_OBJECT_NOT_FOUND:
|
||
hr = RMS_E_CARTRIDGE_NOT_FOUND;
|
||
break;
|
||
|
||
case ERROR_INVALID_HANDLE:
|
||
case ERROR_INVALID_PARAMETER:
|
||
case ERROR_NOT_ENOUGH_MEMORY:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
|
||
default:
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("GetNtmsObjectInformation"), OLESTR("Unexpected Error: "),
|
||
WsbHrAsString(hr), NULL);
|
||
break;
|
||
}
|
||
}
|
||
);
|
||
|
||
WsbTraceOut(OLESTR("CRmsNTMS::EnsureAllSidesNotAllocated"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
||
return(hr);
|
||
}
|
||
|
||
STDMETHODIMP
|
||
CRmsNTMS::DismountAll(
|
||
IN REFGUID fromMediaSet,
|
||
IN DWORD dwOptions)
|
||
/*++
|
||
|
||
Implements:
|
||
|
||
IRmsNTMS::DismountAll
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
WsbTraceIn( OLESTR("CRmsNTMS::DismountAll"), OLESTR("") );
|
||
|
||
try {
|
||
WsbAssert(GUID_NULL != fromMediaSet, E_INVALIDARG);
|
||
|
||
HANDLE hFindMedia = NULL;
|
||
DWORD err1 = NO_ERROR;
|
||
HANDLE hSession = m_SessionHandle;
|
||
NTMS_OBJECTINFORMATION physicalMediaInfo;
|
||
NTMS_GUID setId = fromMediaSet;
|
||
NTMS_GUID partId = GUID_NULL;
|
||
|
||
// Dismount all mounted medias from the given pool
|
||
|
||
hr = findFirstNtmsObject(NTMS_PHYSICAL_MEDIA, setId, NULL, GUID_NULL, &hFindMedia, &physicalMediaInfo);
|
||
while(S_OK == hr) {
|
||
switch (physicalMediaInfo.Info.PhysicalMedia.MediaState) {
|
||
case NTMS_MEDIASTATE_LOADED:
|
||
case NTMS_MEDIASTATE_MOUNTED:
|
||
// Dismount the media
|
||
try {
|
||
partId = physicalMediaInfo.Info.PhysicalMedia.MountedPartition;
|
||
WsbAffirm(GUID_NULL != partId, E_UNEXPECTED);
|
||
|
||
DWORD dwNtmsOptions = 0;
|
||
WsbTraceAlways(OLESTR("DismountNtmsMedia()\n"));
|
||
if (! ( dwOptions & RMS_DISMOUNT_IMMEDIATE )) {
|
||
dwNtmsOptions |= NTMS_DISMOUNT_DEFERRED;
|
||
}
|
||
err1 = DismountNtmsMedia(hSession, &partId, 1, dwNtmsOptions);
|
||
WsbAffirmNoError(err1);
|
||
|
||
} WsbCatchAndDo(hr,
|
||
if (err1 != NO_ERROR) {
|
||
WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
|
||
OLESTR("DismountNtmsMedia"), OLESTR(""),
|
||
WsbHrAsString(hr), NULL);
|
||
}
|
||
);
|
||
|
||
break;
|
||
|
||
default:
|
||
// Media is not mounted - skip it
|
||
break;
|
||
}
|
||
|
||
hr = findNextNtmsObject(hFindMedia, &physicalMediaInfo);
|
||
}
|
||
|
||
findCloseNtmsObject(hFindMedia);
|
||
hr = S_OK;
|
||
|
||
} WsbCatch(hr);
|
||
|
||
WsbTraceOut( OLESTR("CRmsNTMS::DismountAll"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
|
||
|
||
return hr;
|
||
}
|