Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4974 lines
189 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved
  3. Module Name:
  4. RmsNTMS.cpp
  5. Abstract:
  6. Implementation of CRmsNTMS
  7. Author:
  8. Brian Dodd [brian] 14-May-1997
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "RmsServr.h"
  13. #include "RmsNTMS.h"
  14. typedef struct RmsNTMSSearchHandle {
  15. WCHAR FindName[NTMS_OBJECTNAME_LENGTH];
  16. NTMS_GUID FindId;
  17. DWORD FindType;
  18. LPNTMS_GUID Objects;
  19. DWORD NumberOfObjects;
  20. DWORD MaxObjects;
  21. DWORD Next;
  22. DWORD LastError;
  23. } RMS_NTMS_SEARCH_HANDLE, *LPRMS_NTMS_SEARCH_HANDLE;
  24. #define ADD_ACE_MASK_BITS 1
  25. #define REMOVE_ACE_MASK_BITS 2
  26. //
  27. // We use application name in RSM interface for media pool name.
  28. // Media pool name is an identifier of the media pool in RSM, therefore, we cannot allow
  29. // this string to be localized. Localizing this string would create another pool after
  30. // installing a foreign language MUI.
  31. //
  32. #define REMOTE_STORAGE_APP_NAME OLESTR("Remote Storage")
  33. /////////////////////////////////////////////////////////////////////////////
  34. // IRmsNTMS implementation
  35. /*
  36. HINSTANCE hInstDll;
  37. typedef DWORD (*FunctionName)( void );
  38. FunctionName FunctionNameFn;
  39. hInstDll = LoadLibrary( "dll" );
  40. FunctionNameFn = (FunctionName) GetProcAddress( hInstDll, "FunctionName" );
  41. result = (FunctionNameFn)();
  42. */
  43. STDMETHODIMP
  44. CRmsNTMS::FinalConstruct(void)
  45. /*++
  46. Implements:
  47. CComObjectRoot::FinalConstruct
  48. --*/
  49. {
  50. HRESULT hr = S_OK;
  51. CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = this;
  52. WsbTraceIn(OLESTR("CRmsNTMS::FinalConstruct"), OLESTR(""));
  53. m_pLibGuids = NULL;
  54. m_dwNofLibs = 0;
  55. try {
  56. WsbAffirmHr(CComObjectRoot::FinalConstruct());
  57. WsbAffirmHr( changeState( RmsNtmsStateStarting ));
  58. m_SessionHandle = INVALID_HANDLE_VALUE;
  59. m_IsRmsConfiguredForNTMS = FALSE;
  60. m_IsNTMSRegistered = FALSE;
  61. m_Name = RMS_NTMS_OBJECT_NAME;
  62. m_Description = RMS_NTMS_OBJECT_DESCRIPTION;
  63. if ( S_OK == getNtmsSupportFromRegistry(NULL) ) {
  64. m_IsRmsConfiguredForNTMS = TRUE;
  65. }
  66. HKEY hKeyMachine = 0;
  67. HKEY hKey = 0;
  68. if ( S_OK == WsbOpenRegistryKey(NULL, RMS_NTMS_REGISTRY_STRING, KEY_QUERY_VALUE, &hKeyMachine, &hKey) ) {
  69. WsbCloseRegistryKey (&hKeyMachine, &hKey);
  70. m_IsNTMSRegistered = TRUE;
  71. }
  72. // Failure precedence.
  73. WsbAffirm(m_IsRmsConfiguredForNTMS, RMS_E_NOT_CONFIGURED_FOR_NTMS);
  74. WsbAffirm(m_IsNTMSRegistered, RMS_E_NTMS_NOT_REGISTERED);
  75. WsbAffirmHr( changeState( RmsNtmsStateStarted ));
  76. } WsbCatchAndDo(hr,
  77. pObject->Disable( hr );
  78. WsbLogEvent(RMS_MESSAGE_NTMS_CONNECTION_NOT_ESABLISHED, 0, NULL, WsbHrAsString(hr), NULL);
  79. // Always construct!
  80. hr = S_OK;
  81. );
  82. WsbTraceOut(OLESTR("CRmsNTMS::FinalConstruct"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  83. return hr;
  84. }
  85. STDMETHODIMP
  86. CRmsNTMS::FinalRelease(void)
  87. /*++
  88. Implements:
  89. CComObjectRoot::FinalRelease
  90. --*/
  91. {
  92. HRESULT hr = S_OK;
  93. WsbTraceIn(OLESTR("CRmsNTMS::FinalRelease"), OLESTR(""));
  94. try {
  95. WsbAffirmHr( changeState( RmsNtmsStateStopping ));
  96. endSession();
  97. if (m_pLibGuids) {
  98. WsbFree(m_pLibGuids);
  99. }
  100. CComObjectRoot::FinalRelease();
  101. WsbAffirmHr( changeState( RmsNtmsStateStopped ));
  102. } WsbCatch(hr);
  103. WsbTraceOut(OLESTR("CRmsNTMS::FinalRelease"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  104. return hr;
  105. }
  106. STDMETHODIMP
  107. CRmsNTMS::IsInstalled(void)
  108. {
  109. HRESULT hr = S_OK;
  110. try {
  111. if ( !m_IsEnabled ) {
  112. if ( !m_IsNTMSRegistered ) {
  113. // check again... NTMS can get registered at anytime.
  114. HKEY hKeyMachine = 0;
  115. HKEY hKey = 0;
  116. WsbAffirm(S_OK == WsbOpenRegistryKey(NULL, RMS_NTMS_REGISTRY_STRING, KEY_QUERY_VALUE, &hKeyMachine, &hKey), RMS_E_NTMS_NOT_REGISTERED);
  117. WsbCloseRegistryKey (&hKeyMachine, &hKey);
  118. m_IsNTMSRegistered = TRUE;
  119. CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = this;
  120. pObject->Enable();
  121. // now need to initialize
  122. WsbAffirmHr(InitializeInAnotherThread());
  123. }
  124. WsbAffirm(m_IsRmsConfiguredForNTMS, RMS_E_NOT_CONFIGURED_FOR_NTMS);
  125. WsbAffirm(m_IsNTMSRegistered, RMS_E_NTMS_NOT_REGISTERED);
  126. }
  127. } WsbCatch(hr);
  128. return hr;
  129. }
  130. STDMETHODIMP
  131. CRmsNTMS::Initialize(void)
  132. {
  133. HRESULT hr = E_FAIL;
  134. CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = this;
  135. WsbTraceIn(OLESTR("CRmsNTMS::Initialize"), OLESTR(""));
  136. try {
  137. WsbAffirmHr( changeState( RmsNtmsStateInitializing ));
  138. if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
  139. WsbAffirmHr(beginSession());
  140. }
  141. HANDLE hSession = m_SessionHandle;
  142. //
  143. // Create Remote Storage specific NTMS media pools
  144. //
  145. WsbAffirmHr( createMediaPools() );
  146. //
  147. // Report on other NTMS objects of interest
  148. //
  149. HANDLE hFind = NULL;
  150. NTMS_OBJECTINFORMATION objectInfo;
  151. hr = findFirstNtmsObject( NTMS_MEDIA_TYPE, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
  152. while( S_OK == hr ) {
  153. reportNtmsObjectInformation( &objectInfo );
  154. hr = findNextNtmsObject( hFind, &objectInfo );
  155. }
  156. findCloseNtmsObject( hFind );
  157. hr = findFirstNtmsObject( NTMS_CHANGER, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
  158. while( S_OK == hr ) {
  159. reportNtmsObjectInformation( &objectInfo );
  160. hr = findNextNtmsObject( hFind, &objectInfo );
  161. }
  162. findCloseNtmsObject( hFind );
  163. hr = findFirstNtmsObject( NTMS_CHANGER_TYPE, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
  164. while( S_OK == hr ) {
  165. reportNtmsObjectInformation( &objectInfo );
  166. hr = findNextNtmsObject( hFind, &objectInfo );
  167. }
  168. findCloseNtmsObject( hFind );
  169. hr = findFirstNtmsObject( NTMS_DRIVE, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
  170. while( S_OK == hr ) {
  171. reportNtmsObjectInformation( &objectInfo );
  172. hr = findNextNtmsObject( hFind, &objectInfo );
  173. }
  174. findCloseNtmsObject( hFind );
  175. hr = findFirstNtmsObject( NTMS_DRIVE_TYPE, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
  176. while( S_OK == hr ) {
  177. reportNtmsObjectInformation( &objectInfo );
  178. hr = findNextNtmsObject( hFind, &objectInfo );
  179. }
  180. findCloseNtmsObject( hFind );
  181. WsbAffirmHr( changeState( RmsNtmsStateReady ));
  182. hr = S_OK;
  183. } WsbCatchAndDo(hr,
  184. pObject->Disable( hr );
  185. WsbLogEvent( RMS_MESSAGE_NTMS_INITIALIZATION_FAILED, 0, NULL, WsbHrAsString(hr), NULL );
  186. );
  187. WsbTraceOut( OLESTR("CRmsNTMS::Initialize"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  188. return hr;
  189. }
  190. HRESULT
  191. CRmsNTMS::findFirstNtmsObject(
  192. IN DWORD objectType,
  193. IN REFGUID containerId,
  194. IN WCHAR *objectName,
  195. IN REFGUID objectId,
  196. OUT HANDLE *hFindObject,
  197. OUT LPNTMS_OBJECTINFORMATION pFindObjectData
  198. )
  199. {
  200. HRESULT hr = E_FAIL;
  201. try {
  202. int maxObjects = 16; // Initial size of object id array to allocate
  203. LPRMS_NTMS_SEARCH_HANDLE pFind;
  204. HANDLE hSession = m_SessionHandle;
  205. DWORD errCode;
  206. DWORD numberOfObjects = maxObjects;
  207. LPNTMS_GUID pId = ( containerId == GUID_NULL ) ? NULL : (GUID *)&containerId;
  208. LPNTMS_GUID pObjects = NULL;
  209. NTMS_OBJECTINFORMATION objectInfo;
  210. WsbAssertPointer( hFindObject );
  211. if ( INVALID_HANDLE_VALUE == hSession ) {
  212. WsbThrow( E_UNEXPECTED );
  213. }
  214. *hFindObject = NULL;
  215. memset( &objectInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  216. pObjects = (LPNTMS_GUID)WsbAlloc( maxObjects*sizeof(NTMS_GUID) );
  217. WsbAffirmPointer( pObjects );
  218. // NTMS - enumerate all objects of the given type
  219. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  220. errCode = EnumerateNtmsObject( hSession, pId, pObjects, &numberOfObjects, objectType, 0 );
  221. if ( (ERROR_OBJECT_NOT_FOUND == errCode) || (0 == numberOfObjects) ) { // Don't count on NTMS returning the correct errCode
  222. WsbThrow( RMS_E_NTMS_OBJECT_NOT_FOUND );
  223. }
  224. else if ( ERROR_INSUFFICIENT_BUFFER == errCode ) {
  225. while ( ERROR_INSUFFICIENT_BUFFER == errCode ) {
  226. // Allocate a new buffer, and retry.
  227. WsbTrace(OLESTR("CRmsNTMS::findFirstNtmsObject - Reallocating for %d objects @1.\n"), numberOfObjects);
  228. maxObjects = numberOfObjects;
  229. LPVOID pTemp = WsbRealloc( pObjects, maxObjects*sizeof(NTMS_GUID) );
  230. if( !pTemp ) {
  231. WsbFree( pObjects );
  232. WsbThrow( E_OUTOFMEMORY );
  233. }
  234. pObjects = (LPNTMS_GUID)pTemp;
  235. // NTMS - enumerate all objects of the given type
  236. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  237. errCode = EnumerateNtmsObject( hSession, pId, pObjects, &numberOfObjects, objectType, 0 );
  238. }
  239. }
  240. WsbAffirmNoError( errCode );
  241. HANDLE hTemp = (HANDLE)WsbAlloc( sizeof( RMS_NTMS_SEARCH_HANDLE) );
  242. *hFindObject = hTemp;
  243. WsbAffirmPointer( *hFindObject );
  244. pFind = (LPRMS_NTMS_SEARCH_HANDLE)*hFindObject;
  245. // Initialize the search handle
  246. if ( objectName ) {
  247. wcscpy( pFind->FindName, objectName );
  248. }
  249. else {
  250. wcscpy( pFind->FindName, OLESTR("") );
  251. }
  252. pFind->FindId = objectId;
  253. pFind->FindType = objectType;
  254. pFind->Objects = pObjects;
  255. pFind->NumberOfObjects = numberOfObjects;
  256. pFind->MaxObjects = maxObjects;
  257. pFind->Next = 0;
  258. pFind->LastError = NO_ERROR;
  259. BOOL bFound = FALSE;
  260. while( pFind->Next < pFind->NumberOfObjects ) {
  261. objectInfo.dwType = pFind->FindType;
  262. objectInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  263. // NTMS - Get object information
  264. WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
  265. errCode = GetNtmsObjectInformation( hSession, &pObjects[pFind->Next++], &objectInfo );
  266. pFind->LastError = errCode;
  267. // Media Pools require special handling because they contain other Media Pools
  268. if ( (NTMS_MEDIA_POOL == pFind->FindType) &&
  269. (objectInfo.Info.MediaPool.dwNumberOfMediaPools > 0) ) {
  270. DWORD numberToAdd = objectInfo.Info.MediaPool.dwNumberOfMediaPools;
  271. do {
  272. numberOfObjects = pFind->NumberOfObjects + numberToAdd;
  273. // Allocate a new buffer, and retry.
  274. WsbTrace(OLESTR("CRmsNTMS::findFirstNtmsObject - Reallocating for %d objects @2.\n"), numberOfObjects);
  275. maxObjects = numberOfObjects;
  276. pObjects = (LPNTMS_GUID)WsbRealloc( pFind->Objects, maxObjects*sizeof(NTMS_GUID) );
  277. WsbAffirmAlloc( pObjects );
  278. pFind->Objects = pObjects;
  279. // NTMS - enumerate all objects of the given type
  280. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  281. errCode = EnumerateNtmsObject( hSession,
  282. &objectInfo.ObjectGuid, &pObjects[pFind->NumberOfObjects],
  283. &numberToAdd, pFind->FindType, 0 );
  284. } while ( ERROR_INSUFFICIENT_BUFFER == errCode ) ;
  285. if ( NO_ERROR == errCode ) {
  286. pFind->NumberOfObjects += numberToAdd;
  287. pFind->MaxObjects = maxObjects;
  288. }
  289. else {
  290. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  291. OLESTR("EnumerateNtmsObject"),
  292. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  293. NULL );
  294. WsbAffirmNoError(errCode);
  295. }
  296. }
  297. if ( NO_ERROR == pFind->LastError ) {
  298. // Now see if it is the one we're looking for
  299. if ( GUID_NULL != pFind->FindId ) {
  300. if ( pFind->FindId == objectInfo.ObjectGuid ) { // Match the GUID
  301. bFound = TRUE;
  302. if ( pFindObjectData != NULL ) {
  303. memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
  304. }
  305. break;
  306. }
  307. }
  308. else if ( wcslen( pFind->FindName ) > 0 ) { // Match the Name
  309. if ( 0 == wcscmp( pFind->FindName, objectInfo.szName ) ) {
  310. bFound = TRUE;
  311. if ( pFindObjectData != NULL ) {
  312. memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
  313. }
  314. break;
  315. }
  316. }
  317. else { // Any GUID or Name
  318. bFound = TRUE;
  319. if ( pFindObjectData != NULL ) {
  320. memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
  321. }
  322. break;
  323. }
  324. }
  325. else {
  326. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  327. OLESTR("GetNTMSObjectInformation"),
  328. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  329. NULL );
  330. WsbThrow( RMS_E_NTMS_OBJECT_NOT_FOUND );
  331. }
  332. }
  333. hr = ( bFound ) ? S_OK : RMS_E_NTMS_OBJECT_NOT_FOUND;
  334. } WsbCatch(hr);
  335. return hr;
  336. }
  337. HRESULT
  338. CRmsNTMS::findNextNtmsObject(
  339. IN HANDLE hFindObject,
  340. OUT LPNTMS_OBJECTINFORMATION pFindObjectData
  341. )
  342. {
  343. HRESULT hr = E_FAIL;
  344. try {
  345. HANDLE hSession = m_SessionHandle;
  346. DWORD errCode;
  347. LPRMS_NTMS_SEARCH_HANDLE pFind = (LPRMS_NTMS_SEARCH_HANDLE)hFindObject;
  348. LPNTMS_GUID pObjects = pFind->Objects;
  349. NTMS_OBJECTINFORMATION objectInfo;
  350. if ( INVALID_HANDLE_VALUE == hSession ) {
  351. WsbThrow( E_UNEXPECTED );
  352. }
  353. BOOL bFound = FALSE;
  354. while( pFind->Next < pFind->NumberOfObjects ) {
  355. objectInfo.dwType = pFind->FindType;
  356. objectInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  357. // NTMS - get object information of next object
  358. WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
  359. errCode = GetNtmsObjectInformation( hSession, &pObjects[pFind->Next++], &objectInfo );
  360. pFind->LastError = errCode;
  361. // Media Pools require special handling because they contain other Media Pools
  362. if ( (NTMS_MEDIA_POOL == pFind->FindType) &&
  363. (objectInfo.Info.MediaPool.dwNumberOfMediaPools > 0) ) {
  364. DWORD maxObjects;
  365. DWORD numberOfObjects;
  366. DWORD numberToAdd = objectInfo.Info.MediaPool.dwNumberOfMediaPools;
  367. do {
  368. numberOfObjects = pFind->NumberOfObjects + numberToAdd;
  369. // Allocate a new buffer, and retry.
  370. WsbTrace(OLESTR("CRmsNTMS::findNextNtmsObject - Reallocating for %d objects.\n"), numberOfObjects);
  371. maxObjects = numberOfObjects;
  372. pObjects = (LPNTMS_GUID)WsbRealloc( pFind->Objects, maxObjects*sizeof(NTMS_GUID) );
  373. WsbAffirmAlloc( pObjects );
  374. pFind->Objects = pObjects;
  375. // NTMS - enumerate all objects of the given type
  376. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  377. errCode = EnumerateNtmsObject( hSession,
  378. &objectInfo.ObjectGuid, &pObjects[pFind->NumberOfObjects],
  379. &numberToAdd, pFind->FindType, 0 );
  380. } while ( ERROR_INSUFFICIENT_BUFFER == errCode ) ;
  381. if ( NO_ERROR == errCode ) {
  382. pFind->NumberOfObjects += numberToAdd;
  383. pFind->MaxObjects = maxObjects;
  384. }
  385. else {
  386. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  387. OLESTR("EnumerateNtmsObject"),
  388. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  389. NULL );
  390. WsbAffirmNoError(errCode);
  391. }
  392. }
  393. if ( NO_ERROR == pFind->LastError ) {
  394. // Now see if it is the one we're looking for
  395. if ( GUID_NULL != pFind->FindId ) {
  396. if ( pFind->FindId == objectInfo.ObjectGuid ) { // Match the GUID
  397. bFound = TRUE;
  398. if ( pFindObjectData != NULL ) {
  399. memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
  400. }
  401. break;
  402. }
  403. }
  404. else if ( wcslen( pFind->FindName ) > 0 ) { // Match the Name
  405. if ( 0 == wcscmp( pFind->FindName, objectInfo.szName ) ) {
  406. bFound = TRUE;
  407. if ( pFindObjectData != NULL ) {
  408. memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
  409. }
  410. break;
  411. }
  412. }
  413. else { // Any GUID or Name
  414. bFound = TRUE;
  415. if ( pFindObjectData != NULL ) {
  416. memcpy( pFindObjectData, &objectInfo, sizeof( NTMS_OBJECTINFORMATION ) );
  417. }
  418. break;
  419. }
  420. }
  421. else {
  422. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  423. OLESTR("GetNTMSObjectInformation"),
  424. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  425. NULL );
  426. WsbThrow( RMS_E_NTMS_OBJECT_NOT_FOUND );
  427. }
  428. }
  429. hr = (bFound) ? S_OK : RMS_E_NTMS_OBJECT_NOT_FOUND;
  430. } WsbCatch(hr);
  431. return hr;
  432. }
  433. HRESULT
  434. CRmsNTMS::findCloseNtmsObject(
  435. IN HANDLE hFindObject)
  436. {
  437. HRESULT hr = S_OK;
  438. try {
  439. WsbAffirmPointer(hFindObject); // We don't need to assert here... It's possible to call
  440. // findCloseNtmsObject even if nothing was found with
  441. // findFirstNtmsObject. Skip the free step.
  442. WsbFree(((LPRMS_NTMS_SEARCH_HANDLE)hFindObject)->Objects);
  443. WsbFree(hFindObject);
  444. } WsbCatch(hr);
  445. return hr;
  446. }
  447. HRESULT
  448. CRmsNTMS::reportNtmsObjectInformation(
  449. IN LPNTMS_OBJECTINFORMATION pObjectInfo)
  450. {
  451. HRESULT hr = S_OK;
  452. static DWORD lastTypeReported = 0;
  453. try {
  454. WsbAssertPointer( pObjectInfo );
  455. BOOL bHeaders = (lastTypeReported == pObjectInfo->dwType) ? FALSE : TRUE;
  456. lastTypeReported = pObjectInfo->dwType;
  457. // Output a header to trace file
  458. if ( bHeaders ) {
  459. switch ( pObjectInfo->dwType ) {
  460. case NTMS_UNKNOWN:
  461. case NTMS_OBJECT:
  462. WsbTrace( OLESTR("!!! WARNING !!! - CRmsServer::reportNtmsObjectInformation: report for NTMS object type: %d is not available.\n") );
  463. break;
  464. case NTMS_CHANGER:
  465. break;
  466. case NTMS_CHANGER_TYPE:
  467. break;
  468. case NTMS_COMPUTER:
  469. WsbTrace( OLESTR("!!! WARNING !!! - CRmsServer::reportNtmsObjectInformation: report for NTMS object type: %d is not available.\n") );
  470. break;
  471. case NTMS_DRIVE:
  472. case NTMS_DRIVE_TYPE:
  473. break;
  474. case NTMS_IEDOOR:
  475. case NTMS_IEPORT:
  476. WsbTrace( OLESTR("!!! WARNING !!! - CRmsServer::reportNtmsObjectInformation: report for NTMS object type: %d is not available.\n") );
  477. break;
  478. case NTMS_LIBRARY:
  479. break;
  480. case NTMS_LIBREQUEST:
  481. case NTMS_LOGICAL_MEDIA:
  482. WsbTrace( OLESTR("!!! WARNING !!! - CRmsServer::reportNtmsObjectInformation: report for NTMS object type: %d is not available.\n") );
  483. break;
  484. case NTMS_MEDIA_POOL:
  485. WsbTrace( OLESTR("GUID Enabl Type Media Type GUID Parent GUID A-Pol D-Pol Allocate Physical Logical Pools Name / Description\n") );
  486. WsbTrace( OLESTR("====================================== ===== ==== ====================================== ====================================== ===== ===== ======== ======== ======== ===== ========================================\n") );
  487. break;
  488. case NTMS_MEDIA_TYPE:
  489. WsbTrace( OLESTR("GUID Enabl Type Sides RW Name / Description\n") );
  490. WsbTrace( OLESTR("====================================== ===== ==== ===== == ========================================\n") );
  491. break;
  492. case NTMS_PARTITION:
  493. break;
  494. case NTMS_PHYSICAL_MEDIA:
  495. case NTMS_STORAGESLOT:
  496. case NTMS_OPREQUEST:
  497. default:
  498. WsbTrace( OLESTR("!!! WARNING !!! - CRmsServer::reportNtmsObjectInformation: report for object type: %d is not supported\n") );
  499. break;
  500. }
  501. }
  502. // Convert SYSTEMTIME to FILETIME for output.
  503. SYSTEMTIME sCreated, sModified;
  504. FILETIME fCreated, fModified;
  505. sCreated = pObjectInfo->Created;
  506. sModified = pObjectInfo->Modified;
  507. SystemTimeToFileTime(&sCreated, &fCreated);
  508. SystemTimeToFileTime(&sModified, &fModified);
  509. switch ( pObjectInfo->dwType ) {
  510. case NTMS_UNKNOWN:
  511. case NTMS_OBJECT:
  512. break;
  513. case NTMS_CHANGER:
  514. WsbTrace(OLESTR("Changer %d Information:\n"), pObjectInfo->Info.Changer.Number );
  515. WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
  516. WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
  517. WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
  518. WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
  519. WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
  520. WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
  521. WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
  522. WsbTrace(OLESTR(" Number......... %-d\n"), pObjectInfo->Info.Changer.Number );
  523. WsbTrace(OLESTR(" Changer Type... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Changer.ChangerType) );
  524. WsbTrace(OLESTR(" Serial Number.. <%-ls>\n"), pObjectInfo->Info.Changer.szSerialNumber );
  525. WsbTrace(OLESTR(" Revision....... <%-ls>\n"), pObjectInfo->Info.Changer.szRevision );
  526. WsbTrace(OLESTR(" Device Name.... <%-ls>\n"), pObjectInfo->Info.Changer.szDeviceName );
  527. WsbTrace(OLESTR(" SCSI Port...... %-d\n"), pObjectInfo->Info.Changer.ScsiPort );
  528. WsbTrace(OLESTR(" SCSI Bus....... %-d\n"), pObjectInfo->Info.Changer.ScsiBus );
  529. WsbTrace(OLESTR(" SCSI Target.... %-d\n"), pObjectInfo->Info.Changer.ScsiTarget );
  530. WsbTrace(OLESTR(" SCSI Lun....... %-d\n"), pObjectInfo->Info.Changer.ScsiLun );
  531. WsbTrace(OLESTR(" Library....... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Changer.Library) );
  532. break;
  533. case NTMS_CHANGER_TYPE:
  534. WsbTrace(OLESTR("Changer Type Information:\n") );
  535. WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
  536. WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
  537. WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
  538. WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
  539. WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
  540. WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
  541. WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
  542. WsbTrace(OLESTR(" Vendor......... <%-ls>\n"), pObjectInfo->Info.ChangerType.szVendor );
  543. WsbTrace(OLESTR(" Product........ <%-ls>\n"), pObjectInfo->Info.ChangerType.szProduct );
  544. WsbTrace(OLESTR(" Device Type.... %-d\n"), pObjectInfo->Info.ChangerType.DeviceType );
  545. break;
  546. case NTMS_COMPUTER:
  547. break;
  548. case NTMS_DRIVE:
  549. WsbTrace(OLESTR("Drive %d Information:\n"), pObjectInfo->Info.Drive.Number );
  550. WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
  551. WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
  552. WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
  553. WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
  554. WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
  555. WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
  556. WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
  557. WsbTrace(OLESTR(" Number......... %-d\n"), pObjectInfo->Info.Drive.Number );
  558. WsbTrace(OLESTR(" State.......... %-d\n"), pObjectInfo->Info.Drive.State );
  559. WsbTrace(OLESTR(" Drive Type..... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Drive.DriveType) );
  560. WsbTrace(OLESTR(" Device Name.... <%-ls>\n"), pObjectInfo->Info.Drive.szDeviceName );
  561. WsbTrace(OLESTR(" Serial Number.. <%-ls>\n"), pObjectInfo->Info.Drive.szSerialNumber );
  562. WsbTrace(OLESTR(" Revision....... <%-ls>\n"), pObjectInfo->Info.Drive.szRevision );
  563. WsbTrace(OLESTR(" SCSI Port...... %-d\n"), pObjectInfo->Info.Drive.ScsiPort );
  564. WsbTrace(OLESTR(" SCSI Bus....... %-d\n"), pObjectInfo->Info.Drive.ScsiBus );
  565. WsbTrace(OLESTR(" SCSI Target.... %-d\n"), pObjectInfo->Info.Drive.ScsiTarget );
  566. WsbTrace(OLESTR(" SCSI Lun....... %-d\n"), pObjectInfo->Info.Drive.ScsiLun );
  567. WsbTrace(OLESTR(" Mount Count.... %-d\n"), pObjectInfo->Info.Drive.dwMountCount );
  568. WsbTrace(OLESTR(" Last Cleaned... %02d/%02d/%02d %02d:%02d:%02d.%03d\n"),
  569. pObjectInfo->Info.Drive.LastCleanedTs.wMonth,
  570. pObjectInfo->Info.Drive.LastCleanedTs.wDay,
  571. pObjectInfo->Info.Drive.LastCleanedTs.wYear,
  572. pObjectInfo->Info.Drive.LastCleanedTs.wHour,
  573. pObjectInfo->Info.Drive.LastCleanedTs.wMinute,
  574. pObjectInfo->Info.Drive.LastCleanedTs.wSecond,
  575. pObjectInfo->Info.Drive.LastCleanedTs.wMilliseconds );
  576. WsbTrace(OLESTR(" Partition...... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Drive.SavedPartitionId) );
  577. WsbTrace(OLESTR(" Library........ %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Drive.Library) );
  578. break;
  579. case NTMS_DRIVE_TYPE:
  580. WsbTrace(OLESTR("Drive Type Information:\n") );
  581. WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
  582. WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
  583. WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
  584. WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
  585. WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
  586. WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
  587. WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
  588. WsbTrace(OLESTR(" Vendor......... <%-ls>\n"), pObjectInfo->Info.DriveType.szVendor );
  589. WsbTrace(OLESTR(" Product........ <%-ls>\n"), pObjectInfo->Info.DriveType.szProduct );
  590. WsbTrace(OLESTR(" Number of Heads %-d\n"), pObjectInfo->Info.DriveType.NumberOfHeads );
  591. WsbTrace(OLESTR(" Device Type.... %-d\n"), pObjectInfo->Info.DriveType.DeviceType );
  592. break;
  593. case NTMS_IEDOOR:
  594. case NTMS_IEPORT:
  595. break;
  596. case NTMS_LIBRARY:
  597. WsbTrace(OLESTR("Library Information:\n") );
  598. WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
  599. WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
  600. WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
  601. WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
  602. WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
  603. WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
  604. WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
  605. WsbTrace(OLESTR(" Library Type... %-d\n"), pObjectInfo->Info.Library.LibraryType );
  606. WsbTrace(OLESTR(" CleanerSlot.... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Library.CleanerSlot) );
  607. WsbTrace(OLESTR(" CleanerSlotD... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Library.CleanerSlotDefault) );
  608. WsbTrace(OLESTR(" Can Clean...... %-ls\n"), WsbBoolAsString(pObjectInfo->Info.Library.LibrarySupportsDriveCleaning) );
  609. WsbTrace(OLESTR(" Has Bar Code... %-ls\n"), WsbBoolAsString(pObjectInfo->Info.Library.BarCodeReaderInstalled) );
  610. WsbTrace(OLESTR(" Inventory Method %-d\n"), pObjectInfo->Info.Library.InventoryMethod );
  611. WsbTrace(OLESTR(" Cleans Remaining %-d\n"), pObjectInfo->Info.Library.dwCleanerUsesRemaining );
  612. WsbTrace(OLESTR(" Drives......... %-d (%d)\n"),
  613. pObjectInfo->Info.Library.dwNumberOfDrives,
  614. pObjectInfo->Info.Library.FirstDriveNumber);
  615. WsbTrace(OLESTR(" Slots.......... %-d (%d)\n"),
  616. pObjectInfo->Info.Library.dwNumberOfSlots,
  617. pObjectInfo->Info.Library.FirstSlotNumber);
  618. WsbTrace(OLESTR(" Doors.......... %-d (%d)\n"),
  619. pObjectInfo->Info.Library.dwNumberOfDoors,
  620. pObjectInfo->Info.Library.FirstDoorNumber);
  621. WsbTrace(OLESTR(" Ports.......... %-d (%d)\n"),
  622. pObjectInfo->Info.Library.dwNumberOfPorts,
  623. pObjectInfo->Info.Library.FirstPortNumber);
  624. WsbTrace(OLESTR(" Changers....... %-d (%d)\n"),
  625. pObjectInfo->Info.Library.dwNumberOfChangers,
  626. pObjectInfo->Info.Library.FirstChangerNumber);
  627. WsbTrace(OLESTR(" Media Count.... %-d\n"), pObjectInfo->Info.Library.dwNumberOfMedia );
  628. WsbTrace(OLESTR(" Media Types.... %-d\n"), pObjectInfo->Info.Library.dwNumberOfMediaTypes );
  629. WsbTrace(OLESTR(" Requests....... %-d\n"), pObjectInfo->Info.Library.dwNumberOfLibRequests );
  630. break;
  631. case NTMS_LIBREQUEST:
  632. case NTMS_LOGICAL_MEDIA:
  633. break;
  634. case NTMS_MEDIA_POOL:
  635. {
  636. // We need some temporaries since WsbGuidAsString() uses static memory to store string.
  637. CWsbStringPtr g1 = pObjectInfo->ObjectGuid;
  638. CWsbStringPtr g2 = pObjectInfo->Info.MediaPool.MediaType;
  639. CWsbStringPtr g3 = pObjectInfo->Info.MediaPool.Parent;
  640. WsbTrace( OLESTR("%ls %5ls %4d %ls %ls %5d %5d %8d %8d %8d %5d <%ls> / <%ls>\n"),
  641. (WCHAR *)g1,
  642. WsbBoolAsString(pObjectInfo->Enabled),
  643. pObjectInfo->Info.MediaPool.PoolType,
  644. (WCHAR *)g2,
  645. (WCHAR *)g3,
  646. pObjectInfo->Info.MediaPool.AllocationPolicy,
  647. pObjectInfo->Info.MediaPool.DeallocationPolicy,
  648. pObjectInfo->Info.MediaPool.dwMaxAllocates,
  649. pObjectInfo->Info.MediaPool.dwNumberOfPhysicalMedia,
  650. pObjectInfo->Info.MediaPool.dwNumberOfLogicalMedia,
  651. pObjectInfo->Info.MediaPool.dwNumberOfMediaPools,
  652. pObjectInfo->szName,
  653. pObjectInfo->szDescription );
  654. }
  655. break;
  656. case NTMS_MEDIA_TYPE:
  657. WsbTrace( OLESTR("%ls %5ls %4d %5d %2d <%ls> / <%ls>\n"),
  658. WsbGuidAsString(pObjectInfo->ObjectGuid),
  659. WsbBoolAsString(pObjectInfo->Enabled),
  660. pObjectInfo->Info.MediaType.MediaType,
  661. pObjectInfo->Info.MediaType.NumberOfSides,
  662. pObjectInfo->Info.MediaType.ReadWriteCharacteristics,
  663. pObjectInfo->szName,
  664. pObjectInfo->szDescription );
  665. break;
  666. case NTMS_PARTITION:
  667. WsbTrace(OLESTR("Partion Information:\n") );
  668. WsbTrace(OLESTR(" GUID........... %-ls\n"), WsbGuidAsString(pObjectInfo->ObjectGuid) );
  669. WsbTrace(OLESTR(" Name........... <%-ls>\n"), pObjectInfo->szName );
  670. WsbTrace(OLESTR(" Description.... <%-ls>\n"), pObjectInfo->szDescription );
  671. WsbTrace(OLESTR(" Enabled........ %-ls\n"), WsbBoolAsString(pObjectInfo->Enabled) );
  672. WsbTrace(OLESTR(" Op State....... %-ls\n"), WsbLongAsString(pObjectInfo->dwOperationalState) );
  673. WsbTrace(OLESTR(" Created........ %-ls\n"), WsbFiletimeAsString(FALSE, fCreated) );
  674. WsbTrace(OLESTR(" Modified....... %-ls\n"), WsbFiletimeAsString(FALSE, fModified) );
  675. WsbTrace(OLESTR(" PhysicalMedia.. %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Partition.PhysicalMedia));
  676. WsbTrace(OLESTR(" LogicalMedia... %-ls\n"), WsbGuidAsString(pObjectInfo->Info.Partition.LogicalMedia));
  677. WsbTrace(OLESTR(" State.......... %-d\n"), pObjectInfo->Info.Partition.State);
  678. WsbTrace(OLESTR(" Side........... %-d\n"), pObjectInfo->Info.Partition.Side);
  679. WsbTrace(OLESTR(" OmidLabelIdLen %-d\n"), pObjectInfo->Info.Partition.dwOmidLabelIdLength);
  680. WsbTrace(OLESTR(" OmidLableId:\n"));
  681. WsbTraceBuffer(pObjectInfo->Info.Partition.dwOmidLabelIdLength, pObjectInfo->Info.Partition.OmidLabelId);
  682. WsbTrace(OLESTR(" OmidLabelType.. %-ls\n"), pObjectInfo->Info.Partition.szOmidLabelType);
  683. WsbTrace(OLESTR(" OmidLabelInfo.. %-ls\n"), pObjectInfo->Info.Partition.szOmidLabelInfo);
  684. WsbTrace(OLESTR(" MountCount..... %-d\n"), pObjectInfo->Info.Partition.dwMountCount);
  685. WsbTrace(OLESTR(" AllocateCount.. %-d\n"), pObjectInfo->Info.Partition.dwAllocateCount);
  686. WsbTrace(OLESTR(" Capacity....... %-I64d\n"), pObjectInfo->Info.Partition.Capacity.QuadPart);
  687. break;
  688. case NTMS_PHYSICAL_MEDIA:
  689. case NTMS_STORAGESLOT:
  690. case NTMS_OPREQUEST:
  691. default:
  692. break;
  693. }
  694. } WsbCatch(hr);
  695. return hr;
  696. }
  697. HRESULT
  698. CRmsNTMS::getNtmsSupportFromRegistry(
  699. OUT DWORD *pNTMSSupportValue)
  700. /*++
  701. Routine Description:
  702. Determines if NTMS flag is set in the Registry.
  703. Arguments:
  704. pNTMSSupportValue - Receives the actual value of the regstry key value. Any non-zero
  705. values indicates NTMS support.
  706. Return Values:
  707. S_OK - NTMS support flag is on.
  708. S_FALSE - NTMS support flag is off.
  709. --*/
  710. {
  711. HRESULT hr = S_OK;
  712. DWORD val = RMS_DEFAULT_NTMS_SUPPORT;
  713. WsbTraceIn(OLESTR("CRmsNTMS::getNtmsSupportFromRegistry"), OLESTR(""));
  714. try {
  715. DWORD sizeGot;
  716. const int cDataSizeToGet = 100;
  717. OLECHAR dataString[cDataSizeToGet];
  718. OLECHAR *stopString;
  719. //
  720. // Get the value. If the key doesn't exists, the default value is used.
  721. //
  722. try {
  723. WsbAffirmHrOk(WsbEnsureRegistryKeyExists(NULL, RMS_REGISTRY_STRING));
  724. WsbAffirmHrOk(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_NTMS_SUPPORT,
  725. dataString, cDataSizeToGet, &sizeGot));
  726. val = wcstoul(dataString, &stopString, 10);
  727. } WsbCatch(hr);
  728. if (pNTMSSupportValue != NULL) {
  729. *pNTMSSupportValue = val;
  730. }
  731. hr = (val) ? S_OK : S_FALSE;
  732. } WsbCatchAndDo( hr,
  733. hr = S_FALSE;
  734. );
  735. WsbTraceOut(OLESTR("CRmsNTMS::getNtmsSupportFromRegistry"), OLESTR("hr = <%ls>, val = <%ld>"), WsbHrAsString(hr), val);
  736. return hr;
  737. }
  738. HRESULT
  739. CRmsNTMS::beginSession(void)
  740. /*++
  741. Implements:
  742. CRmsNTMS::beginSession
  743. --*/
  744. {
  745. HRESULT hr = S_OK;
  746. WsbTraceIn( OLESTR("CRmsNTMS::beginSession"), OLESTR("") );
  747. try {
  748. WsbAffirmHrOk(IsInstalled());
  749. WsbAffirmHrOk(endSession()); // clear the old session
  750. WsbAffirmHrOk(waitUntilReady()); // starts a new session
  751. //WsbAffirmHrOk(waitForScratchPool());
  752. } WsbCatch(hr);
  753. WsbTraceOut( OLESTR("CRmsNTMS::beginSession"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  754. return hr;
  755. }
  756. HRESULT
  757. CRmsNTMS::endSession(void)
  758. /*++
  759. Implements:
  760. CRmsNTMS::endSession
  761. --*/
  762. {
  763. HRESULT hr = S_OK;
  764. WsbTraceIn( OLESTR("CRmsNTMS::endSession"), OLESTR("") );
  765. try {
  766. if ( m_SessionHandle != INVALID_HANDLE_VALUE ) {
  767. // NTMS - Close session
  768. WsbTraceAlways(OLESTR("CloseNtmsSession()\n"));
  769. WsbAffirmNoError(CloseNtmsSession(m_SessionHandle));
  770. }
  771. } WsbCatchAndDo(hr,
  772. switch (HRESULT_CODE(hr)) {
  773. case ERROR_CONNECTION_UNAVAIL:
  774. case ERROR_INVALID_HANDLE:
  775. break;
  776. default:
  777. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  778. OLESTR("CloseNtmsSession"), OLESTR("Undocumented Error: "),
  779. WsbHrAsString(hr), NULL);
  780. break;
  781. }
  782. );
  783. m_SessionHandle = INVALID_HANDLE_VALUE;
  784. hr = S_OK;
  785. WsbTraceOut( OLESTR("CRmsNTMS::endSession"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  786. return hr;
  787. }
  788. HRESULT
  789. CRmsNTMS::waitUntilReady(void)
  790. {
  791. HRESULT hr = S_OK;
  792. WsbTraceIn(OLESTR("CRmsNTMS::waitUntilReady"), OLESTR(""));
  793. try {
  794. int retry = 360; // number of retries
  795. // Retrieve the NotificationWaitTime parameter
  796. DWORD size;
  797. OLECHAR tmpString[256];
  798. DWORD notificationWaitTime = RMS_DEFAULT_NOTIFICATION_WAIT_TIME;
  799. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_NOTIFICATION_WAIT_TIME, tmpString, 256, &size))) {
  800. notificationWaitTime = wcstol(tmpString, NULL, 10);
  801. WsbTrace(OLESTR("NotificationWaitTime is %d milliseconds.\n"), notificationWaitTime);
  802. }
  803. do {
  804. // NTMS - Open session
  805. WsbTraceAlways(OLESTR("OpenNtmsSession()\n"));
  806. CWsbStringPtr appName;
  807. WsbAffirmHr(appName.LoadFromRsc(_Module.m_hInst, IDS_PRODUCT_NAME));
  808. m_SessionHandle = OpenNtmsSession(NULL, (WCHAR *) appName, 0);
  809. if ( m_SessionHandle != INVALID_HANDLE_VALUE ) {
  810. break;
  811. }
  812. else {
  813. hr = HRESULT_FROM_WIN32(GetLastError());
  814. switch (HRESULT_CODE(hr)) {
  815. case ERROR_NOT_READY:
  816. if ( retry > 0 ) {
  817. WsbTrace(OLESTR("Waiting for NTMS to come ready - Seconds remaining before timeout: %d\n"), retry*notificationWaitTime/1000);
  818. Sleep(notificationWaitTime);
  819. hr = S_OK;
  820. }
  821. else {
  822. //
  823. // This is the last try, so log the failure.
  824. //
  825. WsbLogEvent(RMS_MESSAGE_NTMS_CONNECTION_NOT_ESABLISHED,
  826. 0, NULL, WsbHrAsString(hr), NULL);
  827. WsbThrow(RMS_E_NTMS_NOT_CONNECTED);
  828. }
  829. break;
  830. case ERROR_INVALID_COMPUTERNAME:
  831. case ERROR_INVALID_PARAMETER:
  832. case ERROR_NO_NETWORK:
  833. case ERROR_NOT_CONNECTED:
  834. WsbLogEvent(RMS_MESSAGE_NTMS_CONNECTION_NOT_ESABLISHED,
  835. 0, NULL, WsbHrAsString(hr), NULL);
  836. WsbThrow(hr);
  837. break;
  838. default:
  839. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  840. OLESTR("OpenNtmsSession"), OLESTR("Undocumented Error: "),
  841. WsbHrAsString(hr), NULL);
  842. WsbThrow(hr);
  843. break;
  844. }
  845. }
  846. } while( retry-- > 0 ) ;
  847. } WsbCatch(hr);
  848. WsbTraceOut(OLESTR("CRmsNTMS::waitUntilReady"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  849. return hr;
  850. }
  851. HRESULT
  852. CRmsNTMS::waitForScratchPool(void)
  853. {
  854. HRESULT hr = S_OK;
  855. DWORD err1 = NO_ERROR;
  856. DWORD err2 = NO_ERROR;
  857. DWORD err3 = NO_ERROR;
  858. HANDLE hNotify = INVALID_HANDLE_VALUE;
  859. WsbTraceIn(OLESTR("CRmsNTMS::waitForScratchPool"), OLESTR(""));
  860. try {
  861. int retry = 60; // number of retries
  862. // Retrieve the NotificationWaitTime parameter
  863. DWORD size;
  864. OLECHAR tmpString[256];
  865. DWORD notificationWaitTime = RMS_DEFAULT_NOTIFICATION_WAIT_TIME;
  866. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_NOTIFICATION_WAIT_TIME, tmpString, 256, &size))) {
  867. notificationWaitTime = wcstol(tmpString, NULL, 10);
  868. WsbTrace(OLESTR("NotificationWaitTime is %d milliseconds.\n"), notificationWaitTime);
  869. }
  870. if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
  871. WsbThrow(E_UNEXPECTED);
  872. }
  873. HANDLE hSession = m_SessionHandle;
  874. NTMS_OBJECTINFORMATION objectInfo;
  875. NTMS_OBJECTINFORMATION scratchInfo;
  876. NTMS_NOTIFICATIONINFORMATION notifyInfo;
  877. HANDLE hFind = NULL;
  878. BOOL bFound = FALSE;
  879. // TODO: We really should wait around until all libraries are classified.
  880. DWORD mediaCount = 0;
  881. hr = findFirstNtmsObject( NTMS_LIBRARY, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
  882. while( S_OK == hr ) {
  883. reportNtmsObjectInformation( &objectInfo );
  884. mediaCount += objectInfo.Info.Library.dwNumberOfMedia;
  885. hr = findNextNtmsObject( hFind, &objectInfo );
  886. }
  887. findCloseNtmsObject( hFind );
  888. if ( 0 == mediaCount) {
  889. WsbThrow( RMS_E_NTMS_OBJECT_NOT_FOUND );
  890. }
  891. /*
  892. // First see if there is any media to be classified, if not we don't bother waiting around for
  893. // nothing to happen.
  894. hr = findFirstNtmsObject( NTMS_PHYSICAL_MEDIA, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
  895. WsbAffirmHrOk( hr );
  896. findCloseNtmsObject( hFind );
  897. */
  898. // NTMS - Open notification channel
  899. WsbTraceAlways(OLESTR("OpenNtmsNotification()\n"));
  900. hNotify = OpenNtmsNotification(hSession, NTMS_MEDIA_POOL);
  901. if ( INVALID_HANDLE_VALUE == hNotify ) {
  902. err1 = GetLastError();
  903. WsbAffirmNoError(err1);
  904. WsbThrow(E_UNEXPECTED);
  905. }
  906. do {
  907. err2 = NO_ERROR;
  908. //
  909. // Count the number of NTMS Scratch pools, and if
  910. // there are more than one, we return. If not,
  911. // we wait until the root level scratch pool object
  912. // is updated.
  913. //
  914. // More that one scratch media pools implies that at
  915. // least one unit of media was classified. We don't
  916. // know until we complete the initialization if it
  917. // was one of the media types supported by RemoteStorage.
  918. //
  919. int count = 0;
  920. hr = findFirstNtmsObject( NTMS_MEDIA_POOL, GUID_NULL, NULL, GUID_NULL, &hFind, &objectInfo);
  921. while( S_OK == hr ) {
  922. if ( NTMS_POOLTYPE_SCRATCH == objectInfo.Info.MediaPool.PoolType ) {
  923. count++;
  924. if ( count == 1 ) {
  925. // Assueme this is the rool pool and one we'll check on for updates
  926. // If the assumption is wrong count will end up > 1.
  927. memcpy(&scratchInfo, &objectInfo, sizeof(NTMS_OBJECTINFORMATION));
  928. }
  929. }
  930. hr = findNextNtmsObject( hFind, &objectInfo );
  931. }
  932. findCloseNtmsObject( hFind );
  933. if ( count > 1 ) {
  934. bFound = TRUE;
  935. hr = S_OK;
  936. break; // Normal exit.
  937. }
  938. if ( count == 0 ) {
  939. WsbThrow(E_UNEXPECTED);
  940. }
  941. // Just one scratch pool detected... wait until a media-type specific pool
  942. // is added root scratch pool. This will show up as an update to the root
  943. // scratch pool.
  944. do {
  945. WsbTrace(OLESTR("Waiting for NTMS scratch pool - Seconds remaining before timeout: %d\n"), retry*notificationWaitTime/1000);
  946. // NTMS - Wait for notification
  947. WsbTraceAlways(OLESTR("WaitForNtmsNotification()\n"));
  948. err2 = WaitForNtmsNotification(hNotify, &notifyInfo, notificationWaitTime);
  949. if ( NO_ERROR == err2 ) {
  950. //
  951. // Note: With this notification mechanism, chances
  952. // are slim that we got notified on the object we really
  953. // care about.
  954. //
  955. WsbTrace(OLESTR("Processing: <%d> %ls\n"), notifyInfo.dwOperation, WsbGuidAsString(notifyInfo.ObjectId));
  956. if ( notifyInfo.ObjectId != scratchInfo.ObjectGuid ) {
  957. WsbTrace(OLESTR("Wrong object, try again...\n"));
  958. continue; // skip this one
  959. }
  960. else {
  961. if ( NTMS_OBJ_UPDATE != notifyInfo.dwOperation ) {
  962. WsbTrace(OLESTR("Wrong operation, try again...\n"));
  963. continue; // skip this one
  964. }
  965. else {
  966. WsbTrace(OLESTR("Scratch pool update detected.\n"));
  967. break; // A scratch pool may have inserted, go check it out...
  968. }
  969. }
  970. }
  971. else if ( ERROR_TIMEOUT != err2 && ERROR_NO_DATA != err2 ) {
  972. WsbAffirmNoError(err2);
  973. }
  974. retry--;
  975. } while( (retry > 0) && (!bFound) );
  976. } while( (retry > 0) && (!bFound) );
  977. // NTMS - Close notification channel
  978. WsbTraceAlways(OLESTR("CloseNtmsNotification()\n"));
  979. err3 = CloseNtmsNotification(hNotify);
  980. WsbAffirmNoError(err3);
  981. if ( !bFound ) {
  982. hr = RMS_E_RESOURCE_UNAVAILABLE;
  983. }
  984. } WsbCatchAndDo(hr,
  985. if ( hNotify != INVALID_HANDLE_VALUE ) {
  986. // NTMS - Close notification channel
  987. WsbTraceAlways(OLESTR("CloseNtmsNotification()\n"));
  988. err3 = CloseNtmsNotification(hNotify);
  989. }
  990. if (err1 != NO_ERROR) {
  991. // OpenNtmsNotification
  992. switch (HRESULT_CODE(hr)) {
  993. case ERROR_DATABASE_FAILURE:
  994. case ERROR_INVALID_HANDLE:
  995. case ERROR_NOT_CONNECTED:
  996. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  997. OLESTR("OpenNtmsNotification"), OLESTR(""),
  998. WsbHrAsString(hr), NULL);
  999. break;
  1000. default:
  1001. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  1002. OLESTR("OpenNtmsNotification"), OLESTR("Undocumented Error: "),
  1003. WsbHrAsString(hr), NULL);
  1004. break;
  1005. }
  1006. }
  1007. if (err2 != NO_ERROR) {
  1008. // WaitForNtmsNotification
  1009. switch (HRESULT_CODE(hr)) {
  1010. case ERROR_INVALID_HANDLE:
  1011. case ERROR_NOT_CONNECTED:
  1012. case ERROR_DATABASE_FAILURE:
  1013. case ERROR_TIMEOUT:
  1014. case ERROR_NO_DATA:
  1015. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  1016. OLESTR("WaitForNtmsNotification"), OLESTR(""),
  1017. WsbHrAsString(hr), NULL);
  1018. break;
  1019. default:
  1020. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  1021. OLESTR("WaitForNtmsNotification"), OLESTR("Undocumented Error: "),
  1022. WsbHrAsString(hr), NULL);
  1023. break;
  1024. }
  1025. }
  1026. if (err3 != NO_ERROR) {
  1027. // CloseNtmsNotification
  1028. switch (HRESULT_CODE(hr)) {
  1029. case ERROR_INVALID_HANDLE:
  1030. case ERROR_NOT_CONNECTED:
  1031. case ERROR_DATABASE_FAILURE:
  1032. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  1033. OLESTR("CloseNtmsNotification"), OLESTR(""),
  1034. WsbHrAsString(hr), NULL);
  1035. break;
  1036. default:
  1037. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  1038. OLESTR("CloseNtmsNotification"), OLESTR("Undocumented Error: "),
  1039. WsbHrAsString(hr), NULL);
  1040. break;
  1041. }
  1042. }
  1043. );
  1044. WsbTraceOut(OLESTR("CRmsNTMS::waitForScratchPool"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  1045. return hr;
  1046. }
  1047. HRESULT
  1048. CRmsNTMS::storageMediaTypeToRmsMedia(
  1049. IN NTMS_MEDIATYPEINFORMATION *pMediaTypeInfo,
  1050. OUT RmsMedia *pTranslatedMediaType)
  1051. {
  1052. HRESULT hr = S_OK;
  1053. DWORD size;
  1054. OLECHAR tmpString[256];
  1055. // Media type is the main criteria
  1056. WsbAssertPointer(pMediaTypeInfo);
  1057. STORAGE_MEDIA_TYPE mediaType = (STORAGE_MEDIA_TYPE)(pMediaTypeInfo->MediaType);
  1058. DWORD tapeEnabled = RMS_DEFAULT_TAPE;
  1059. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_TAPE, tmpString, 256, &size))) {
  1060. // Get the value.
  1061. tapeEnabled = wcstol(tmpString, NULL, 10);
  1062. }
  1063. DWORD opticalEnabled = RMS_DEFAULT_OPTICAL;
  1064. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_OPTICAL, tmpString, 256, &size))) {
  1065. // Get the value.
  1066. opticalEnabled = wcstol(tmpString, NULL, 10);
  1067. }
  1068. DWORD dvdEnabled = RMS_DEFAULT_DVD;
  1069. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_DVD, tmpString, 256, &size))) {
  1070. // Get the value.
  1071. dvdEnabled = wcstol(tmpString, NULL, 10);
  1072. }
  1073. switch ( mediaType ) {
  1074. case DDS_4mm: // Tape - DAT DDS1,2,... (all vendors) (0x20)
  1075. *pTranslatedMediaType = (tapeEnabled) ? RmsMedia4mm : RmsMediaUnknown;
  1076. break;
  1077. case MiniQic: // Tape - miniQIC Tape
  1078. case Travan: // Tape - Travan TR-1,2,3,...
  1079. case QIC: // Tape - QIC
  1080. *pTranslatedMediaType = RmsMediaUnknown;
  1081. break;
  1082. case MP_8mm: // Tape - 8mm Exabyte Metal Particle
  1083. case AME_8mm: // Tape - 8mm Exabyte Advanced Metal Evap
  1084. case AIT1_8mm: // Tape - 8mm Sony AIT1
  1085. *pTranslatedMediaType = (tapeEnabled) ? RmsMedia8mm : RmsMediaUnknown;
  1086. break;
  1087. case DLT: // Tape - DLT Compact IIIxt: IV
  1088. *pTranslatedMediaType = (tapeEnabled) ? RmsMediaDLT : RmsMediaUnknown;
  1089. break;
  1090. case NCTP: // Tape - Philips NCTP
  1091. case IBM_3480: // Tape - IBM 3480
  1092. case IBM_3490E: // Tape - IBM 3490E
  1093. case IBM_Magstar_3590: // Tape - IBM Magstar 3590
  1094. case IBM_Magstar_MP: // Tape - IBM Magstar MP
  1095. case STK_DATA_D3: // Tape - STK Data D3
  1096. case SONY_DTF: // Tape - Sony DTF
  1097. case DV_6mm: // Tape - 6mm Digital Video
  1098. case DMI: // Tape - Exabyte DMI and compatibles
  1099. case SONY_D2: // Tape - Sony D2S and D2L
  1100. case CLEANER_CARTRIDGE: // Cleaner - All Drive types that support Drive Cleaners
  1101. case CD_ROM: // Opt_Disk - CD
  1102. case CD_R: // Opt_Disk - CD-Recordable (Write Once)
  1103. case CD_RW: // Opt_Disk - CD-Rewriteable
  1104. case DVD_ROM: // Opt_Disk - DVD-ROM
  1105. case DVD_R: // Opt_Disk - DVD-Recordable (Write Once)
  1106. case MO_5_WO: // Opt_Disk - MO 5.25" Write Once
  1107. *pTranslatedMediaType = RmsMediaUnknown;
  1108. break;
  1109. case DVD_RW: // Opt_Disk - DVD-Rewriteable
  1110. *pTranslatedMediaType = (dvdEnabled) ? RmsMediaDVD : RmsMediaUnknown;
  1111. break;
  1112. case MO_5_RW: // Opt_Disk - MO 5.25" Rewriteable (not LIMDOW)
  1113. case MO_3_RW: // Opt_Disk - 3.5" Rewriteable MO Disk
  1114. case MO_5_LIMDOW: // Opt_Disk - MO 5.25" Rewriteable (LIMDOW)
  1115. case PC_5_RW: // Opt_Disk - Phase Change 5.25" Rewriteable
  1116. case PD_5_RW: // Opt_Disk - PhaseChange Dual Rewriteable
  1117. case PINNACLE_APEX_5_RW: // Opt_Disk - Pinnacle Apex 4.6GB Rewriteable Optical
  1118. case NIKON_12_RW: // Opt_Disk - Nikon 12" Rewriteable
  1119. *pTranslatedMediaType = (opticalEnabled) ? RmsMediaOptical : RmsMediaUnknown;
  1120. break;
  1121. case PC_5_WO: // Opt_Disk - Phase Change 5.25" Write Once Optical
  1122. case ABL_5_WO: // Opt_Disk - Ablative 5.25" Write Once Optical
  1123. *pTranslatedMediaType = RmsMediaUnknown;
  1124. break;
  1125. case SONY_12_WO: // Opt_Disk - Sony 12" Write Once
  1126. case PHILIPS_12_WO: // Opt_Disk - Philips/LMS 12" Write Once
  1127. case HITACHI_12_WO: // Opt_Disk - Hitachi 12" Write Once
  1128. case CYGNET_12_WO: // Opt_Disk - Cygnet/ATG 12" Write Once
  1129. case KODAK_14_WO: // Opt_Disk - Kodak 14" Write Once
  1130. case MO_NFR_525: // Opt_Disk - Near Field Recording (Terastor)
  1131. case IOMEGA_ZIP: // Mag_Disk - Iomega Zip
  1132. case IOMEGA_JAZ: // Mag_Disk - Iomega Jaz
  1133. case SYQUEST_EZ135: // Mag_Disk - Syquest EZ135
  1134. case SYQUEST_EZFLYER: // Mag_Disk - Syquest EzFlyer
  1135. case SYQUEST_SYJET: // Mag_Disk - Syquest SyJet
  1136. case AVATAR_F2: // Mag_Disk - 2.5" Floppy
  1137. *pTranslatedMediaType = RmsMediaUnknown;
  1138. break;
  1139. case RemovableMedia: // This is reported on stand-alone optical drives.
  1140. default:
  1141. // Check RSM characteristics for Rewriteable Disk
  1142. if ((pMediaTypeInfo->ReadWriteCharacteristics == NTMS_MEDIARW_REWRITABLE) &&
  1143. (pMediaTypeInfo->DeviceType == FILE_DEVICE_DISK)) {
  1144. *pTranslatedMediaType = (opticalEnabled) ? RmsMediaOptical : RmsMediaUnknown;
  1145. } else {
  1146. // Not a rewritable disk and not one of the supported tape types...
  1147. *pTranslatedMediaType = RmsMediaUnknown;
  1148. }
  1149. break;
  1150. }
  1151. if ((*pTranslatedMediaType == RmsMediaUnknown) &&
  1152. (pMediaTypeInfo->DeviceType == FILE_DEVICE_TAPE)) {
  1153. // Check in the Registry whether there are additional tapes that we need to support
  1154. ULONG *pTypes= NULL;
  1155. ULONG uTypes = 0;
  1156. if (SUCCEEDED(WsbGetRegistryValueUlongAsMultiString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_ADDITIONAL_TAPE, &pTypes, &uTypes))) {
  1157. // Compare Registry types to the media type we have
  1158. for (ULONG u=0; u<uTypes; u++) {
  1159. if ((STORAGE_MEDIA_TYPE)(pTypes[u]) == mediaType) {
  1160. // Support it !!
  1161. WsbTraceAlways(OLESTR("CRmsNTMS::storageMediaTypeToRmsMedia: Registry asks to support tape type %lu\n"),
  1162. pTypes[u]);
  1163. *pTranslatedMediaType = RmsMediaTape;
  1164. break;
  1165. }
  1166. }
  1167. }
  1168. if (pTypes != NULL) {
  1169. WsbFree(pTypes);
  1170. pTypes = NULL;
  1171. }
  1172. }
  1173. return hr;
  1174. }
  1175. HRESULT
  1176. CRmsNTMS::createMediaPools(void)
  1177. {
  1178. HRESULT hr = S_OK;
  1179. WsbTraceIn(OLESTR("CRmsNTMS::createMediaPools"), OLESTR(""));
  1180. try {
  1181. HANDLE hSession;
  1182. NTMS_GUID rootPoolId = GUID_NULL;
  1183. if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
  1184. WsbAffirmHr(beginSession());
  1185. }
  1186. hSession = m_SessionHandle;
  1187. try {
  1188. // NTMS - Create Application Media Pool.
  1189. WsbTraceAlways(OLESTR("CreateNtmsMediaPool()\n"));
  1190. WsbAffirmNoError(CreateNtmsMediaPool(hSession, REMOTE_STORAGE_APP_NAME, NULL, NTMS_OPEN_ALWAYS, NULL, &rootPoolId));
  1191. // Now set access permissions on the pool: turn off ordinary users access
  1192. WsbAffirmHrOk(setPoolDACL(&rootPoolId, DOMAIN_ALIAS_RID_USERS, REMOVE_ACE_MASK_BITS,NTMS_USE_ACCESS | NTMS_MODIFY_ACCESS | NTMS_CONTROL_ACCESS));
  1193. } WsbCatchAndDo(hr,
  1194. switch(HRESULT_CODE(hr)) {
  1195. case ERROR_INVALID_PARAMETER:
  1196. case ERROR_INVALID_HANDLE:
  1197. case ERROR_INVALID_NAME:
  1198. case ERROR_OBJECT_NOT_FOUND:
  1199. case ERROR_ALREADY_EXISTS:
  1200. case ERROR_ACCESS_DENIED:
  1201. case ERROR_DATABASE_FAILURE:
  1202. case ERROR_DATABASE_FULL:
  1203. WsbLogEvent( RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  1204. OLESTR("CreateNtmsMediaPool"), OLESTR(""),
  1205. WsbHrAsString(hr),
  1206. NULL );
  1207. break;
  1208. default:
  1209. WsbLogEvent( RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  1210. OLESTR("CreateNtmsMediaPool"), OLESTR("Undocumented Error: "),
  1211. WsbHrAsString(hr),
  1212. NULL );
  1213. break;
  1214. }
  1215. WsbThrow(hr);
  1216. );
  1217. //
  1218. // Only one of the following should be executed, comment out the other.
  1219. //
  1220. WsbAffirmHr( createMediaPoolForEveryMediaType(rootPoolId) ); // New way
  1221. /*
  1222. WsbAffirmHr( replicateScratchMediaPool(rootPoolId) ); // Old way
  1223. */
  1224. } WsbCatch(hr);
  1225. WsbTraceOut( OLESTR("CRmsNTMS::createMediaPools"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  1226. return hr;
  1227. }
  1228. HRESULT
  1229. CRmsNTMS::replicateScratchMediaPool(
  1230. IN REFGUID /*rootPoolId*/)
  1231. {
  1232. HRESULT hr = E_FAIL;
  1233. WsbTraceIn(OLESTR("CRmsNTMS::replicateScratchMediaPool"), OLESTR(""));
  1234. try {
  1235. HANDLE hSession;
  1236. DWORD errCode;
  1237. NTMS_OBJECTINFORMATION mediaTypeInfo;
  1238. NTMS_OBJECTINFORMATION mediaPoolInfo;
  1239. HANDLE hFind = NULL;
  1240. NTMS_GUID poolId = GUID_NULL;
  1241. if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
  1242. WsbAffirmHr(beginSession());
  1243. }
  1244. hSession = m_SessionHandle;
  1245. // For each media pool in the scratch pool create an application specific pool.
  1246. hr = findFirstNtmsObject( NTMS_MEDIA_POOL, GUID_NULL, NULL, GUID_NULL, &hFind, &mediaPoolInfo);
  1247. while( S_OK == hr ) {
  1248. reportNtmsObjectInformation( &mediaPoolInfo );
  1249. poolId = GUID_NULL;
  1250. try {
  1251. // Set up application specific NTMS Media Pools. One for each compatible type.
  1252. //
  1253. // To get here we had to already detect a media-type specific scratch pool
  1254. // in waitForScratchPool()
  1255. if ( NTMS_POOLTYPE_SCRATCH == mediaPoolInfo.Info.MediaPool.PoolType &&
  1256. 0 == mediaPoolInfo.Info.MediaPool.dwNumberOfMediaPools ) {
  1257. // This is a base level scratch media pool.
  1258. // Create a similar pool for application specific use.
  1259. CWsbStringPtr name = REMOTE_STORAGE_APP_NAME;
  1260. name.Append( OLESTR("\\") );
  1261. name.Append( mediaPoolInfo.szName );
  1262. NTMS_GUID mediaTypeId = mediaPoolInfo.Info.MediaPool.MediaType;
  1263. // We need more information about the media type.
  1264. memset( &mediaTypeInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  1265. mediaTypeInfo.dwType = NTMS_MEDIA_TYPE;
  1266. mediaTypeInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  1267. // NTMS - Get Media Pool Information
  1268. WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
  1269. errCode = GetNtmsObjectInformation( hSession, &mediaTypeId, &mediaTypeInfo );
  1270. if ( errCode != NO_ERROR ) {
  1271. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1272. OLESTR("GetNtmsObjectInformation"),
  1273. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1274. NULL );
  1275. WsbThrow( E_UNEXPECTED );
  1276. }
  1277. // Translate the NTMS media type into something understood by RMS
  1278. RmsMedia translatedMediaType;
  1279. storageMediaTypeToRmsMedia(&(mediaTypeInfo.Info.MediaType), &translatedMediaType);
  1280. if ( translatedMediaType != RmsMediaUnknown ) {
  1281. // This something that Remote Storage can deal with
  1282. CWsbBstrPtr mediaSetName = RMS_UNDEFINED_STRING;
  1283. CWsbBstrPtr mediaSetDesc = RMS_UNDEFINED_STRING;
  1284. BOOL mediaSetIsEnabled = FALSE;
  1285. // NTMS - Create Application Media Pool.
  1286. WsbTraceAlways(OLESTR("CreateNtmsMediaPool()\n"));
  1287. errCode = CreateNtmsMediaPool( hSession, (WCHAR *) name, &mediaTypeId, NTMS_CREATE_NEW, NULL, &poolId );
  1288. if ( ERROR_ALREADY_EXISTS == errCode ) {
  1289. // We still need the poolId of the existing pool.
  1290. // NTMS - Create Application Media Pool.
  1291. WsbTraceAlways(OLESTR("CreateNtmsMediaPool()\n"));
  1292. errCode = CreateNtmsMediaPool( hSession, (WCHAR *)name, &mediaTypeId, NTMS_OPEN_EXISTING, NULL, &poolId );
  1293. if ( errCode != NO_ERROR ) {
  1294. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1295. OLESTR("CreateNtmsMediaPool"),
  1296. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1297. NULL );
  1298. WsbThrow( E_UNEXPECTED );
  1299. }
  1300. NTMS_OBJECTINFORMATION mediaPoolInfo;
  1301. memset( &mediaPoolInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  1302. mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
  1303. mediaPoolInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  1304. // NTMS - Get Media Pool Information
  1305. WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
  1306. errCode = GetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
  1307. if ( errCode != NO_ERROR ) {
  1308. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1309. OLESTR("GetNtmsObjectInformation"),
  1310. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1311. NULL );
  1312. WsbThrow( E_UNEXPECTED );
  1313. }
  1314. // Save relevant info
  1315. mediaSetName = mediaPoolInfo.szName;
  1316. mediaSetDesc = mediaPoolInfo.szDescription;
  1317. mediaSetIsEnabled = mediaPoolInfo.Enabled;
  1318. }
  1319. else if ( NO_ERROR == errCode ) {
  1320. memset( &mediaPoolInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  1321. mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
  1322. mediaPoolInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  1323. // NTMS - Get Media Pool Information
  1324. WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
  1325. errCode = GetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
  1326. if ( errCode != NO_ERROR ) {
  1327. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1328. OLESTR("GetNtmsObjectInformation"),
  1329. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1330. NULL );
  1331. WsbThrow( E_UNEXPECTED );
  1332. }
  1333. WsbAssert( NTMS_POOLTYPE_APPLICATION == mediaPoolInfo.Info.MediaPool.PoolType, E_UNEXPECTED );
  1334. // Set media pool parameters
  1335. // Aallocation/deallocation policy
  1336. mediaPoolInfo.Info.MediaPool.AllocationPolicy = NTMS_ALLOCATE_FROMSCRATCH;
  1337. mediaPoolInfo.Info.MediaPool.DeallocationPolicy = 0;
  1338. // Max number of allocates per media
  1339. mediaPoolInfo.Info.MediaPool.dwMaxAllocates = 5;// Just a few... we automatically
  1340. // deallocate media if there's
  1341. // problem with scratch mount
  1342. // operation.
  1343. // NOTE: This can be overridden using
  1344. // the NTMS GUI.
  1345. // NTMS - Set Media Pool Information.
  1346. WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
  1347. errCode = SetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
  1348. if ( errCode != NO_ERROR ) {
  1349. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1350. OLESTR("SetNtmsObjectInformation"),
  1351. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1352. NULL );
  1353. WsbThrow( E_UNEXPECTED );
  1354. }
  1355. // Save relevant info
  1356. mediaSetName = mediaPoolInfo.szName;
  1357. mediaSetDesc = mediaPoolInfo.szDescription;
  1358. mediaSetIsEnabled = mediaPoolInfo.Enabled;
  1359. }
  1360. else {
  1361. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1362. OLESTR("CreateNtmsMediaPool"),
  1363. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1364. NULL );
  1365. WsbThrow( E_UNEXPECTED );
  1366. }
  1367. // Now we have an NTMS media pool for our specific use. Now expose it
  1368. // through the RMS interface by creating a CRmsMediaSet.
  1369. if ( poolId != GUID_NULL ) {
  1370. CComPtr<IRmsMediaSet> pMediaSet;
  1371. // Find the RmsMediaSet with the same id, or create a new one.
  1372. CComQIPtr<IRmsServer, &IID_IRmsServer> pServer = g_pServer;
  1373. WsbAffirmHr( pServer->CreateObject( poolId, CLSID_CRmsMediaSet, IID_IRmsMediaSet, RmsOpenAlways, (void **)&pMediaSet ) );
  1374. WsbTrace(OLESTR("CRmsNTMS::replicateScratchMediaPool - type %d CRmsMediaSet created.\n"), translatedMediaType);
  1375. WsbAffirmHr( pMediaSet->SetMediaSetType( RmsMediaSetNTMS ) );
  1376. WsbAffirmHr( pMediaSet->SetMediaSupported( translatedMediaType ) );
  1377. CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = pMediaSet;
  1378. WsbTrace(OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType - MediaSet: <%ls/%ls>; Enabled: %ls\n"),
  1379. WsbQuickString(WsbStringAsString(mediaSetName)),
  1380. WsbQuickString(WsbStringAsString(mediaSetDesc)),
  1381. WsbQuickString(WsbBoolAsString(mediaSetIsEnabled)));
  1382. WsbAffirmHr(pObject->SetName(mediaSetName));
  1383. WsbAffirmHr(pObject->SetDescription(mediaSetDesc));
  1384. if (!mediaSetIsEnabled) {
  1385. WsbAffirmHr(pObject->Disable(E_FAIL));
  1386. }
  1387. if (S_OK == IsMediaCopySupported(poolId)) {
  1388. WsbAffirmHr( pMediaSet->SetIsMediaCopySupported(TRUE));
  1389. }
  1390. hr = pMediaSet->IsMediaCopySupported();
  1391. WsbTrace(OLESTR("CRmsNTMS::replicateScratchMediaPool - media copies are %ls.\n"),
  1392. (S_OK == pMediaSet->IsMediaCopySupported()) ? OLESTR("enabled") : OLESTR("disabled"));
  1393. }
  1394. }
  1395. }
  1396. } WsbCatch(hr);
  1397. hr = findNextNtmsObject( hFind, &mediaPoolInfo );
  1398. } // while finding media pools
  1399. findCloseNtmsObject( hFind );
  1400. hr = S_OK;
  1401. } WsbCatch(hr);
  1402. WsbTraceOut( OLESTR("CRmsNTMS::replicateScratchMediaPool"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  1403. return hr;
  1404. }
  1405. HRESULT
  1406. CRmsNTMS::createMediaPoolForEveryMediaType(
  1407. IN REFGUID /*rootPoolId*/)
  1408. {
  1409. HRESULT hr = S_OK;
  1410. WsbTraceIn(OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType"), OLESTR(""));
  1411. try {
  1412. DWORD errCode;
  1413. if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
  1414. WsbAffirmHr(beginSession());
  1415. }
  1416. HANDLE hSession = m_SessionHandle;
  1417. HANDLE hFindLib = NULL;
  1418. NTMS_OBJECTINFORMATION libraryInfo;
  1419. BOOL bSupportedLib = FALSE;
  1420. m_dwNofLibs = 0;
  1421. hr = findFirstNtmsObject( NTMS_LIBRARY, GUID_NULL, NULL, GUID_NULL, &hFindLib, &libraryInfo);
  1422. while( S_OK == hr ) {
  1423. bSupportedLib = FALSE;
  1424. reportNtmsObjectInformation( &libraryInfo );
  1425. if (libraryInfo.Info.Library.dwNumberOfMediaTypes > 0) {
  1426. HANDLE hFindType = NULL;
  1427. NTMS_OBJECTINFORMATION mediaTypeInfo;
  1428. hr = findFirstNtmsObject( NTMS_MEDIA_TYPE, libraryInfo.ObjectGuid, NULL, GUID_NULL, &hFindType, &mediaTypeInfo);
  1429. while( S_OK == hr ) {
  1430. //
  1431. // Create an application Media Pool for each type
  1432. //
  1433. NTMS_GUID poolId;
  1434. // This is a base level scratch media pool.
  1435. // Create a similar pool for application specific use.
  1436. CWsbStringPtr name = REMOTE_STORAGE_APP_NAME;
  1437. name.Append( OLESTR("\\") );
  1438. name.Append( mediaTypeInfo.szName );
  1439. NTMS_GUID mediaTypeId = mediaTypeInfo.ObjectGuid;
  1440. // Translate the NTMS media type into something understood by RMS
  1441. RmsMedia translatedMediaType;
  1442. storageMediaTypeToRmsMedia(&(mediaTypeInfo.Info.MediaType), &translatedMediaType);
  1443. if ( translatedMediaType != RmsMediaUnknown ) {
  1444. // This something that Remote Storage can deal with
  1445. CWsbBstrPtr mediaSetName = RMS_UNDEFINED_STRING;
  1446. CWsbBstrPtr mediaSetDesc = RMS_UNDEFINED_STRING;
  1447. BOOL mediaSetIsEnabled = FALSE;
  1448. // NTMS - Create Application Media Pool.
  1449. WsbTraceAlways(OLESTR("CreateNtmsMediaPool(<%ls>) - Try New.\n"), (WCHAR *) name);
  1450. errCode = CreateNtmsMediaPool( hSession, (WCHAR *) name, &mediaTypeId, NTMS_CREATE_NEW, NULL, &poolId );
  1451. if ( ERROR_ALREADY_EXISTS == errCode ) {
  1452. WsbTraceAlways(OLESTR("MediaPool <%ls> already exists.\n"), (WCHAR *) name);
  1453. // We still need the poolId of the existing pool.
  1454. // NTMS - Create Application Media Pool.
  1455. WsbTraceAlways(OLESTR("CreateNtmsMediaPool(<%ls>) - Try Existing.\n"), (WCHAR *) name);
  1456. errCode = CreateNtmsMediaPool( hSession, (WCHAR *)name, &mediaTypeId, NTMS_OPEN_EXISTING, NULL, &poolId );
  1457. if ( errCode != NO_ERROR ) {
  1458. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1459. OLESTR("CreateNtmsMediaPool"),
  1460. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1461. NULL );
  1462. WsbThrow( E_UNEXPECTED );
  1463. }
  1464. WsbTraceAlways(OLESTR("Media Pool %ls detected.\n"), WsbGuidAsString(poolId));
  1465. NTMS_OBJECTINFORMATION mediaPoolInfo;
  1466. memset( &mediaPoolInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  1467. mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
  1468. mediaPoolInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  1469. // NTMS - Get Media Pool Information
  1470. WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
  1471. errCode = GetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
  1472. if ( errCode != NO_ERROR ) {
  1473. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1474. OLESTR("GetNtmsObjectInformation"),
  1475. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1476. NULL );
  1477. WsbThrow( E_UNEXPECTED );
  1478. }
  1479. // Save relevant info
  1480. mediaSetName = mediaPoolInfo.szName;
  1481. mediaSetDesc = mediaPoolInfo.szDescription;
  1482. mediaSetIsEnabled = mediaPoolInfo.Enabled;
  1483. }
  1484. else if ( NO_ERROR == errCode ) {
  1485. WsbTraceAlways(OLESTR("MediaPool <%ls> created.\n"), (WCHAR *) name);
  1486. NTMS_OBJECTINFORMATION mediaPoolInfo;
  1487. memset( &mediaPoolInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  1488. mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
  1489. mediaPoolInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  1490. // NTMS - Get Media Pool Information
  1491. WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
  1492. errCode = GetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
  1493. if ( errCode != NO_ERROR ) {
  1494. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1495. OLESTR("GetNtmsObjectInformation"),
  1496. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1497. NULL );
  1498. WsbThrow( E_UNEXPECTED );
  1499. }
  1500. WsbAssert( NTMS_POOLTYPE_APPLICATION == mediaPoolInfo.Info.MediaPool.PoolType, E_UNEXPECTED );
  1501. // Set media pool parameters
  1502. // Aallocation/deallocation policy
  1503. mediaPoolInfo.Info.MediaPool.AllocationPolicy = NTMS_ALLOCATE_FROMSCRATCH;
  1504. mediaPoolInfo.Info.MediaPool.DeallocationPolicy = 0;
  1505. // Max number of allocates per media
  1506. mediaPoolInfo.Info.MediaPool.dwMaxAllocates = 0;// Unlimited... we automatically
  1507. // deallocate media if there's
  1508. // problem with scratch mount
  1509. // operation.
  1510. // TODO: Verify that NTMS always allocates
  1511. // media with the lowest allocation
  1512. // count.
  1513. // NOTE: This can be overridden using
  1514. // the NTMS GUI.
  1515. // NTMS - Set Media Pool Information.
  1516. WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
  1517. errCode = SetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
  1518. if ( errCode != NO_ERROR ) {
  1519. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1520. OLESTR("SetNtmsObjectInformation"),
  1521. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1522. NULL );
  1523. WsbThrow( E_UNEXPECTED );
  1524. }
  1525. // Save relevant info
  1526. mediaSetName = mediaPoolInfo.szName;
  1527. mediaSetDesc = mediaPoolInfo.szDescription;
  1528. mediaSetIsEnabled = mediaPoolInfo.Enabled;
  1529. }
  1530. else {
  1531. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  1532. OLESTR("CreateNtmsMediaPool"),
  1533. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  1534. NULL );
  1535. WsbThrow( E_UNEXPECTED );
  1536. }
  1537. // Now set access permissions on the pool: turn off ordinary users access
  1538. WsbAffirmHrOk(setPoolDACL(&poolId, DOMAIN_ALIAS_RID_USERS, REMOVE_ACE_MASK_BITS,NTMS_USE_ACCESS | NTMS_MODIFY_ACCESS | NTMS_CONTROL_ACCESS));
  1539. // Now we have an NTMS media pool for our specific use. Now expose it
  1540. // through the RMS interface by creating a CRmsMediaSet.
  1541. if ( poolId != GUID_NULL ) {
  1542. //
  1543. // Add to CRmsMediaSet collection
  1544. //
  1545. CComPtr<IRmsMediaSet> pMediaSet;
  1546. // Find the CRmsMediaSet with the same id, or create a new one.
  1547. CComQIPtr<IRmsServer, &IID_IRmsServer> pServer = g_pServer;
  1548. WsbAffirmHr( pServer->CreateObject( poolId, CLSID_CRmsMediaSet, IID_IRmsMediaSet, RmsOpenAlways, (void **)&pMediaSet ) );
  1549. WsbTrace(OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType - type %d CRmsMediaSet established.\n"), translatedMediaType);
  1550. WsbAffirmHr( pMediaSet->SetMediaSetType( RmsMediaSetNTMS ) );
  1551. WsbAffirmHr( pMediaSet->SetMediaSupported( translatedMediaType ) );
  1552. CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = pMediaSet;
  1553. WsbTrace(OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType - MediaSet: <%ls/%ls> %ls; Enabled: %ls\n"),
  1554. WsbQuickString(WsbStringAsString(mediaSetName)),
  1555. WsbQuickString(WsbStringAsString(mediaSetDesc)),
  1556. WsbQuickString(WsbGuidAsString(poolId)),
  1557. WsbQuickString(WsbBoolAsString(mediaSetIsEnabled)));
  1558. WsbAffirmHr(pObject->SetName(mediaSetName));
  1559. WsbAffirmHr(pObject->SetDescription(mediaSetDesc));
  1560. if (!mediaSetIsEnabled) {
  1561. WsbAffirmHr(pObject->Disable(E_FAIL));
  1562. }
  1563. if (S_OK == IsMediaCopySupported(poolId)) {
  1564. WsbAffirmHr( pMediaSet->SetIsMediaCopySupported(TRUE));
  1565. }
  1566. hr = pMediaSet->IsMediaCopySupported();
  1567. WsbTrace(OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType - media copies are %ls.\n"),
  1568. (S_OK == pMediaSet->IsMediaCopySupported()) ? OLESTR("enabled") : OLESTR("disabled"));
  1569. }
  1570. // The library has a supported media type
  1571. bSupportedLib = TRUE;
  1572. }
  1573. hr = findNextNtmsObject( hFindType, &mediaTypeInfo );
  1574. }
  1575. findCloseNtmsObject( hFindType );
  1576. }
  1577. // Check if the library has supported media type
  1578. if (bSupportedLib) {
  1579. // Add library GUI to the libraries list
  1580. // (Realloc one item each time since we don't expect many items)
  1581. m_dwNofLibs++;
  1582. LPVOID pTemp = WsbRealloc(m_pLibGuids, m_dwNofLibs*sizeof(NTMS_GUID));
  1583. if (!pTemp) {
  1584. WsbThrow(E_OUTOFMEMORY);
  1585. }
  1586. m_pLibGuids = (LPNTMS_GUID)pTemp;
  1587. m_pLibGuids[m_dwNofLibs-1] = libraryInfo.ObjectGuid;
  1588. }
  1589. // Continue library enumeration
  1590. hr = findNextNtmsObject( hFindLib, &libraryInfo );
  1591. }
  1592. findCloseNtmsObject( hFindLib );
  1593. hr = S_OK;
  1594. } WsbCatch(hr);
  1595. WsbTraceOut( OLESTR("CRmsNTMS::createMediaPoolForEveryMediaType"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  1596. return hr;
  1597. }
  1598. STDMETHODIMP
  1599. CRmsNTMS::Allocate(
  1600. IN REFGUID fromMediaSet,
  1601. IN REFGUID prevSideId,
  1602. IN OUT LONGLONG *pFreeSpace,
  1603. IN BSTR displayName,
  1604. IN DWORD dwOptions,
  1605. OUT IRmsCartridge **ppCartridge)
  1606. /*++
  1607. Implements:
  1608. IRmsNTMS::Allocate
  1609. --*/
  1610. {
  1611. HRESULT hr = S_OK;
  1612. DWORD err1 = NO_ERROR;
  1613. DWORD err2 = NO_ERROR;
  1614. DWORD err3 = NO_ERROR;
  1615. DWORD err4 = NO_ERROR;
  1616. DWORD err5 = NO_ERROR;
  1617. DWORD err6 = NO_ERROR;
  1618. DWORD err7 = NO_ERROR;
  1619. WsbTraceIn(OLESTR("CRmsNTMS::Allocate"), OLESTR("<%ls> <%ls> <%ls> <%ls> <0x%08x"),
  1620. WsbGuidAsString(fromMediaSet), WsbGuidAsString(prevSideId),
  1621. WsbPtrToLonglongAsString(pFreeSpace), WsbStringAsString(displayName), dwOptions);
  1622. try {
  1623. WsbAssert(fromMediaSet != GUID_NULL, E_INVALIDARG);
  1624. WsbAssertPointer(ppCartridge);
  1625. // Retrieve the AllocateWaitTime and RequestWaitTime parameters
  1626. DWORD size;
  1627. OLECHAR tmpString[256];
  1628. DWORD allocateWaitTime;
  1629. DWORD requestWaitTime;
  1630. BOOL bShortTimeout = ( dwOptions & RMS_SHORT_TIMEOUT ) ? TRUE : FALSE;
  1631. if (bShortTimeout) {
  1632. allocateWaitTime = RMS_DEFAULT_SHORT_WAIT_TIME;
  1633. requestWaitTime = RMS_DEFAULT_SHORT_WAIT_TIME;
  1634. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_SHORT_WAIT_TIME, tmpString, 256, &size))) {
  1635. allocateWaitTime = wcstol(tmpString, NULL, 10);
  1636. requestWaitTime = wcstol(tmpString, NULL, 10);
  1637. WsbTrace(OLESTR("allocateWaitTime (Short) is %d milliseconds.\n"), allocateWaitTime);
  1638. WsbTrace(OLESTR("RequestWaitTime (Short) is %d milliseconds.\n"), requestWaitTime);
  1639. }
  1640. } else {
  1641. allocateWaitTime = RMS_DEFAULT_ALLOCATE_WAIT_TIME;
  1642. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_ALLOCATE_WAIT_TIME, tmpString, 256, &size))) {
  1643. allocateWaitTime = wcstol(tmpString, NULL, 10);
  1644. WsbTrace(OLESTR("AllocateWaitTime is %d milliseconds.\n"), allocateWaitTime);
  1645. }
  1646. requestWaitTime = RMS_DEFAULT_REQUEST_WAIT_TIME;
  1647. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_REQUEST_WAIT_TIME, tmpString, 256, &size))) {
  1648. requestWaitTime = wcstol(tmpString, NULL, 10);
  1649. WsbTrace(OLESTR("RequestWaitTime is %d milliseconds.\n"), requestWaitTime);
  1650. }
  1651. }
  1652. // Special error recovery to handle when NTMS is down, or was cycled.
  1653. do {
  1654. hr = S_OK;
  1655. HANDLE hSession = m_SessionHandle;
  1656. NTMS_GUID setId = fromMediaSet;
  1657. NTMS_GUID partId = GUID_NULL;
  1658. NTMS_GUID *pPartId = NULL;
  1659. NTMS_GUID requestId;
  1660. err1 = NO_ERROR;
  1661. err2 = NO_ERROR;
  1662. err3 = NO_ERROR;
  1663. err4 = NO_ERROR;
  1664. err5 = NO_ERROR;
  1665. err6 = NO_ERROR;
  1666. err7 = NO_ERROR;
  1667. try {
  1668. // Look for a specific media ourselves if:
  1669. // 1. A specific capacity is required AND
  1670. // 2. We do not try to allocate a second side
  1671. if (pFreeSpace && (prevSideId == GUID_NULL)) {
  1672. if (*pFreeSpace > 0) {
  1673. int retry = 3; // Give the operator 3 chances to get it right!
  1674. do {
  1675. // We need to allocate a unit of media that matches the capacity specified.
  1676. //
  1677. // Enumerate the partitions in the scratch pool of the same type as
  1678. // specified to find a capatible unit of media
  1679. //
  1680. // First find the media type we looking for
  1681. NTMS_OBJECTINFORMATION mediaPoolInfo;
  1682. NTMS_OBJECTINFORMATION partitionInfo;
  1683. HANDLE hFindPool = NULL;
  1684. HANDLE hFindPart = NULL;
  1685. BOOL bFound = FALSE;
  1686. NTMS_GUID scratchPoolId;
  1687. err1 = NO_ERROR;
  1688. err2 = NO_ERROR;
  1689. err3 = NO_ERROR;
  1690. err4 = NO_ERROR;
  1691. err5 = NO_ERROR;
  1692. err6 = NO_ERROR;
  1693. err7 = NO_ERROR;
  1694. // First look in our pool for scratch media of the correct size
  1695. hr = findFirstNtmsObject(NTMS_PARTITION, setId, NULL, GUID_NULL, &hFindPart, &partitionInfo);
  1696. while(S_OK == hr) {
  1697. reportNtmsObjectInformation(&partitionInfo);
  1698. if ((TRUE == partitionInfo.Enabled) &&
  1699. (NTMS_READY == partitionInfo.dwOperationalState) &&
  1700. (NTMS_PARTSTATE_AVAILABLE == partitionInfo.Info.Partition.State) &&
  1701. (partitionInfo.Info.Partition.Capacity.QuadPart >= *pFreeSpace)) {
  1702. NTMS_GUID physicalPartMediaId = partitionInfo.Info.Partition.PhysicalMedia;
  1703. try {
  1704. // Check if the media is online and enabled
  1705. NTMS_OBJECTINFORMATION mediaPartInfo;
  1706. mediaPartInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  1707. mediaPartInfo.dwType = NTMS_PHYSICAL_MEDIA;
  1708. // NTMS - Get physical media information
  1709. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
  1710. WsbAffirmNoError( GetNtmsObjectInformation( hSession, &physicalPartMediaId, &mediaPartInfo ) );
  1711. // Check location type, if enabled & if all new
  1712. if ( (mediaPartInfo.Info.PhysicalMedia.LocationType != NTMS_UNKNOWN)
  1713. && (mediaPartInfo.Enabled) ) {
  1714. // Ensure that ALL sides are not allocated yet
  1715. hr = EnsureAllSidesNotAllocated(physicalPartMediaId);
  1716. if (S_OK == hr) {
  1717. // We'll use this unit of media.
  1718. // Save parameterers required for Allocate.
  1719. bFound = TRUE;
  1720. partId = partitionInfo.ObjectGuid;
  1721. pPartId = &partId;
  1722. break;
  1723. } else if (S_FALSE != hr) {
  1724. WsbAffirmHr(hr);
  1725. }
  1726. }
  1727. } WsbCatchAndDo (hr,
  1728. WsbTraceAlways(OLESTR("CRmsNTMS::Allocate: Failed to check media <%ls> hr = <%ls>\n"),
  1729. WsbGuidAsString(physicalPartMediaId), WsbHrAsString(hr));
  1730. hr = S_OK;
  1731. )
  1732. }
  1733. hr = findNextNtmsObject(hFindPart, &partitionInfo);
  1734. } // while finding media pools
  1735. findCloseNtmsObject(hFindPart);
  1736. hr = S_OK;
  1737. if (!bFound) {
  1738. // Now try the Scratch Pool
  1739. memset(&mediaPoolInfo, 0, sizeof(NTMS_OBJECTINFORMATION));
  1740. mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
  1741. mediaPoolInfo.dwSize = sizeof(NTMS_OBJECTINFORMATION);
  1742. // NTMS - Get Media Pool Information
  1743. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_MEDIA_POOL)\n"));
  1744. err3 = GetNtmsObjectInformation(hSession, &setId, &mediaPoolInfo);
  1745. WsbAffirmNoError( err3 );
  1746. // Save the media type for the media pool
  1747. NTMS_GUID mediaTypeId = mediaPoolInfo.Info.MediaPool.MediaType;
  1748. // Find the scratch pool with the same media type
  1749. hr = findFirstNtmsObject(NTMS_MEDIA_POOL, GUID_NULL, NULL, GUID_NULL, &hFindPool, &mediaPoolInfo);
  1750. while(S_OK == hr) {
  1751. if ((NTMS_POOLTYPE_SCRATCH == mediaPoolInfo.Info.MediaPool.PoolType) &&
  1752. (mediaTypeId == mediaPoolInfo.Info.MediaPool.MediaType)) {
  1753. // This is a base level scratch media pool for type we're looking for.
  1754. scratchPoolId = mediaPoolInfo.ObjectGuid;
  1755. hr = findFirstNtmsObject(NTMS_PARTITION, scratchPoolId, NULL, GUID_NULL, &hFindPart, &partitionInfo);
  1756. while(S_OK == hr) {
  1757. reportNtmsObjectInformation(&partitionInfo);
  1758. if ((TRUE == partitionInfo.Enabled) &&
  1759. (NTMS_READY == partitionInfo.dwOperationalState) &&
  1760. (NTMS_PARTSTATE_AVAILABLE == partitionInfo.Info.Partition.State) &&
  1761. (partitionInfo.Info.Partition.Capacity.QuadPart >= *pFreeSpace)) {
  1762. // Check if the media is online and enabled
  1763. DWORD errPart = NO_ERROR;
  1764. NTMS_OBJECTINFORMATION mediaPartInfo;
  1765. NTMS_GUID physicalPartMediaId = partitionInfo.Info.Partition.PhysicalMedia;
  1766. mediaPartInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  1767. mediaPartInfo.dwType = NTMS_PHYSICAL_MEDIA;
  1768. // NTMS - Get physical media information
  1769. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
  1770. errPart = GetNtmsObjectInformation( hSession, &physicalPartMediaId, &mediaPartInfo );
  1771. // Ignore error here, just don't use this partition
  1772. if (errPart == NO_ERROR) {
  1773. // Check location type and if enabled
  1774. if ( (mediaPartInfo.Info.PhysicalMedia.LocationType != NTMS_UNKNOWN)
  1775. && (mediaPartInfo.Enabled) ) {
  1776. // We'll use this unit of media.
  1777. // Save parameterers required for Allocate.
  1778. bFound = TRUE;
  1779. partId = partitionInfo.ObjectGuid;
  1780. pPartId = &partId;
  1781. break;
  1782. }
  1783. } else {
  1784. WsbTraceAlways(OLESTR("CRmsNTMS::Allocate: Failed to get object info for media <%ls> hr = <%ls>\n"),
  1785. WsbGuidAsString(physicalPartMediaId), WsbHrAsString(HRESULT_FROM_WIN32(errPart)));
  1786. }
  1787. }
  1788. hr = findNextNtmsObject(hFindPart, &partitionInfo);
  1789. } // while finding media pools
  1790. findCloseNtmsObject(hFindPart);
  1791. hr = S_OK;
  1792. break;
  1793. }
  1794. hr = findNextNtmsObject(hFindPool, &mediaPoolInfo);
  1795. } // while finding media pools
  1796. findCloseNtmsObject(hFindPool);
  1797. hr = S_OK;
  1798. }
  1799. if (bFound) {
  1800. break;
  1801. }
  1802. else {
  1803. OLECHAR * messageText = NULL;
  1804. WCHAR *stringArr[2];
  1805. WCHAR capString[40];
  1806. WsbShortSizeFormat64(*pFreeSpace, capString);
  1807. stringArr[0] = mediaPoolInfo.szName;
  1808. stringArr[1] = capString;
  1809. if (0 == FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  1810. LoadLibraryEx( WSB_FACILITY_PLATFORM_NAME, NULL, LOAD_LIBRARY_AS_DATAFILE ),
  1811. RMS_MESSAGE_SCRATCH_MEDIA_REQUEST, MAKELANGID ( LANG_NEUTRAL, SUBLANG_DEFAULT ),
  1812. (LPTSTR)&messageText, 0, (va_list *)stringArr)) {
  1813. WsbTrace(OLESTR("CRmsNTMS::Allocate: FormatMessage failed: %ls\n"),
  1814. WsbHrAsString(HRESULT_FROM_WIN32(GetLastError())));
  1815. }
  1816. // NTMS - Submit operator request
  1817. WsbTraceAlways(OLESTR("SubmitNtmsOperatorRequest()\n"));
  1818. err5 = SubmitNtmsOperatorRequest(hSession, NTMS_OPREQ_NEWMEDIA, messageText, &scratchPoolId, NULL, &requestId);
  1819. LocalFree(messageText);
  1820. WsbAffirmNoError(err5);
  1821. // NTMS - Wait for operator request
  1822. WsbTraceAlways(OLESTR("WaitForNtmsOperatorRequest()\n"));
  1823. err6 = WaitForNtmsOperatorRequest(hSession, &requestId, requestWaitTime);
  1824. //
  1825. // !!! NOTE !!! At the time of this writting WaitForNtmsOperatorRequest
  1826. // did not return ERROR_TIMEOUT.
  1827. //
  1828. if (ERROR_TIMEOUT == err6) {
  1829. // Best effort cleanup...
  1830. // NTMS - Cancel operator request
  1831. WsbTraceAlways(OLESTR("CancelNtmsOperatorRequest()\n"));
  1832. err7 = CancelNtmsOperatorRequest(hSession, &requestId);
  1833. }
  1834. WsbAffirmNoError(err6);
  1835. }
  1836. WsbAssertHrOk(hr);
  1837. // At this point the operator added a compatable unit of media...
  1838. // Verify until we're exceed the retry count.
  1839. retry--;
  1840. } while (retry > 0);
  1841. if (0 == retry) {
  1842. WsbThrow(RMS_E_SCRATCH_NOT_FOUND);
  1843. }
  1844. }
  1845. }
  1846. // NTMS - Allocate a unit of scratch media
  1847. WsbTraceAlways(OLESTR("AllocateNtmsMedia()\n"));
  1848. // Set additional allocation settings
  1849. DWORD dwAllocateOptions = 0;
  1850. NTMS_GUID mediaId = prevSideId;
  1851. if (mediaId == GUID_NULL) {
  1852. dwAllocateOptions |= NTMS_ALLOCATE_NEW;
  1853. } else {
  1854. // Allocating the second side: mediaId should hold the LMID of the first side
  1855. dwAllocateOptions |= NTMS_ALLOCATE_NEXT;
  1856. }
  1857. if (dwOptions & RMS_ALLOCATE_NO_BLOCK) {
  1858. dwAllocateOptions |= NTMS_ALLOCATE_ERROR_IF_UNAVAILABLE;
  1859. allocateWaitTime = 0;
  1860. }
  1861. err1 = AllocateNtmsMedia( hSession, &setId, pPartId, &mediaId,
  1862. dwAllocateOptions, allocateWaitTime, NULL );
  1863. WsbAffirmNoError( err1 );
  1864. // Now get/set the various information fields for the unit of media.
  1865. DWORD sideNo = 2;
  1866. NTMS_GUID side[2];
  1867. // NTMS - Enumerate the sides of a unit of media
  1868. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  1869. err2 = EnumerateNtmsObject(hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0);
  1870. WsbAffirmNoError( err2 );
  1871. NTMS_OBJECTINFORMATION partitionInfo;
  1872. partitionInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  1873. partitionInfo.dwType = NTMS_PARTITION;
  1874. // NTMS - Get partition information
  1875. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
  1876. err3 = GetNtmsObjectInformation( hSession, &side[0], &partitionInfo );
  1877. WsbAffirmNoError( err3 );
  1878. NTMS_OBJECTINFORMATION mediaInfo;
  1879. NTMS_GUID physicalMediaId = partitionInfo.Info.Partition.PhysicalMedia;
  1880. mediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  1881. mediaInfo.dwType = NTMS_PHYSICAL_MEDIA;
  1882. // NTMS - Get physical media information
  1883. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
  1884. err3 = GetNtmsObjectInformation( hSession, &physicalMediaId, &mediaInfo );
  1885. WsbAffirmNoError( err3 );
  1886. NTMS_OBJECTINFORMATION logicalMediaInfo;
  1887. logicalMediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  1888. logicalMediaInfo.dwType = NTMS_LOGICAL_MEDIA;
  1889. // NTMS - Get physical media information
  1890. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_LOGICAL_MEDIA)\n"));
  1891. err3 = GetNtmsObjectInformation( hSession, &mediaId, &logicalMediaInfo );
  1892. WsbAffirmNoError( err3 );
  1893. // Save the capacity for the return arg.
  1894. if (pFreeSpace) {
  1895. *pFreeSpace = partitionInfo.Info.Partition.Capacity.QuadPart;
  1896. }
  1897. // Set name & description
  1898. CWsbStringPtr mediaDisplayName;
  1899. // Set new physical media name for first side
  1900. // Modify original name for second side
  1901. if ( !(dwAllocateOptions & NTMS_ALLOCATE_NEXT) ) {
  1902. mediaDisplayName = (WCHAR *)displayName;
  1903. } else {
  1904. WCHAR *dashPtr = wcsrchr((WCHAR *)displayName, L'-');
  1905. mediaDisplayName = mediaInfo.szName;
  1906. if (dashPtr) {
  1907. WsbAffirmHr(mediaDisplayName.Append(dashPtr));
  1908. }
  1909. }
  1910. // Set the Name to the displayName, only if there's no bar code.
  1911. if ( NTMS_BARCODESTATE_OK != mediaInfo.Info.PhysicalMedia.BarCodeState) {
  1912. wcscpy(mediaInfo.szName, mediaDisplayName);
  1913. wcscpy(partitionInfo.szName, (WCHAR *) displayName);
  1914. // NTMS doesn't allow dup logical media names. We set
  1915. // the name to the mediaId to keep it unique. The logical
  1916. // media name is not displayed in the Removable Storage UI.
  1917. wcscpy(logicalMediaInfo.szName, (WCHAR *) WsbGuidAsString(mediaId));
  1918. }
  1919. // Set the Description to the displayName
  1920. wcscpy(logicalMediaInfo.szDescription, (WCHAR *) displayName);
  1921. wcscpy(partitionInfo.szDescription, (WCHAR *) displayName);
  1922. wcscpy(mediaInfo.szDescription, (WCHAR *) mediaDisplayName);
  1923. // NTMS - Set partition information.
  1924. WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
  1925. err4 = SetNtmsObjectInformation( hSession, &side[0], &partitionInfo );
  1926. WsbAffirmNoError( err4 );
  1927. // NTMS - Set physical media information.
  1928. WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
  1929. err4 = SetNtmsObjectInformation( hSession, &physicalMediaId, &mediaInfo );
  1930. WsbAffirmNoError( err4 );
  1931. // NTMS - Set logical media information.
  1932. WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
  1933. err4 = SetNtmsObjectInformation( hSession, &mediaId, &logicalMediaInfo );
  1934. WsbAffirmNoError( err4 );
  1935. WsbAssertHrOk(FindCartridge(mediaId, ppCartridge));
  1936. WsbAssertHr((*ppCartridge)->SetStatus(RmsStatusScratch));
  1937. break;
  1938. } WsbCatchAndDo(hr,
  1939. switch (HRESULT_CODE(hr)) {
  1940. case ERROR_INVALID_HANDLE:
  1941. case ERROR_NOT_CONNECTED:
  1942. case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
  1943. case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
  1944. case RPC_S_CALL_FAILED: // Media Services crashed.
  1945. WsbAffirmHr(beginSession());
  1946. continue;
  1947. }
  1948. WsbThrow(hr);
  1949. );
  1950. } while(1);
  1951. } WsbCatchAndDo(hr,
  1952. if (err1 != NO_ERROR) {
  1953. // AllocateNtmsMedia
  1954. switch (HRESULT_CODE(hr)) {
  1955. case ERROR_TIMEOUT:
  1956. case ERROR_MEDIA_UNAVAILABLE:
  1957. hr = RMS_E_SCRATCH_NOT_FOUND;
  1958. break;
  1959. case ERROR_CANCELLED:
  1960. hr = RMS_E_CANCELLED;
  1961. break;
  1962. case ERROR_MEDIA_OFFLINE:
  1963. hr = RMS_E_MEDIA_OFFLINE;
  1964. break;
  1965. case ERROR_REQUEST_REFUSED:
  1966. hr = RMS_E_REQUEST_REFUSED;
  1967. break;
  1968. case ERROR_WRITE_PROTECT:
  1969. hr = RMS_E_WRITE_PROTECT;
  1970. break;
  1971. case ERROR_INVALID_MEDIA_POOL:
  1972. hr = RMS_E_MEDIASET_NOT_FOUND;
  1973. break;
  1974. case ERROR_ACCESS_DENIED:
  1975. case ERROR_DATABASE_FAILURE:
  1976. case ERROR_DATABASE_FULL:
  1977. case ERROR_DEVICE_NOT_AVAILABLE:
  1978. case ERROR_INVALID_HANDLE:
  1979. case ERROR_INVALID_MEDIA:
  1980. case ERROR_INVALID_PARAMETER:
  1981. case ERROR_NOT_ENOUGH_MEMORY:
  1982. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  1983. OLESTR("AllocateNtmsMedia"), OLESTR(""),
  1984. WsbHrAsString(hr), NULL);
  1985. break;
  1986. default:
  1987. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  1988. OLESTR("AllocateNtmsMedia"), OLESTR("Undocumented Error: "),
  1989. WsbHrAsString(hr), NULL);
  1990. break;
  1991. }
  1992. }
  1993. else if (err2 != NO_ERROR ) {
  1994. // EnumerateNtmsObject
  1995. switch (HRESULT_CODE(hr)) {
  1996. case ERROR_OBJECT_NOT_FOUND:
  1997. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  1998. break;
  1999. case ERROR_INVALID_PARAMETER:
  2000. case ERROR_INSUFFICIENT_BUFFER:
  2001. case ERROR_INVALID_HANDLE:
  2002. case ERROR_NOT_ENOUGH_MEMORY:
  2003. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2004. OLESTR("EnumerateNtmsObject"), OLESTR(""),
  2005. WsbHrAsString(hr), NULL);
  2006. break;
  2007. default:
  2008. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2009. OLESTR("EnumerateNtmsObject"), OLESTR("Undocumented Error: "),
  2010. WsbHrAsString(hr), NULL);
  2011. break;
  2012. }
  2013. }
  2014. else if (err3 != NO_ERROR) {
  2015. // GetNtmsObjectInformation
  2016. switch (HRESULT_CODE(hr)) {
  2017. case ERROR_OBJECT_NOT_FOUND:
  2018. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  2019. break;
  2020. case ERROR_INVALID_HANDLE:
  2021. case ERROR_INVALID_PARAMETER:
  2022. case ERROR_NOT_ENOUGH_MEMORY:
  2023. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2024. OLESTR("GetNtmsObjectInformation"), OLESTR(""),
  2025. WsbHrAsString(hr), NULL);
  2026. break;
  2027. default:
  2028. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2029. OLESTR("GetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
  2030. WsbHrAsString(hr), NULL);
  2031. break;
  2032. }
  2033. }
  2034. else if (err4 != NO_ERROR) {
  2035. // SetNtmsObjectInformation
  2036. switch (HRESULT_CODE(hr)) {
  2037. case ERROR_ACCESS_DENIED:
  2038. case ERROR_DATABASE_FAILURE:
  2039. case ERROR_DATABASE_FULL:
  2040. case ERROR_INVALID_HANDLE:
  2041. case ERROR_INVALID_PARAMETER:
  2042. case ERROR_NOT_ENOUGH_MEMORY:
  2043. case ERROR_OBJECT_NOT_FOUND:
  2044. case ERROR_OBJECT_ALREADY_EXISTS: // bmd: 1/18/99 - Not documented, but NTMS doesn't allow dup logical media names.
  2045. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2046. OLESTR("SetNtmsObjectInformation"), OLESTR(""),
  2047. WsbHrAsString(hr), NULL);
  2048. break;
  2049. default:
  2050. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2051. OLESTR("SetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
  2052. WsbHrAsString(hr), NULL);
  2053. break;
  2054. }
  2055. }
  2056. else if (err5 != NO_ERROR) {
  2057. // SubmitNtmsOperatorRequest
  2058. switch (HRESULT_CODE(hr)) {
  2059. case ERROR_ACCESS_DENIED:
  2060. case ERROR_DATABASE_FAILURE:
  2061. case ERROR_INVALID_HANDLE:
  2062. case ERROR_INVALID_PARAMETER:
  2063. case ERROR_NOT_CONNECTED:
  2064. case ERROR_OBJECT_NOT_FOUND:
  2065. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2066. OLESTR("SubmitNtmsOperatorRequest"), OLESTR(""),
  2067. WsbHrAsString(hr), NULL);
  2068. break;
  2069. default:
  2070. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2071. OLESTR("SubmitNtmsOperatorRequest"), OLESTR("Undocumented Error: "),
  2072. WsbHrAsString(hr), NULL);
  2073. break;
  2074. }
  2075. }
  2076. else if (err6 != NO_ERROR) {
  2077. // WaitForNtmsOperatorRequest
  2078. switch (HRESULT_CODE(hr)) {
  2079. case ERROR_TIMEOUT:
  2080. hr = RMS_E_TIMEOUT;
  2081. break;
  2082. case ERROR_CANCELLED:
  2083. hr = RMS_E_CANCELLED;
  2084. break;
  2085. case ERROR_REQUEST_REFUSED:
  2086. hr = RMS_E_REQUEST_REFUSED;
  2087. break;
  2088. case ERROR_ACCESS_DENIED:
  2089. case ERROR_INVALID_HANDLE:
  2090. case ERROR_INVALID_PARAMETER:
  2091. case ERROR_NOT_CONNECTED:
  2092. case ERROR_OBJECT_NOT_FOUND:
  2093. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2094. OLESTR("WaitForNtmsOperatorRequest"), OLESTR(""),
  2095. WsbHrAsString(hr), NULL);
  2096. break;
  2097. default:
  2098. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2099. OLESTR("WaitForNtmsOperatorRequest"), OLESTR("Undocumented Error: "),
  2100. WsbHrAsString(hr), NULL);
  2101. break;
  2102. }
  2103. }
  2104. );
  2105. WsbTraceOut(OLESTR("CRmsNTMS::Allocate"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  2106. return hr;
  2107. }
  2108. STDMETHODIMP
  2109. CRmsNTMS::Mount(
  2110. IN IRmsCartridge *pCart,
  2111. IN OUT IRmsDrive **ppDrive,
  2112. IN DWORD dwOptions OPTIONAL,
  2113. IN DWORD threadId OPTIONAL)
  2114. /*++
  2115. Implements:
  2116. IRmsNTMS::Mount
  2117. --*/
  2118. {
  2119. HRESULT hr = S_OK;
  2120. DWORD err1 = NO_ERROR;
  2121. DWORD err2 = NO_ERROR;
  2122. DWORD err3 = NO_ERROR;
  2123. DWORD err4 = NO_ERROR;
  2124. BOOL mediaMounted = FALSE;
  2125. BOOL bNoBlock = ( dwOptions & RMS_MOUNT_NO_BLOCK ) ? TRUE : FALSE;
  2126. // declared outside try block so it can be accessible throughout the method
  2127. DWORD sideNo = 2;
  2128. NTMS_GUID side[2];
  2129. WsbTraceIn( OLESTR("CRmsNTMS::Mount"), OLESTR("") );
  2130. try {
  2131. WsbAssertPointer(pCart);
  2132. CComPtr<IRmsDrive> pDrive;
  2133. // determine the timeout for the operator request
  2134. DWORD size;
  2135. OLECHAR tmpString[256];
  2136. BOOL bShortTimeout = ( dwOptions & RMS_SHORT_TIMEOUT ) ? TRUE : FALSE;
  2137. DWORD mountWaitTime;
  2138. if (bShortTimeout) {
  2139. mountWaitTime = RMS_DEFAULT_SHORT_WAIT_TIME;
  2140. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_SHORT_WAIT_TIME, tmpString, 256, &size))) {
  2141. mountWaitTime = wcstol(tmpString, NULL, 10);
  2142. WsbTrace(OLESTR("MountWaitTime (Short) is %d milliseconds.\n"), mountWaitTime);
  2143. }
  2144. } else {
  2145. mountWaitTime = RMS_DEFAULT_MOUNT_WAIT_TIME;
  2146. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_MOUNT_WAIT_TIME, tmpString, 256, &size))) {
  2147. mountWaitTime = wcstol(tmpString, NULL, 10);
  2148. WsbTrace(OLESTR("MountWaitTime is %d milliseconds.\n"), mountWaitTime);
  2149. }
  2150. }
  2151. NTMS_OBJECTINFORMATION driveInfo;
  2152. memset( &driveInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  2153. // Special error recovery to handle when NTMS is down, or was cycled.
  2154. do {
  2155. hr = S_OK;
  2156. HANDLE hSession = m_SessionHandle;
  2157. NTMS_GUID mediaId = GUID_NULL;
  2158. WsbAffirmHr(pCart->GetCartridgeId(&mediaId));
  2159. WsbAssert(mediaId != GUID_NULL, E_INVALIDARG);
  2160. err1 = NO_ERROR;
  2161. err2 = NO_ERROR;
  2162. err3 = NO_ERROR;
  2163. try {
  2164. // NTMS - enumerate the sides of a unit of media
  2165. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  2166. err1 = EnumerateNtmsObject( hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0 );
  2167. WsbAffirmNoError( err1 );
  2168. DWORD count = 1;
  2169. NTMS_GUID driveId;
  2170. // NTMS - issue mount request
  2171. WsbTraceAlways(OLESTR("MountNtmsMedia()\n"));
  2172. DWORD dwOpt = NTMS_MOUNT_READ | NTMS_MOUNT_WRITE;
  2173. if (bNoBlock) {
  2174. dwOpt |= (NTMS_MOUNT_ERROR_NOT_AVAILABLE | NTMS_MOUNT_ERROR_OFFLINE);
  2175. }
  2176. if (dwOptions & RMS_USE_MOUNT_NO_DEADLOCK) {
  2177. /*
  2178. DEADLOCK AVOIDANCE: when RSM support for MountNtmsMediaDA is
  2179. in, the next line should be uncommented, and the other 2 lines
  2180. in this 'if' block should be removed.
  2181. err2 = MountNtmsMediaDA( hSession, &side[0], &driveId, count, dwOpt, NTMS_PRIORITY_NORMAL, mountWaitTime, NULL, &threadId, 1);
  2182. */
  2183. UNREFERENCED_PARAMETER(threadId);
  2184. err2 = MountNtmsMedia( hSession, &side[0], &driveId, count, dwOpt, NTMS_PRIORITY_NORMAL, mountWaitTime, NULL);
  2185. } else {
  2186. err2 = MountNtmsMedia( hSession, &side[0], &driveId, count, dwOpt, NTMS_PRIORITY_NORMAL, mountWaitTime, NULL);
  2187. }
  2188. WsbAffirmNoError( err2 );
  2189. mediaMounted = TRUE;
  2190. //
  2191. // We now need two critical pieces of information. The Device name and
  2192. // the kind of media we just mounted. This gives use the essential information
  2193. // to create a data mover. Since we drill through NTMS to get this information
  2194. // we also create cartridge, drive objects.
  2195. //
  2196. driveInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  2197. driveInfo.dwType = NTMS_DRIVE;
  2198. // NTMS - get drive information
  2199. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_DRIVE)\n"));
  2200. err3 = GetNtmsObjectInformation( hSession, &driveId, &driveInfo );
  2201. WsbAffirmNoError( err3 );
  2202. break;
  2203. } WsbCatchAndDo(hr,
  2204. switch (HRESULT_CODE(hr)) {
  2205. case ERROR_INVALID_HANDLE:
  2206. case ERROR_NOT_CONNECTED:
  2207. case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
  2208. case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
  2209. case RPC_S_CALL_FAILED: // Media Services crashed.
  2210. WsbAffirmHr(beginSession());
  2211. continue;
  2212. }
  2213. WsbThrow(hr);
  2214. );
  2215. } while(1);
  2216. RmsMedia mediaType;
  2217. WsbAffirmHr(pCart->GetType((LONG *)&mediaType));
  2218. // Create Drive
  2219. WsbAssertHr(CoCreateInstance(CLSID_CRmsDrive, 0, CLSCTX_SERVER, IID_IRmsDrive, (void **)&pDrive));
  2220. CComQIPtr<IRmsChangerElement, &IID_IRmsChangerElement> pElmt = pDrive;
  2221. WsbAssertHr(pElmt->SetMediaSupported(mediaType));
  2222. CComQIPtr<IRmsDevice, &IID_IRmsDevice> pDevice = pDrive;
  2223. WsbAssertHr(pDevice->SetDeviceAddress(
  2224. (BYTE) driveInfo.Info.Drive.ScsiPort,
  2225. (BYTE) driveInfo.Info.Drive.ScsiBus,
  2226. (BYTE) driveInfo.Info.Drive.ScsiTarget,
  2227. (BYTE) driveInfo.Info.Drive.ScsiLun));
  2228. CWsbBstrPtr deviceName = driveInfo.Info.Drive.szDeviceName;
  2229. ////////////////////////////////////////////////////////////////////////////////////////
  2230. // Convert the NTMS device name to something usable.
  2231. //
  2232. switch (mediaType) {
  2233. case RmsMediaOptical:
  2234. case RmsMediaDVD:
  2235. case RmsMediaDisk:
  2236. {
  2237. // We need to convert \\.\PhysicalDriveN to something accessible by the file system.
  2238. WCHAR *szDriveLetter = NULL;
  2239. WCHAR *szVolumeName = NULL;
  2240. err4 = GetVolumesFromDrive( (WCHAR *)deviceName, &szVolumeName, &szDriveLetter );
  2241. if (szVolumeName) {
  2242. delete [] szVolumeName; // don't need it for now
  2243. }
  2244. if (NO_ERROR == err4) {
  2245. if (szDriveLetter) {
  2246. deviceName = szDriveLetter;
  2247. } else {
  2248. WsbTraceAlways(OLESTR("CRmsNTMS::Mount: GetVolumesFromDrive succeeded but output drive is NULL !!\n"));
  2249. WsbThrow(RMS_E_RESOURCE_UNAVAILABLE);
  2250. }
  2251. }
  2252. if (szDriveLetter) {
  2253. delete [] szDriveLetter;
  2254. }
  2255. WsbAffirmNoError( err4 );
  2256. WsbTrace(OLESTR("CRmsNTMS::Mount: device name after convert is %s\n"), (WCHAR *)deviceName);
  2257. }
  2258. break;
  2259. default:
  2260. break;
  2261. }
  2262. ////////////////////////////////////////////////////////////////////////////////////////
  2263. WsbAssertHr(pDevice->SetDeviceName(deviceName));
  2264. WsbAssertHr(pCart->SetDrive(pDrive));
  2265. // Fill in the return arguments.
  2266. *ppDrive = pDrive;
  2267. pDrive->AddRef();
  2268. } WsbCatchAndDo(hr,
  2269. // Process the exception
  2270. if (err1 != NO_ERROR ) {
  2271. // EnumerateNtmsObject
  2272. switch (HRESULT_CODE(hr)) {
  2273. case ERROR_OBJECT_NOT_FOUND:
  2274. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  2275. break;
  2276. case ERROR_INVALID_PARAMETER:
  2277. case ERROR_INSUFFICIENT_BUFFER:
  2278. case ERROR_INVALID_HANDLE:
  2279. case ERROR_NOT_ENOUGH_MEMORY:
  2280. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2281. OLESTR("EnumerateNtmsObject"), OLESTR(""),
  2282. WsbHrAsString(hr), NULL);
  2283. break;
  2284. default:
  2285. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2286. OLESTR("EnumerateNtmsObject"), OLESTR("Undocumented Error: "),
  2287. WsbHrAsString(hr), NULL);
  2288. break;
  2289. }
  2290. }
  2291. else if (err2 != NO_ERROR) {
  2292. // MountNtmsMedia
  2293. switch (HRESULT_CODE(hr)) {
  2294. case ERROR_TIMEOUT:
  2295. hr = RMS_E_CARTRIDGE_UNAVAILABLE;
  2296. break;
  2297. case ERROR_CANCELLED:
  2298. hr = RMS_E_CANCELLED;
  2299. break;
  2300. case ERROR_MEDIA_OFFLINE:
  2301. hr = RMS_E_MEDIA_OFFLINE;
  2302. if (bNoBlock) {
  2303. DWORD errSub = NO_ERROR;
  2304. try {
  2305. // Since we are not blocking for NTMS to ask the operator
  2306. // to mount the offline media, we do it ourselves
  2307. // create operator message
  2308. CWsbBstrPtr cartridgeName = "";
  2309. CWsbBstrPtr cartridgeDesc = "";
  2310. OLECHAR * messageText = NULL;
  2311. WCHAR *stringArr[2];
  2312. cartridgeName.Free();
  2313. WsbAffirmHr(pCart->GetName(&cartridgeName));
  2314. cartridgeDesc.Free();
  2315. WsbAffirmHr(pCart->GetDescription(&cartridgeDesc));
  2316. stringArr[0] = (WCHAR *) cartridgeName;
  2317. stringArr[1] = (WCHAR *) cartridgeDesc;
  2318. if (0 == FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  2319. LoadLibraryEx( WSB_FACILITY_PLATFORM_NAME, NULL, LOAD_LIBRARY_AS_DATAFILE ),
  2320. RMS_MESSAGE_OFFLINE_MEDIA_REQUEST, MAKELANGID ( LANG_NEUTRAL, SUBLANG_DEFAULT ),
  2321. (LPTSTR)&messageText, 0, (va_list *)stringArr)) {
  2322. WsbTrace(OLESTR("CRmsNTMS::Mount: FormatMessage failed: %ls\n"),
  2323. WsbHrAsString(HRESULT_FROM_WIN32(GetLastError())));
  2324. messageText = NULL;
  2325. }
  2326. NTMS_GUID mediaId = GUID_NULL;
  2327. NTMS_GUID libId = GUID_NULL;
  2328. NTMS_GUID requestId = GUID_NULL;
  2329. WsbAffirmHr(pCart->GetCartridgeId(&mediaId));
  2330. WsbAssert(mediaId != GUID_NULL, E_INVALIDARG);
  2331. // Library Id should be gathered here - need to clarify why
  2332. // does the GetHome return a null id !!!
  2333. // WsbAffirmHr(pCart->GetHome(NULL, &libId, NULL, NULL, NULL, NULL, NULL, NULL));
  2334. // WsbAssert(libId != GUID_NULL, E_INVALIDARG);
  2335. // submit operator request
  2336. errSub = SubmitNtmsOperatorRequest(m_SessionHandle, NTMS_OPREQ_MOVEMEDIA,
  2337. messageText, &mediaId, &libId, &requestId);
  2338. LocalFree(messageText);
  2339. WsbAffirmNoError (errSub);
  2340. } WsbCatchAndDo(hr,
  2341. // Process the error of the Corrective Action
  2342. if (errSub != NO_ERROR ) {
  2343. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2344. OLESTR("SubmitNtmsOperatorRequest"), OLESTR(""),
  2345. WsbHrAsString(hr), NULL);
  2346. }
  2347. // place back the original mane error
  2348. hr = RMS_E_MEDIA_OFFLINE;
  2349. );
  2350. }
  2351. break;
  2352. case ERROR_REQUEST_REFUSED:
  2353. hr = RMS_E_REQUEST_REFUSED;
  2354. break;
  2355. case ERROR_WRITE_PROTECT:
  2356. hr = RMS_E_WRITE_PROTECT;
  2357. break;
  2358. case ERROR_INVALID_STATE:
  2359. case ERROR_INVALID_DRIVE: {
  2360. // when performing NTMS mount in non-blocking mode , this error may
  2361. // just mean that a corrective action such as drive cleaning should
  2362. // be performed before mounting (note that ONLY when not blocking,
  2363. // NTMS can not instruct corrective actions by itself)
  2364. if (bNoBlock) {
  2365. try {
  2366. CWsbBstrPtr cartridgeName = "";
  2367. CWsbBstrPtr cartridgeDesc = "";
  2368. cartridgeName.Free();
  2369. WsbAffirmHr(pCart->GetName(&cartridgeName));
  2370. cartridgeDesc.Free();
  2371. WsbAffirmHr(pCart->GetDescription(&cartridgeDesc));
  2372. WsbLogEvent(RMS_MESSAGE_DRIVE_NOT_AVAILABLE, 0, NULL,
  2373. (WCHAR *) cartridgeName, (WCHAR *) cartridgeDesc, NULL);
  2374. } WsbCatch(hr);
  2375. break;
  2376. }
  2377. }
  2378. case ERROR_RESOURCE_DISABLED: {
  2379. // Check if the the media (cartridge) is disabled - different error should
  2380. // be returned for media and for other resources (library, drive, etc.)
  2381. HRESULT hrOrg = hr;
  2382. DWORD errSub1 = NO_ERROR;
  2383. DWORD errSub2 = NO_ERROR;
  2384. try {
  2385. // get physical media information
  2386. NTMS_OBJECTINFORMATION objectInfo;
  2387. objectInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  2388. objectInfo.dwType = NTMS_PARTITION;
  2389. WsbAssert(side[0] != GUID_NULL, E_INVALIDARG);
  2390. errSub1 = GetNtmsObjectInformation( m_SessionHandle, &side[0], &objectInfo );
  2391. WsbAffirmNoError (errSub1);
  2392. NTMS_GUID physicalMediaId = objectInfo.Info.Partition.PhysicalMedia;
  2393. WsbAssert(physicalMediaId != GUID_NULL, E_INVALIDARG);
  2394. objectInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  2395. objectInfo.dwType = NTMS_PHYSICAL_MEDIA;
  2396. errSub2 = GetNtmsObjectInformation( m_SessionHandle, &physicalMediaId, &objectInfo );
  2397. WsbAffirmNoError (errSub2);
  2398. // set our dedicated error only if (physical) media is disabled
  2399. if (! objectInfo.Enabled) {
  2400. hr = RMS_E_CARTRIDGE_DISABLED;
  2401. }
  2402. } WsbCatchAndDo(hr,
  2403. // Process the error of the get-info requests
  2404. if (errSub1 != NO_ERROR ) {
  2405. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2406. OLESTR("GetNtmsObjectInformation (Partition)"), OLESTR(""),
  2407. WsbHrAsString(hr), NULL);
  2408. } else if (errSub2 != NO_ERROR ) {
  2409. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2410. OLESTR("GetNtmsObjectInformation (Physical Media)"), OLESTR(""),
  2411. WsbHrAsString(hr), NULL);
  2412. }
  2413. // place back the original mane error
  2414. hr = hrOrg;
  2415. );
  2416. break;
  2417. }
  2418. case ERROR_ACCESS_DENIED:
  2419. case ERROR_BUSY:
  2420. case ERROR_DATABASE_FAILURE:
  2421. case ERROR_DATABASE_FULL:
  2422. case ERROR_DRIVE_MEDIA_MISMATCH:
  2423. case ERROR_INVALID_LIBRARY:
  2424. case ERROR_INVALID_MEDIA:
  2425. case ERROR_NOT_ENOUGH_MEMORY: {
  2426. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2427. OLESTR("MountNtmsMedia"), OLESTR(""),
  2428. WsbHrAsString(hr), NULL);
  2429. break;
  2430. }
  2431. default: {
  2432. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2433. OLESTR("MountNtmsMedia"), OLESTR("Undocumented Error: "),
  2434. WsbHrAsString(hr), NULL);
  2435. break;
  2436. }
  2437. }
  2438. }
  2439. else if (err3 != NO_ERROR) {
  2440. // GetNtmsObjectInformation
  2441. switch (HRESULT_CODE(hr)) {
  2442. case ERROR_OBJECT_NOT_FOUND:
  2443. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  2444. break;
  2445. case ERROR_INVALID_HANDLE:
  2446. case ERROR_INVALID_PARAMETER:
  2447. case ERROR_NOT_ENOUGH_MEMORY:
  2448. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2449. OLESTR("GetNtmsObjectInformation"), OLESTR(""),
  2450. WsbHrAsString(hr), NULL);
  2451. break;
  2452. default:
  2453. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2454. OLESTR("GetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
  2455. WsbHrAsString(hr), NULL);
  2456. break;
  2457. }
  2458. } else if (err4 != NO_ERROR) {
  2459. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2460. OLESTR("GetVolumesFromDrive"), OLESTR("Unexpected Failure: "),
  2461. WsbHrAsString(hr), NULL);
  2462. }
  2463. if (mediaMounted) {
  2464. // Something failed after the mount completed, so need to clean up...
  2465. // Dismount the media to release the resource before returning.
  2466. Dismount(pCart, FALSE);
  2467. }
  2468. );
  2469. WsbTraceOut( OLESTR("CRmsNTMS::Mount"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  2470. return hr;
  2471. }
  2472. STDMETHODIMP
  2473. CRmsNTMS::Dismount(
  2474. IN IRmsCartridge *pCart, IN DWORD dwOptions)
  2475. /*++
  2476. Implements:
  2477. IRmsNTMS::Dismount
  2478. --*/
  2479. {
  2480. HRESULT hr = S_OK;
  2481. DWORD err1 = NO_ERROR;
  2482. DWORD err2 = NO_ERROR;
  2483. WsbTraceIn( OLESTR("CRmsNTMS::Dismount"), OLESTR("") );
  2484. try {
  2485. WsbAssertPointer(pCart);
  2486. do {
  2487. hr = S_OK;
  2488. HANDLE hSession = m_SessionHandle;
  2489. NTMS_GUID mediaId = GUID_NULL;
  2490. WsbAffirmHr(pCart->GetCartridgeId(&mediaId));
  2491. WsbAssert(mediaId != GUID_NULL, E_INVALIDARG);
  2492. NTMS_GUID side[2];
  2493. DWORD sideNo = 2;
  2494. err1 = NO_ERROR;
  2495. err2 = NO_ERROR;
  2496. try {
  2497. // NTMS - enumerate the sides of a unit of media
  2498. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  2499. err1 = EnumerateNtmsObject( hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0 );
  2500. WsbAffirmNoError( err1 );
  2501. // NTMS - dismount media
  2502. DWORD dwNtmsOptions = 0;
  2503. WsbTraceAlways(OLESTR("DismountNtmsMedia()\n"));
  2504. if (! ( dwOptions & RMS_DISMOUNT_IMMEDIATE )) {
  2505. dwNtmsOptions |= NTMS_DISMOUNT_DEFERRED;
  2506. }
  2507. err2 = DismountNtmsMedia( hSession, &side[0], 1, dwNtmsOptions );
  2508. #ifdef DBG
  2509. // TODO: Remove this trap for the unexpected ERROR_ACCESS_DENIED error.
  2510. WsbAssert(err2 != ERROR_ACCESS_DENIED, HRESULT_FROM_WIN32(err2));
  2511. #endif
  2512. WsbAffirmNoError( err2 );
  2513. // Since RSM Dismount is asyncronous, we may need to wait some arbitrary time,
  2514. // in order that when we come back, the media is really dismounted
  2515. if ( (dwOptions & RMS_DISMOUNT_DEFERRED_ONLY) && (!(dwOptions & RMS_DISMOUNT_IMMEDIATE)) ) {
  2516. CComQIPtr<IRmsServer, &IID_IRmsServer> pServer = g_pServer;
  2517. if (S_OK == pServer->IsReady()) {
  2518. DWORD size;
  2519. OLECHAR tmpString[256];
  2520. DWORD waitTime = RMS_DEFAULT_AFTER_DISMOUNT_WAIT_TIME;
  2521. if (SUCCEEDED(WsbGetRegistryValueString(NULL, RMS_REGISTRY_STRING, RMS_PARAMETER_AFTER_DISMOUNT_WAIT_TIME, tmpString, 256, &size))) {
  2522. waitTime = wcstol(tmpString, NULL, 10);
  2523. WsbTrace(OLESTR("AfterDismountWaitTime is %d milliseconds.\n"), waitTime);
  2524. }
  2525. Sleep(waitTime);
  2526. }
  2527. }
  2528. break;
  2529. } WsbCatchAndDo(hr,
  2530. switch (HRESULT_CODE(hr)) {
  2531. case ERROR_INVALID_HANDLE:
  2532. case ERROR_NOT_CONNECTED:
  2533. case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
  2534. case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
  2535. case RPC_S_CALL_FAILED: // Media Services crashed.
  2536. WsbAffirmHr(beginSession());
  2537. continue;
  2538. }
  2539. WsbThrow(hr);
  2540. );
  2541. } while(1);
  2542. } WsbCatchAndDo(hr,
  2543. if (err1 != NO_ERROR) {
  2544. // EnumerateNtmsObject
  2545. switch (HRESULT_CODE(hr)) {
  2546. case ERROR_INVALID_PARAMETER:
  2547. case ERROR_INVALID_HANDLE:
  2548. case ERROR_OBJECT_NOT_FOUND:
  2549. case ERROR_NOT_ENOUGH_MEMORY:
  2550. case ERROR_INSUFFICIENT_BUFFER:
  2551. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2552. OLESTR("EnumerateNtmsObject"), OLESTR(""),
  2553. WsbHrAsString(hr), NULL);
  2554. break;
  2555. default:
  2556. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2557. OLESTR("EnumerateNtmsObject"), OLESTR("Undocumented Error: "),
  2558. WsbHrAsString(hr), NULL);
  2559. break;
  2560. }
  2561. }
  2562. else if (err2 != NO_ERROR) {
  2563. // DismountNtmsMedia
  2564. switch (HRESULT_CODE(hr)) {
  2565. case ERROR_MEDIA_OFFLINE:
  2566. hr = RMS_E_MEDIA_OFFLINE;
  2567. break;
  2568. case ERROR_TIMEOUT:
  2569. case ERROR_INVALID_MEDIA:
  2570. case ERROR_INVALID_LIBRARY:
  2571. case ERROR_DEVICE_NOT_AVAILABLE:
  2572. case ERROR_MEDIA_NOT_AVAILABLE:
  2573. case ERROR_NOT_ENOUGH_MEMORY:
  2574. case ERROR_INVALID_STATE:
  2575. case ERROR_ACCESS_DENIED:
  2576. case ERROR_DATABASE_FAILURE:
  2577. case ERROR_DATABASE_FULL:
  2578. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2579. OLESTR("DismountNtmsMedia"), OLESTR(""),
  2580. WsbHrAsString(hr), NULL);
  2581. break;
  2582. default:
  2583. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2584. OLESTR("DismountNtmsMedia"), OLESTR("Undocumented Error: "),
  2585. WsbHrAsString(hr), NULL);
  2586. break;
  2587. }
  2588. }
  2589. );
  2590. WsbTraceOut( OLESTR("CRmsNTMS::Dismount"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  2591. return hr;
  2592. }
  2593. STDMETHODIMP
  2594. CRmsNTMS::Deallocate(
  2595. IN IRmsCartridge *pCart)
  2596. /*++
  2597. Implements:
  2598. IRmsNTMS::DeallocateMedia
  2599. --*/
  2600. {
  2601. HRESULT hr = S_OK;
  2602. DWORD err1 = NO_ERROR;
  2603. DWORD err2 = NO_ERROR;
  2604. DWORD err3 = NO_ERROR;
  2605. DWORD err4 = NO_ERROR;
  2606. WsbTraceIn(OLESTR("CRmsNTMS::Deallocate"), OLESTR(""));
  2607. try {
  2608. WsbAssertPointer(pCart);
  2609. do {
  2610. hr = S_OK;
  2611. HANDLE hSession = m_SessionHandle;
  2612. NTMS_GUID mediaId = GUID_NULL;
  2613. WsbAffirmHr(pCart->GetCartridgeId(&mediaId));
  2614. WsbAssert(mediaId != GUID_NULL, E_INVALIDARG);
  2615. err1 = NO_ERROR;
  2616. err2 = NO_ERROR;
  2617. err3 = NO_ERROR;
  2618. err4 = NO_ERROR;
  2619. NTMS_OBJECTINFORMATION partitionInfo;
  2620. memset( &partitionInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  2621. DWORD sideNo = 2;
  2622. NTMS_GUID side[2];
  2623. try {
  2624. // NTMS - enumerate the sides of a unit of media
  2625. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  2626. err1 = EnumerateNtmsObject( hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0 );
  2627. WsbAffirmNoError( err1 );
  2628. // NTMS - get partition information
  2629. partitionInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  2630. partitionInfo.dwType = NTMS_PARTITION;
  2631. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
  2632. err2 = GetNtmsObjectInformation( hSession, &side[0], &partitionInfo );
  2633. WsbAffirmNoError( err2 );
  2634. // NULL the Description
  2635. wcscpy(partitionInfo.szDescription, L"");
  2636. // NTMS - Set partition information.
  2637. WsbTraceAlways(OLESTR("SetNtmsObjectInformation()\n"));
  2638. err3 = SetNtmsObjectInformation( hSession, &side[0], &partitionInfo );
  2639. WsbAffirmNoError( err3 );
  2640. // NTMS - deallocate media
  2641. WsbTraceAlways(OLESTR("DeallocateNtmsMedia()\n"));
  2642. err4 = DeallocateNtmsMedia( hSession, &mediaId, 0 );
  2643. WsbAffirmNoError( err4 );
  2644. break;
  2645. } WsbCatchAndDo(hr,
  2646. switch (HRESULT_CODE(hr)) {
  2647. case ERROR_INVALID_HANDLE:
  2648. case ERROR_NOT_CONNECTED:
  2649. case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
  2650. case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
  2651. case RPC_S_CALL_FAILED: // Media Services crashed.
  2652. WsbAffirmHr(beginSession());
  2653. continue;
  2654. }
  2655. WsbThrow(hr);
  2656. );
  2657. } while(1);
  2658. } WsbCatchAndDo(hr,
  2659. if (err1 != NO_ERROR ) {
  2660. // EnumerateNtmsObject
  2661. switch (HRESULT_CODE(hr)) {
  2662. case ERROR_OBJECT_NOT_FOUND:
  2663. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  2664. break;
  2665. case ERROR_INVALID_PARAMETER:
  2666. case ERROR_INVALID_HANDLE:
  2667. case ERROR_NOT_ENOUGH_MEMORY:
  2668. case ERROR_INSUFFICIENT_BUFFER:
  2669. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2670. OLESTR("EnumerateNtmsObject"), OLESTR(""),
  2671. WsbHrAsString(hr), NULL);
  2672. break;
  2673. default:
  2674. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2675. OLESTR("EnumerateNtmsObject"), OLESTR("Undocumented Error: "),
  2676. WsbHrAsString(hr), NULL);
  2677. break;
  2678. }
  2679. }
  2680. else if (err2 != NO_ERROR) {
  2681. // GetNtmsObjectInformation
  2682. switch (HRESULT_CODE(hr)) {
  2683. case ERROR_OBJECT_NOT_FOUND:
  2684. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  2685. break;
  2686. case ERROR_INVALID_HANDLE:
  2687. case ERROR_INVALID_PARAMETER:
  2688. case ERROR_NOT_ENOUGH_MEMORY:
  2689. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2690. OLESTR("GetNtmsObjectInformation"), OLESTR(""),
  2691. WsbHrAsString(hr), NULL);
  2692. break;
  2693. default:
  2694. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2695. OLESTR("GetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
  2696. WsbHrAsString(hr), NULL);
  2697. break;
  2698. }
  2699. }
  2700. else if (err3 != NO_ERROR) {
  2701. // SetNtmsObjectInformation
  2702. switch (HRESULT_CODE(hr)) {
  2703. case ERROR_ACCESS_DENIED:
  2704. case ERROR_DATABASE_FAILURE:
  2705. case ERROR_DATABASE_FULL:
  2706. case ERROR_INVALID_HANDLE:
  2707. case ERROR_INVALID_PARAMETER:
  2708. case ERROR_NOT_ENOUGH_MEMORY:
  2709. case ERROR_OBJECT_NOT_FOUND:
  2710. case ERROR_OBJECT_ALREADY_EXISTS: // bmd: 1/18/99 - Not documented, but NTMS doesn't allow dup logical media names.
  2711. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2712. OLESTR("SetNtmsObjectInformation"), OLESTR(""),
  2713. WsbHrAsString(hr), NULL);
  2714. break;
  2715. default:
  2716. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2717. OLESTR("SetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
  2718. WsbHrAsString(hr), NULL);
  2719. break;
  2720. }
  2721. }
  2722. else if (err4 != NO_ERROR) {
  2723. // DeallocateNtmsMedia
  2724. switch (HRESULT_CODE(hr)) {
  2725. case ERROR_INVALID_PARAMETER:
  2726. case ERROR_INVALID_HANDLE:
  2727. case ERROR_INVALID_MEDIA:
  2728. //case ERROR_INVALID_PARTITION:
  2729. case ERROR_NOT_ENOUGH_MEMORY:
  2730. case ERROR_DATABASE_FAILURE:
  2731. case ERROR_DATABASE_FULL:
  2732. case ERROR_ACCESS_DENIED:
  2733. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2734. OLESTR("DeallocateNtmsMedia"), OLESTR(""),
  2735. WsbHrAsString(hr),
  2736. NULL);
  2737. break;
  2738. default:
  2739. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2740. OLESTR("DeallocateNtmsMedia"), OLESTR("Undocumented Error: "),
  2741. WsbHrAsString(hr), NULL);
  2742. break;
  2743. }
  2744. }
  2745. );
  2746. WsbTraceOut(OLESTR("CRmsNTMS::Deallocate"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  2747. return hr;
  2748. }
  2749. STDMETHODIMP
  2750. CRmsNTMS::UpdateOmidInfo(
  2751. IN REFGUID cartId,
  2752. IN BYTE *pBuffer,
  2753. IN LONG size,
  2754. IN LONG type)
  2755. /*++
  2756. Implements:
  2757. IRmsNTMS::UpdateOmidInfo
  2758. --*/
  2759. {
  2760. HRESULT hr = S_OK;
  2761. DWORD err1 = NO_ERROR;
  2762. WsbTraceIn( OLESTR("CRmsNTMS::UpdateOmidInfo"), OLESTR("<%ls> <0x%08x> <%d>"), WsbGuidAsString(cartId), pBuffer, size );
  2763. try {
  2764. WsbAssert(cartId != GUID_NULL, E_INVALIDARG);
  2765. WsbAssertPointer(pBuffer);
  2766. WsbAssert(size > 0, E_INVALIDARG);
  2767. WsbTraceBuffer(size, pBuffer);
  2768. do {
  2769. hr = S_OK;
  2770. HANDLE hSession = m_SessionHandle;
  2771. NTMS_GUID mediaId = cartId;
  2772. err1 = NO_ERROR;
  2773. try {
  2774. // NTMS - update on media information.
  2775. WsbTraceAlways(OLESTR("UpdateNtmsOmidInfo()\n"));
  2776. switch((RmsOnMediaIdentifier)type) {
  2777. case RmsOnMediaIdentifierMTF:
  2778. err1 = UpdateNtmsOmidInfo(hSession, &mediaId, NTMS_OMID_TYPE_RAW_LABEL, size, pBuffer);
  2779. break;
  2780. case RmsOnMediaIdentifierWIN32:
  2781. WsbAssert(size == sizeof(NTMS_FILESYSTEM_INFO), E_UNEXPECTED);
  2782. err1 = UpdateNtmsOmidInfo(hSession, &mediaId, NTMS_OMID_TYPE_FILESYSTEM_INFO, size, pBuffer);
  2783. break;
  2784. default:
  2785. WsbThrow(E_UNEXPECTED);
  2786. }
  2787. WsbAffirmNoError( err1 );
  2788. break;
  2789. } WsbCatchAndDo(hr,
  2790. switch (HRESULT_CODE(hr)) {
  2791. case ERROR_INVALID_HANDLE:
  2792. case ERROR_NOT_CONNECTED:
  2793. case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
  2794. case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
  2795. case RPC_S_CALL_FAILED: // Media Services crashed.
  2796. WsbAffirmHr(beginSession());
  2797. continue;
  2798. }
  2799. WsbThrow(hr);
  2800. );
  2801. } while(1);
  2802. } WsbCatchAndDo(hr,
  2803. if (err1 != NO_ERROR) {
  2804. // UpdateNtmsOmidInfo
  2805. switch (HRESULT_CODE(hr)) {
  2806. case ERROR_ACCESS_DENIED:
  2807. case ERROR_DATABASE_FAILURE:
  2808. case ERROR_INVALID_HANDLE:
  2809. case ERROR_INVALID_MEDIA:
  2810. //case ERROR_INVALID_PARTITION:
  2811. case ERROR_INVALID_PARAMETER:
  2812. case ERROR_NOT_CONNECTED:
  2813. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2814. OLESTR("UpdateNtmsOmidInfo"), OLESTR(""),
  2815. WsbHrAsString(hr), NULL);
  2816. break;
  2817. default:
  2818. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2819. OLESTR("UpdateNtmsOmidInfo"), OLESTR("Undocumented Error: "),
  2820. WsbHrAsString(hr), NULL);
  2821. break;
  2822. }
  2823. }
  2824. );
  2825. WsbTraceOut( OLESTR("CRmsNTMS::UpdateOmidInfo"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  2826. return hr;
  2827. }
  2828. STDMETHODIMP
  2829. CRmsNTMS::GetBlockSize(
  2830. IN REFGUID cartId,
  2831. OUT LONG *pBlockSize
  2832. )
  2833. /*++
  2834. Implements:
  2835. IRmsNTMS::GetBlockSize
  2836. --*/
  2837. {
  2838. HRESULT hr = S_OK;
  2839. DWORD err1 = NO_ERROR;
  2840. WsbTraceIn(OLESTR("CRmsNTMS::GetBlockSize"), OLESTR("<%ls> <x%08x>"), WsbGuidAsString(cartId), pBlockSize);
  2841. try {
  2842. WsbAssertPointer(pBlockSize);
  2843. do {
  2844. hr = S_OK;
  2845. err1 = NO_ERROR;
  2846. HANDLE hSession = m_SessionHandle;
  2847. NTMS_GUID mediaId = cartId;
  2848. DWORD nBlockSize;
  2849. DWORD sizeOfBlockSize = sizeof(DWORD);
  2850. try {
  2851. err1 = GetNtmsObjectAttribute(hSession, &mediaId, NTMS_LOGICAL_MEDIA, OLESTR("BlockSize"), (LPVOID) &nBlockSize, &sizeOfBlockSize);
  2852. WsbAffirmNoError(err1);
  2853. *pBlockSize = (LONG) nBlockSize;
  2854. break;
  2855. } WsbCatchAndDo(hr,
  2856. switch (HRESULT_CODE(hr)) {
  2857. case ERROR_INVALID_HANDLE:
  2858. case ERROR_NOT_CONNECTED:
  2859. case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
  2860. case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
  2861. case RPC_S_CALL_FAILED: // Media Services crashed.
  2862. WsbAffirmHr(beginSession());
  2863. continue;
  2864. }
  2865. WsbThrow(hr);
  2866. );
  2867. } while(1);
  2868. } WsbCatchAndDo(hr,
  2869. if (err1 != NO_ERROR) {
  2870. // GetNtmsObjectAttribute
  2871. switch (HRESULT_CODE(hr)) {
  2872. case ERROR_OBJECT_NOT_FOUND: // Don't log this error. Attribute doesn't
  2873. break; // exist for new media. We skip this error
  2874. // and let the caller deal with it.
  2875. case ERROR_DATABASE_FAILURE: // Log these errors.
  2876. case ERROR_INVALID_HANDLE:
  2877. case ERROR_NOT_CONNECTED:
  2878. case ERROR_INSUFFICIENT_BUFFER:
  2879. case ERROR_NO_DATA:
  2880. case ERROR_INVALID_PARAMETER:
  2881. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2882. OLESTR("GetNtmsObjectAttribute"), OLESTR(""),
  2883. WsbHrAsString(hr), NULL);
  2884. break;
  2885. default:
  2886. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2887. OLESTR("GetNtmsObjectAttribute"), OLESTR("Undocumented Error: "),
  2888. WsbHrAsString(hr), NULL);
  2889. break;
  2890. }
  2891. }
  2892. );
  2893. WsbTraceOut(OLESTR("CRmsNTMS::GetBlockSize"), OLESTR("hr = <%ls>, BlockSize = <%d>"), WsbHrAsString(hr), *pBlockSize);
  2894. return hr;
  2895. }
  2896. STDMETHODIMP
  2897. CRmsNTMS::SetBlockSize(
  2898. IN REFGUID cartId,
  2899. IN LONG blockSize
  2900. )
  2901. /*++
  2902. Implements:
  2903. IRmsNTMS::SetBlockSize
  2904. --*/
  2905. {
  2906. HRESULT hr = S_OK;
  2907. DWORD err1 = NO_ERROR;
  2908. WsbTraceIn(OLESTR("CRmsNTMS::SetBlockSize"), OLESTR("<%ls> <%d>"), WsbGuidAsString(cartId), blockSize);
  2909. try {
  2910. do {
  2911. hr = S_OK;
  2912. err1 = NO_ERROR;
  2913. HANDLE hSession = m_SessionHandle;
  2914. NTMS_GUID mediaId = cartId;
  2915. DWORD nBlockSize = blockSize;
  2916. DWORD sizeOfBlockSize = sizeof(DWORD);
  2917. try {
  2918. err1 = SetNtmsObjectAttribute(hSession, &mediaId, NTMS_LOGICAL_MEDIA, OLESTR("BlockSize"), (LPVOID) &nBlockSize, sizeOfBlockSize);
  2919. WsbAffirmNoError(err1);
  2920. break;
  2921. } WsbCatchAndDo(hr,
  2922. switch (HRESULT_CODE(hr)) {
  2923. case ERROR_INVALID_HANDLE:
  2924. case ERROR_NOT_CONNECTED:
  2925. case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
  2926. case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
  2927. case RPC_S_CALL_FAILED: // Media Services crashed.
  2928. WsbAffirmHr(beginSession());
  2929. continue;
  2930. }
  2931. WsbThrow(hr);
  2932. );
  2933. } while(1);
  2934. } WsbCatchAndDo(hr,
  2935. if (err1 != NO_ERROR) {
  2936. // SetNtmsObjectAttribute
  2937. switch (HRESULT_CODE(hr)) {
  2938. case ERROR_DATABASE_FAILURE:
  2939. case ERROR_INVALID_HANDLE:
  2940. case ERROR_INSUFFICIENT_BUFFER:
  2941. case ERROR_NOT_CONNECTED:
  2942. case ERROR_NO_DATA:
  2943. case ERROR_INVALID_PARAMETER:
  2944. case ERROR_OBJECT_NOT_FOUND:
  2945. case ERROR_INVALID_NAME:
  2946. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2947. OLESTR("SetNtmsObjectAttribute"), OLESTR(""),
  2948. WsbHrAsString(hr), NULL);
  2949. break;
  2950. default:
  2951. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  2952. OLESTR("SetNtmsObjectAttribute"), OLESTR("Undocumented Error: "),
  2953. WsbHrAsString(hr), NULL);
  2954. break;
  2955. }
  2956. }
  2957. );
  2958. WsbTraceOut(OLESTR("CRmsNTMS::SetBlockSize"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  2959. return hr;
  2960. }
  2961. HRESULT
  2962. CRmsNTMS::changeState(
  2963. IN LONG newState
  2964. )
  2965. /*++
  2966. Routine Description:
  2967. Changes the state of the NTMS object.
  2968. Arguments:
  2969. None.
  2970. Return Values:
  2971. S_OK - Success.
  2972. --*/
  2973. {
  2974. HRESULT hr = S_OK;
  2975. WsbTraceIn(OLESTR("CRmsNTMS::changeState"), OLESTR("<%d>"), newState);
  2976. try {
  2977. CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = this;
  2978. WsbAssertPointer( pObject );
  2979. // TODO: Validate the state change
  2980. WsbAffirmHr(pObject->SetState(newState));
  2981. } WsbCatch(hr);
  2982. WsbTraceOut(OLESTR("CRmsNTMS::changeState"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  2983. return hr;
  2984. }
  2985. STDMETHODIMP
  2986. CRmsNTMS::ExportDatabase(void)
  2987. /*++
  2988. Implements:
  2989. CRmsNTMS::ExportDatabase
  2990. --*/
  2991. {
  2992. HRESULT hr = S_OK;
  2993. DWORD err1 = NO_ERROR;
  2994. WsbTraceIn( OLESTR("CRmsNTMS::ExportDatabase"), OLESTR(""));
  2995. try {
  2996. do {
  2997. hr = S_OK;
  2998. HANDLE hSession = m_SessionHandle;
  2999. err1 = NO_ERROR;
  3000. try {
  3001. err1 = ExportNtmsDatabase(hSession);
  3002. WsbAffirmNoError(err1);
  3003. break;
  3004. } WsbCatchAndDo(hr,
  3005. switch (HRESULT_CODE(hr)) {
  3006. case ERROR_INVALID_HANDLE:
  3007. case ERROR_NOT_CONNECTED:
  3008. case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running
  3009. case RPC_S_CALL_FAILED_DNE: // Media Services is up, handle is not valid.
  3010. case RPC_S_CALL_FAILED: // Media Services crashed.
  3011. WsbAffirmHr(beginSession());
  3012. continue;
  3013. }
  3014. WsbThrow(hr);
  3015. );
  3016. } while(1);
  3017. } WsbCatchAndDo(hr,
  3018. if (err1 != NO_ERROR) {
  3019. // ExportNtmsDatabase
  3020. switch (HRESULT_CODE(hr)) {
  3021. case ERROR_ACCESS_DENIED:
  3022. case ERROR_DATABASE_FAILURE:
  3023. case ERROR_INVALID_HANDLE:
  3024. case ERROR_NOT_CONNECTED:
  3025. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3026. OLESTR("ExportNtmsDatabase"), OLESTR(""),
  3027. WsbHrAsString(hr), NULL);
  3028. break;
  3029. default:
  3030. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3031. OLESTR("ExportNtmsDatabase"), OLESTR("Undocumented Error: "),
  3032. WsbHrAsString(hr), NULL);
  3033. break;
  3034. }
  3035. }
  3036. );
  3037. WsbTraceOut(OLESTR("CRmsNTMS::ExportDatabase"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  3038. return hr;
  3039. }
  3040. STDMETHODIMP
  3041. CRmsNTMS::FindCartridge(
  3042. IN REFGUID cartId,
  3043. OUT IRmsCartridge **ppCartridge)
  3044. /*++
  3045. Implements:
  3046. CRmsNTMS::FindCartridge
  3047. --*/
  3048. {
  3049. HRESULT hr = S_OK;
  3050. DWORD err1 = NO_ERROR;
  3051. DWORD err2 = NO_ERROR;
  3052. WsbTraceIn( OLESTR("CRmsNTMS::FindCartridge"), OLESTR("<%ls> <0x%08x>"), WsbGuidAsString(cartId), ppCartridge);
  3053. try {
  3054. WsbAssert(cartId != GUID_NULL, E_INVALIDARG);
  3055. WsbAssertPointer(ppCartridge);
  3056. NTMS_OBJECTINFORMATION partitionInfo;
  3057. memset( &partitionInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  3058. NTMS_OBJECTINFORMATION mediaInfo;
  3059. memset( &mediaInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  3060. NTMS_OBJECTINFORMATION mediaTypeInfo;
  3061. memset( &mediaTypeInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  3062. NTMS_OBJECTINFORMATION libraryInfo;
  3063. memset( &libraryInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  3064. NTMS_OBJECTINFORMATION logicalMediaInfo;
  3065. memset( &logicalMediaInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  3066. RmsMedia translatedMediaType = RmsMediaUnknown;
  3067. // Special error recovery to handle when NTMS is down, or was cycled.
  3068. do {
  3069. hr = S_OK;
  3070. HANDLE hSession = m_SessionHandle;
  3071. NTMS_GUID mediaId = cartId;
  3072. DWORD sideNo = 2;
  3073. NTMS_GUID side[2];
  3074. err1 = NO_ERROR;
  3075. err2 = NO_ERROR;
  3076. try {
  3077. // NTMS - enumerate the sides of a unit of media
  3078. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  3079. err1 = EnumerateNtmsObject( hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0 );
  3080. WsbAffirmNoError( err1 );
  3081. // NTMS - get partition information
  3082. partitionInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  3083. partitionInfo.dwType = NTMS_PARTITION;
  3084. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
  3085. err2 = GetNtmsObjectInformation( hSession, &side[0], &partitionInfo );
  3086. WsbAffirmNoError( err2 );
  3087. // NTMS - get physical media information
  3088. NTMS_GUID physicalMediaId = partitionInfo.Info.Partition.PhysicalMedia;
  3089. mediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  3090. mediaInfo.dwType = NTMS_PHYSICAL_MEDIA;
  3091. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
  3092. err2 = GetNtmsObjectInformation( hSession, &physicalMediaId, &mediaInfo );
  3093. WsbAffirmNoError( err2);
  3094. // NTMS - get media type information
  3095. NTMS_GUID mediaTypeId = mediaInfo.Info.PhysicalMedia.MediaType;
  3096. mediaTypeInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  3097. mediaTypeInfo.dwType = NTMS_MEDIA_TYPE;
  3098. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_MEDIA_TYPE)\n"));
  3099. err2 = GetNtmsObjectInformation( hSession, &mediaTypeId, &mediaTypeInfo );
  3100. WsbAffirmNoError( err2 );
  3101. // Translate the NTMS media type into something understood by RMS
  3102. storageMediaTypeToRmsMedia(&(mediaTypeInfo.Info.MediaType), &translatedMediaType);
  3103. // NTMS - get logical media information
  3104. logicalMediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  3105. logicalMediaInfo.dwType = NTMS_LOGICAL_MEDIA;
  3106. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_LOGICAL_MEDIA)\n"));
  3107. err2 = GetNtmsObjectInformation( hSession, &mediaId, &logicalMediaInfo );
  3108. WsbAffirmNoError( err2 );
  3109. // NTMS - get library information
  3110. NTMS_GUID libraryId = mediaInfo.Info.PhysicalMedia.CurrentLibrary;
  3111. libraryInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  3112. libraryInfo.dwType = NTMS_LIBRARY;
  3113. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_LIBRARY)\n"));
  3114. err2 = GetNtmsObjectInformation( hSession, &libraryId, &libraryInfo );
  3115. WsbAffirmNoError( err2 );
  3116. break;
  3117. } WsbCatchAndDo(hr,
  3118. switch (HRESULT_CODE(hr)) {
  3119. case ERROR_INVALID_HANDLE:
  3120. case ERROR_NOT_CONNECTED:
  3121. case RPC_S_SERVER_UNAVAILABLE: // Media Services is not running.
  3122. case RPC_S_CALL_FAILED_DNE: // Media Services is up; handle is not valid.
  3123. case RPC_S_CALL_FAILED: // Media Services crashed.
  3124. WsbAffirmHr(beginSession());
  3125. continue;
  3126. }
  3127. WsbThrow(hr);
  3128. );
  3129. } while(1);
  3130. // Create Cartridge
  3131. IRmsCartridge *pCart = 0;
  3132. WsbAssertHr(CoCreateInstance(CLSID_CRmsCartridge, 0, CLSCTX_SERVER,
  3133. IID_IRmsCartridge, (void **)&pCart));
  3134. // Fill in the object data
  3135. // The media Name is what is displaye by NTMS UI
  3136. CWsbBstrPtr name = mediaInfo.szName;
  3137. WsbAffirmHr(pCart->SetName(name));
  3138. // The partition Description is what is displayed by NTMS UI.
  3139. CWsbBstrPtr desc = partitionInfo.szDescription;
  3140. WsbAffirmHr(pCart->SetDescription(desc));
  3141. WsbAffirmHr(pCart->SetCartridgeId(cartId));
  3142. CWsbBstrPtr barCode = mediaInfo.Info.PhysicalMedia.szBarCode;
  3143. CWsbBstrPtr seqNo = mediaInfo.Info.PhysicalMedia.szSequenceNumber; // Not used
  3144. WsbAffirmHr(pCart->SetTagAndNumber(barCode, 0));
  3145. WsbAffirmHr(pCart->SetType((LONG) translatedMediaType));
  3146. switch (mediaInfo.Info.PhysicalMedia.MediaState) {
  3147. case NTMS_MEDIASTATE_IDLE:
  3148. case NTMS_MEDIASTATE_UNLOADED:
  3149. WsbAffirmHr(pCart->SetIsAvailable(TRUE));
  3150. break;
  3151. default:
  3152. WsbAffirmHr(pCart->SetIsAvailable(FALSE));
  3153. break;
  3154. }
  3155. RmsElement type = RmsElementUnknown;
  3156. if ( NTMS_LIBRARYTYPE_ONLINE == libraryInfo.Info.Library.LibraryType ) {
  3157. switch (mediaInfo.Info.PhysicalMedia.LocationType) {
  3158. case NTMS_STORAGESLOT:
  3159. type = RmsElementStorage;
  3160. break;
  3161. case NTMS_DRIVE:
  3162. type = RmsElementDrive;
  3163. break;
  3164. case NTMS_IEPORT:
  3165. type = RmsElementIEPort;
  3166. break;
  3167. case NTMS_CHANGER:
  3168. type = RmsElementChanger;
  3169. break;
  3170. default:
  3171. type = RmsElementUnknown;
  3172. break;
  3173. }
  3174. }
  3175. else if ( NTMS_LIBRARYTYPE_STANDALONE == libraryInfo.Info.Library.LibraryType ) {
  3176. switch (mediaInfo.Info.PhysicalMedia.LocationType) {
  3177. case NTMS_DRIVE:
  3178. type = RmsElementDrive;
  3179. break;
  3180. default:
  3181. type = RmsElementUnknown;
  3182. break;
  3183. }
  3184. } else {
  3185. type = RmsElementShelf;
  3186. }
  3187. WsbAffirmHr(pCart->SetLocation(type,
  3188. mediaInfo.Info.PhysicalMedia.CurrentLibrary,
  3189. logicalMediaInfo.Info.LogicalMedia.MediaPool,
  3190. 0, 0, 0, 0, 0));
  3191. WsbAffirmHr(pCart->SetManagedBy((LONG)RmsMediaManagerNTMS));
  3192. WsbAssertHr(pCart->SetStatus(RmsStatusPrivate));
  3193. CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObj = pCart;
  3194. if (!mediaInfo.Enabled) {
  3195. WsbAffirmHr(pObj->Disable(RMS_E_CARTRIDGE_DISABLED));
  3196. }
  3197. CComQIPtr<IRmsStorageInfo, &IID_IRmsStorageInfo> pInfo = pCart;
  3198. WsbAffirmHr(pInfo->SetCapacity(partitionInfo.Info.Partition.Capacity.QuadPart));
  3199. WsbTrace(OLESTR("Cartridge id <name/desc>: %ls <%ls/%ls>\n"), WsbGuidAsString(cartId), (WCHAR *) name, (WCHAR *) desc);
  3200. WsbTrace(OLESTR("Cartridge <barCode/seqNo>: <%ls/%ls>\n"), (WCHAR *) barCode, (WCHAR *) seqNo );
  3201. WsbTrace(OLESTR("Cartridge Enabled: %ls\n"), WsbHrAsString(pObj->IsEnabled()));
  3202. WsbTrace(OLESTR("Cartridge type: %d\n"), translatedMediaType);
  3203. WsbTrace(OLESTR("Cartridge capacity: %I64d\n"), partitionInfo.Info.Partition.Capacity.QuadPart);
  3204. WsbTrace(OLESTR("Cartridge domain: %ls\n"), WsbGuidAsString(logicalMediaInfo.Info.LogicalMedia.MediaPool));
  3205. if (mediaInfo.Info.PhysicalMedia.MediaPool != logicalMediaInfo.Info.LogicalMedia.MediaPool) {
  3206. CWsbStringPtr idPhysical = mediaInfo.Info.PhysicalMedia.CurrentLibrary;
  3207. CWsbStringPtr idLogical = logicalMediaInfo.Info.LogicalMedia.MediaPool;
  3208. WsbTraceAlways(OLESTR("CRmsNTMS::FindCartridge - Media Pool Id mismatch %ls != %ls\n"), idPhysical, idLogical );
  3209. }
  3210. // Fill in the return argument.
  3211. *ppCartridge = pCart;
  3212. } WsbCatchAndDo( hr,
  3213. WsbTrace(OLESTR("CRmsNTMS::FindCartridge - %ls Not Found. hr = <%ls>\n"),WsbGuidAsString(cartId),WsbHrAsString(hr));
  3214. if (err1 != NO_ERROR ) {
  3215. // EnumerateNtmsObject
  3216. switch (HRESULT_CODE(hr)) {
  3217. case ERROR_OBJECT_NOT_FOUND:
  3218. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  3219. break;
  3220. case ERROR_INVALID_PARAMETER:
  3221. case ERROR_INVALID_HANDLE:
  3222. case ERROR_NOT_ENOUGH_MEMORY:
  3223. case ERROR_INSUFFICIENT_BUFFER:
  3224. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3225. OLESTR("EnumerateNtmsObject"), OLESTR(""),
  3226. WsbHrAsString(hr), NULL);
  3227. break;
  3228. default:
  3229. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3230. OLESTR("EnumerateNtmsObject"), OLESTR("Undocumented Error: "),
  3231. WsbHrAsString(hr), NULL);
  3232. break;
  3233. }
  3234. }
  3235. else if (err2 != NO_ERROR) {
  3236. // GetNtmsObjectInformation
  3237. switch (HRESULT_CODE(hr)) {
  3238. case ERROR_OBJECT_NOT_FOUND:
  3239. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  3240. break;
  3241. case ERROR_INVALID_HANDLE:
  3242. case ERROR_INVALID_PARAMETER:
  3243. case ERROR_NOT_ENOUGH_MEMORY:
  3244. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3245. OLESTR("GetNtmsObjectInformation"), OLESTR(""),
  3246. WsbHrAsString(hr), NULL);
  3247. break;
  3248. default:
  3249. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3250. OLESTR("GetNtmsObjectInformation"), OLESTR("Undocumented Error: "),
  3251. WsbHrAsString(hr), NULL);
  3252. break;
  3253. }
  3254. }
  3255. );
  3256. WsbTraceOut( OLESTR("CRmsNTMS::FindCartridge"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  3257. return hr;
  3258. }
  3259. STDMETHODIMP
  3260. CRmsNTMS::Suspend(void)
  3261. /*++
  3262. Implements:
  3263. CRmsNTMS::Suspend
  3264. --*/
  3265. {
  3266. HRESULT hr = S_OK;
  3267. WsbTraceIn( OLESTR("CRmsNTMS::Suspend"), OLESTR(""));
  3268. try {
  3269. WsbAffirmHr(changeState(RmsNtmsStateSuspending));
  3270. WsbAffirmHr(endSession());
  3271. WsbAffirmHr(changeState(RmsNtmsStateSuspended));
  3272. } WsbCatch(hr);
  3273. WsbTraceOut( OLESTR("CRmsNTMS::Suspend"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  3274. return hr;
  3275. }
  3276. STDMETHODIMP
  3277. CRmsNTMS::Resume(void)
  3278. /*++
  3279. Implements:
  3280. CRmsNTMS::Resume
  3281. --*/
  3282. {
  3283. HRESULT hr = S_OK;
  3284. WsbTraceIn( OLESTR("CRmsNTMS::Resume"), OLESTR(""));
  3285. try {
  3286. WsbAffirmHr(changeState(RmsNtmsStateResuming));
  3287. WsbAffirmHr(beginSession());
  3288. WsbAffirmHr(changeState(RmsNtmsStateReady));
  3289. } WsbCatch(hr);
  3290. WsbTraceOut( OLESTR("CRmsNTMS::Resume"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  3291. return hr;
  3292. }
  3293. HRESULT
  3294. CRmsNTMS::InitializeInAnotherThread(void)
  3295. {
  3296. HRESULT hr = S_OK;
  3297. WsbTraceIn(OLESTR("CRmsNTMS::InitializeInAnotherThread"), OLESTR(""));
  3298. try {
  3299. DWORD threadId;
  3300. HANDLE hThread;
  3301. CComQIPtr<IRmsServer, &IID_IRmsServer> pServer = g_pServer;
  3302. WsbAffirmHr( pServer->ChangeState( RmsServerStateInitializing ));
  3303. WsbAffirmHandle(hThread = CreateThread(NULL, 1024, CRmsNTMS::InitializationThread, this, 0, &threadId));
  3304. CloseHandle(hThread);
  3305. } WsbCatch(hr);
  3306. WsbTraceOut(OLESTR("CRmsNTMS::InitializeInAnotherThread"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  3307. return hr;
  3308. }
  3309. DWORD WINAPI
  3310. CRmsNTMS::InitializationThread(
  3311. IN LPVOID pv)
  3312. {
  3313. HRESULT hr = S_OK;
  3314. WsbTraceIn(OLESTR("CRmsNTMS::InitializationThread"), OLESTR(""));
  3315. try {
  3316. WsbAssertPointer(pv);
  3317. CRmsNTMS *pNTMS = (CRmsNTMS*)pv;
  3318. WsbAffirmHr(pNTMS->Initialize());
  3319. CComQIPtr<IRmsServer, &IID_IRmsServer> pServer = g_pServer;
  3320. WsbAffirmHr( pServer->ChangeState( RmsServerStateReady ));
  3321. } WsbCatch(hr);
  3322. WsbTraceOut(OLESTR("CRmsNTMS::InitializationThread"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  3323. return hr;
  3324. }
  3325. HRESULT
  3326. CRmsNTMS::isReady(void)
  3327. {
  3328. HRESULT hr = S_OK;
  3329. try {
  3330. BOOL isEnabled;
  3331. HRESULT status;
  3332. RmsServerState state;
  3333. CComQIPtr<IRmsComObject, &IID_IRmsComObject> pObject = this;
  3334. WsbAssertPointer( pObject );
  3335. WsbAffirmHr( isEnabled = pObject->IsEnabled());
  3336. WsbAffirmHr( pObject->GetState( (LONG *)&state ));
  3337. WsbAffirmHr( pObject->GetStatusCode( &status ));
  3338. if ( S_OK == isEnabled ) {
  3339. if ( RmsServerStateReady == state ) {
  3340. hr = S_OK;
  3341. }
  3342. else {
  3343. if ( S_OK == status ) {
  3344. WsbThrow(E_UNEXPECTED);
  3345. }
  3346. else {
  3347. WsbThrow(status);
  3348. }
  3349. }
  3350. }
  3351. else {
  3352. if ( S_OK == status ) {
  3353. WsbThrow(E_UNEXPECTED);
  3354. }
  3355. else {
  3356. WsbThrow(status);
  3357. }
  3358. }
  3359. } WsbCatch(hr);
  3360. return hr;
  3361. }
  3362. HRESULT
  3363. CRmsNTMS::setPoolDACL (
  3364. IN OUT NTMS_GUID *pPoolId,
  3365. IN DWORD subAuthority,
  3366. IN DWORD action,
  3367. IN DWORD mask)
  3368. {
  3369. HRESULT hr = S_OK;
  3370. WsbTraceIn(OLESTR("CRmsNTMS::SetPoolDACL"), OLESTR("%ls <%d> <%d> <%d>"), WsbGuidAsString(*pPoolId), subAuthority, action, mask);
  3371. PSID psidAccount = NULL;
  3372. PSECURITY_DESCRIPTOR psdRePoolSd = NULL;
  3373. try {
  3374. SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
  3375. DWORD errCode = NO_ERROR, sizeTry = 5, sizeReturned = 0;
  3376. PACL paclDis = NULL;
  3377. ACCESS_ALLOWED_ACE *pAce = NULL;
  3378. BOOL daclPresent = FALSE, daclDefaulted = FALSE;
  3379. HANDLE hSession = m_SessionHandle;
  3380. WsbAffirmStatus(AllocateAndInitializeSid(&ntauth, 2, SECURITY_BUILTIN_DOMAIN_RID, subAuthority, 0, 0, 0, 0, 0, 0, &psidAccount));
  3381. //Get the security descriptor for the pool
  3382. for (;;) {
  3383. if (psdRePoolSd != NULL) {
  3384. free(psdRePoolSd);
  3385. }
  3386. psdRePoolSd = (PSECURITY_DESCRIPTOR)malloc(sizeTry);
  3387. WsbAffirm(NULL != psdRePoolSd, E_OUTOFMEMORY);
  3388. errCode = GetNtmsObjectSecurity(hSession, pPoolId, NTMS_MEDIA_POOL, DACL_SECURITY_INFORMATION, psdRePoolSd, sizeTry, &sizeReturned);
  3389. if (errCode == ERROR_SUCCESS) {
  3390. break;
  3391. }
  3392. else if (errCode == ERROR_INSUFFICIENT_BUFFER) {
  3393. sizeTry = sizeReturned;
  3394. continue;
  3395. }
  3396. else {
  3397. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  3398. OLESTR("GetNtmsObjectSecurity"),
  3399. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  3400. NULL );
  3401. WsbAffirmNoError(errCode);
  3402. }
  3403. }
  3404. // Get a pointer to the DACL
  3405. WsbAffirmStatus(GetSecurityDescriptorDacl(psdRePoolSd, &daclPresent, &paclDis, &daclDefaulted));
  3406. // Go through the DACL and change the mask of the ACE that matches the SID
  3407. for (DWORD i = 0;i < paclDis->AceCount; ++i) {
  3408. WsbAffirmStatus(GetAce(paclDis, i, (LPVOID*) &pAce));
  3409. if (EqualSid(psidAccount, &(pAce->SidStart))) {
  3410. if (action == ADD_ACE_MASK_BITS) {
  3411. pAce->Mask |= mask;
  3412. } else {
  3413. pAce->Mask &= ~mask;
  3414. }
  3415. }
  3416. }
  3417. // Set the pool security descriptor
  3418. errCode = SetNtmsObjectSecurity(hSession, pPoolId, NTMS_MEDIA_POOL, DACL_SECURITY_INFORMATION, psdRePoolSd);
  3419. WsbAffirmNoError(errCode);
  3420. } WsbCatch(hr);
  3421. if (psdRePoolSd) {
  3422. free(psdRePoolSd);
  3423. }
  3424. if (psidAccount) {
  3425. FreeSid(psidAccount);
  3426. }
  3427. WsbTraceOut(OLESTR("CRmsNTMS::SetPoolDACL"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  3428. return hr;
  3429. }
  3430. HRESULT
  3431. CRmsNTMS::IsMediaCopySupported (
  3432. IN REFGUID mediaPoolId)
  3433. {
  3434. HRESULT hr = S_OK;
  3435. WsbTraceIn(OLESTR("CRmsNTMS::IsMediaCopySupported"), OLESTR("%ls"), WsbGuidAsString(mediaPoolId));
  3436. try {
  3437. // If we can find two drives that support this media type then
  3438. // the media copy operation is supported.
  3439. // For each drive known to NTMS we need to find what media types
  3440. // it supports. NTMS doesn't keep media type information for the
  3441. // drive, but assumes homogeneous drives in a library (per HighGound) -
  3442. // so detecting this is a bit convoluted.
  3443. // we'll search through each library and find the media types
  3444. // supported, and count the number of drives in the library.
  3445. if ( INVALID_HANDLE_VALUE == m_SessionHandle ) {
  3446. WsbAffirmHr(beginSession());
  3447. }
  3448. HANDLE hSession = m_SessionHandle;
  3449. NTMS_OBJECTINFORMATION mediaPoolInfo;
  3450. NTMS_GUID poolId = mediaPoolId;
  3451. memset(&mediaPoolInfo, 0, sizeof(NTMS_OBJECTINFORMATION));
  3452. mediaPoolInfo.dwType = NTMS_MEDIA_POOL;
  3453. mediaPoolInfo.dwSize = sizeof(NTMS_OBJECTINFORMATION);
  3454. // NTMS - Get Media Pool Information
  3455. WsbTraceAlways(OLESTR("GetNtmsObjectInformation()\n"));
  3456. DWORD errCode = GetNtmsObjectInformation( hSession, &poolId, &mediaPoolInfo );
  3457. if ( errCode != NO_ERROR ) {
  3458. WsbLogEvent( RMS_MESSAGE_NTMS_FAILURE, 0, NULL,
  3459. OLESTR("GetNtmsObjectInformation"),
  3460. WsbHrAsString(HRESULT_FROM_WIN32(errCode)),
  3461. NULL );
  3462. WsbThrow( E_UNEXPECTED );
  3463. }
  3464. NTMS_GUID mediaTypeId = mediaPoolInfo.Info.MediaPool.MediaType;
  3465. NTMS_OBJECTINFORMATION libInfo;
  3466. HANDLE hFindLib = NULL;
  3467. int driveCount = 0;
  3468. hr = findFirstNtmsObject( NTMS_LIBRARY,
  3469. GUID_NULL, NULL, GUID_NULL, &hFindLib, &libInfo);
  3470. while( S_OK == hr ) {
  3471. HANDLE hFindLib2 = NULL;
  3472. // now see if the library in which the drive is contained supported
  3473. // the specified media type
  3474. if ( libInfo.Info.Library.dwNumberOfDrives > 0 ) {
  3475. hr = findFirstNtmsObject( NTMS_MEDIA_TYPE,
  3476. libInfo.ObjectGuid, NULL, mediaTypeId, &hFindLib2, NULL);
  3477. WsbTrace(OLESTR("Searching <%ls> for media type and drives; hr = %ls (state = %d, enabled = %ls, drives = %d)\n"),
  3478. libInfo.szName, WsbHrAsString(hr),
  3479. libInfo.dwOperationalState,
  3480. WsbBoolAsString(libInfo.Enabled),
  3481. libInfo.Info.Library.dwNumberOfDrives);
  3482. if ((S_OK == hr) &&
  3483. ((NTMS_READY == libInfo.dwOperationalState) ||
  3484. (NTMS_INITIALIZING == libInfo.dwOperationalState)) &&
  3485. (libInfo.Enabled)) {
  3486. driveCount += libInfo.Info.Library.dwNumberOfDrives;
  3487. }
  3488. findCloseNtmsObject( hFindLib2 );
  3489. }
  3490. hr = findNextNtmsObject( hFindLib, &libInfo );
  3491. }
  3492. findCloseNtmsObject( hFindLib );
  3493. hr = (driveCount > 1) ? S_OK : S_FALSE;
  3494. } WsbCatch(hr);
  3495. WsbTraceOut(OLESTR("CRmsNTMS::IsMediaCopySupported"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  3496. return hr;
  3497. }
  3498. STDMETHODIMP
  3499. CRmsNTMS::UpdateDrive(
  3500. IN IRmsDrive *pDrive)
  3501. /*++
  3502. Implements:
  3503. IRmsNTMS::UpdateDrive
  3504. --*/
  3505. {
  3506. HRESULT hr = S_OK;
  3507. CComPtr<IRmsComObject> pObject;
  3508. GUID driveId;
  3509. DWORD err1 = NO_ERROR;
  3510. WsbTraceIn(OLESTR("CRmsNTMS::UpdateDrive"), OLESTR(""));
  3511. try {
  3512. // get drive information
  3513. WsbAffirmHr(pDrive->QueryInterface(IID_IRmsComObject, (void **)&pObject));
  3514. WsbAffirmHr(pObject->GetObjectId(&driveId));
  3515. NTMS_OBJECTINFORMATION objectInfo;
  3516. objectInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  3517. objectInfo.dwType = NTMS_DRIVE;
  3518. WsbAssert(driveId != GUID_NULL, E_INVALIDARG);
  3519. err1 = GetNtmsObjectInformation( m_SessionHandle, &driveId, &objectInfo );
  3520. WsbAffirmNoError (err1);
  3521. // Note: Currently, the method updates only the enable/disable state of the drive
  3522. // If required, the method may update more fields
  3523. if (objectInfo.Enabled) {
  3524. WsbAffirmHr(pObject->Enable());
  3525. } else {
  3526. WsbAffirmHr(pObject->Disable(S_OK));
  3527. }
  3528. } WsbCatchAndDo(hr,
  3529. // Process the error of the get-info request
  3530. if (err1 != NO_ERROR ) {
  3531. if (err1 == ERROR_OBJECT_NOT_FOUND) {
  3532. hr = RMS_E_NTMS_OBJECT_NOT_FOUND;
  3533. }
  3534. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3535. OLESTR("GetNtmsObjectInformation (Drive)"), OLESTR(""),
  3536. WsbHrAsString(hr), NULL);
  3537. }
  3538. );
  3539. WsbTraceOut(OLESTR("CRmsNTMS::UpdateDrive"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  3540. return(hr);
  3541. }
  3542. HRESULT
  3543. CRmsNTMS::GetNofAvailableDrives(
  3544. OUT DWORD* pdwNofDrives
  3545. )
  3546. /*++
  3547. Implements:
  3548. IRmsNTMS::GetNofAvailableDrives().
  3549. --*/
  3550. {
  3551. HRESULT hr = S_OK;
  3552. WsbTraceIn(OLESTR("CRmsNTMS::GetNofAvailableDrives"), OLESTR(""));
  3553. *pdwNofDrives = 0;
  3554. // Enumerate over all libraries that HSM uses
  3555. // (Outside the try block, since we want to continue if a failure occur on a specific library)
  3556. WsbTrace(OLESTR("CRmsNTMS::GetNofAvailableDrives: Total number of libraries is %lu\n"), m_dwNofLibs);
  3557. for (int j=0; j<(int)m_dwNofLibs; j++) {
  3558. LPNTMS_GUID pObjects = NULL;
  3559. DWORD errCode = NO_ERROR;
  3560. // get library id
  3561. GUID libId = m_pLibGuids[j];
  3562. try {
  3563. // Enumerate on all drives in the library
  3564. DWORD dwNofObjects = 16; // Initial size of object id array to allocate
  3565. int nRetry = 0;
  3566. // Allocate according to
  3567. pObjects = (LPNTMS_GUID)WsbAlloc( dwNofObjects*sizeof(NTMS_GUID) );
  3568. WsbAffirmPointer( pObjects );
  3569. // Enumerate all drives
  3570. do {
  3571. errCode = EnumerateNtmsObject(m_SessionHandle, &libId, pObjects, &dwNofObjects, NTMS_DRIVE, 0);
  3572. WsbTraceAlways(OLESTR("CRmsNTMS::GetNofAvailableDrives: Total number of drives is %lu\n"),
  3573. dwNofObjects);
  3574. nRetry++;
  3575. if ( (ERROR_OBJECT_NOT_FOUND == errCode) || (0 == dwNofObjects) ) { // Don't count on NTMS returning the correct errCode
  3576. // Not considered as an NTMS error, prevent logging by setting to NO_ERROR
  3577. errCode = NO_ERROR;
  3578. WsbThrow( RMS_E_NTMS_OBJECT_NOT_FOUND );
  3579. } else if (ERROR_INSUFFICIENT_BUFFER == errCode) {
  3580. // Don't retry more than 3 times
  3581. if (3 <= nRetry) {
  3582. WsbThrow(HRESULT_FROM_WIN32(errCode));
  3583. }
  3584. // Allocate a new buffer, and retry.
  3585. WsbTrace(OLESTR("CRmsNTMS::GetNofAvailableDrives: Reallocating buffer\n"));
  3586. LPVOID pTemp = WsbRealloc( pObjects, dwNofObjects*sizeof(NTMS_GUID) );
  3587. if (!pTemp) {
  3588. WsbThrow(E_OUTOFMEMORY);
  3589. }
  3590. pObjects = (LPNTMS_GUID)pTemp;
  3591. } else {
  3592. // Other unexpected error
  3593. WsbAffirmNoError(errCode);
  3594. }
  3595. } while (ERROR_INSUFFICIENT_BUFFER == errCode);
  3596. // go over all drives, get information and check availablity
  3597. for (int i = 0; i < (int)dwNofObjects; i++) {
  3598. GUID driveId = pObjects[i];
  3599. try {
  3600. NTMS_OBJECTINFORMATION objectInfo;
  3601. memset( &objectInfo, 0, sizeof(NTMS_OBJECTINFORMATION) );
  3602. objectInfo.dwSize = sizeof(NTMS_OBJECTINFORMATION);
  3603. objectInfo.dwType = NTMS_DRIVE;
  3604. WsbAssert(driveId != GUID_NULL, E_INVALIDARG);
  3605. errCode = GetNtmsObjectInformation(m_SessionHandle, &driveId, &objectInfo );
  3606. WsbAffirmNoError (errCode);
  3607. WsbTrace(OLESTR("CRmsNTMS::GetNofAvailableDrives: drive <%ls> enable/disable = %ls\n"),
  3608. WsbGuidAsString(driveId), WsbBoolAsString(objectInfo.Enabled));
  3609. if (objectInfo.Enabled) {
  3610. (*pdwNofDrives)++;
  3611. }
  3612. } WsbCatchAndDo(hr,
  3613. // Log error and go on to the next drive
  3614. if (errCode != NO_ERROR ) {
  3615. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3616. OLESTR("GetNtmsObjectInformation (Drive)"), OLESTR(""),
  3617. WsbHrAsString(hr), NULL);
  3618. }
  3619. WsbTraceAlways(OLESTR("CRmsNTMS::GetNofAvailableDrives: Failed to get info for drive <%ls> hr = <%ls>\n"),
  3620. WsbGuidAsString(driveId), WsbHrAsString(hr));
  3621. hr = S_OK;
  3622. );
  3623. }
  3624. } WsbCatchAndDo(hr,
  3625. // Log error and go on to the next library
  3626. if (errCode != NO_ERROR ) {
  3627. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3628. OLESTR("EnumerateNtmsObject (Drive)"), OLESTR(""),
  3629. WsbHrAsString(hr), NULL);
  3630. }
  3631. WsbTraceAlways(OLESTR("CRmsNTMS::GetNofAvailableDrives: Failed to enumerate drives in library <%ls> hr = <%ls>\n"),
  3632. WsbGuidAsString(libId), WsbHrAsString(hr));
  3633. hr = S_OK;
  3634. );
  3635. if (pObjects) {
  3636. WsbFree(pObjects);
  3637. }
  3638. } // of for
  3639. WsbTraceOut(OLESTR("CRmsNTMS::GetNofAvailableDrives"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  3640. return(hr);
  3641. }
  3642. HRESULT
  3643. CRmsNTMS::CheckSecondSide(
  3644. IN REFGUID firstSideId,
  3645. OUT BOOL *pbValid,
  3646. OUT GUID *pSecondSideId
  3647. )
  3648. /*++
  3649. Implements:
  3650. IRmsNTMS::CheckSecondSide().
  3651. --*/
  3652. {
  3653. HRESULT hr = S_OK;
  3654. DWORD err1 = NO_ERROR;
  3655. DWORD err2 = NO_ERROR;
  3656. WsbTraceIn(OLESTR("CRmsNTMS::CheckSecondSide"), OLESTR(""));
  3657. *pbValid = FALSE;
  3658. *pSecondSideId = GUID_NULL;
  3659. try {
  3660. WsbAssert(firstSideId != GUID_NULL, E_INVALIDARG);
  3661. WsbAssertPointer(pbValid);
  3662. WsbAssertPointer(pSecondSideId);
  3663. NTMS_OBJECTINFORMATION partitionInfo;
  3664. memset( &partitionInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  3665. NTMS_OBJECTINFORMATION mediaInfo;
  3666. memset( &mediaInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  3667. HANDLE hSession = m_SessionHandle;
  3668. NTMS_GUID mediaId = firstSideId;
  3669. NTMS_GUID firstSidePartitionId;
  3670. NTMS_GUID side[2];
  3671. DWORD sideNo = 2;
  3672. // NTMS - get Partition from LMID
  3673. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  3674. err1 = EnumerateNtmsObject(hSession, &mediaId, side, &sideNo, NTMS_PARTITION, 0);
  3675. WsbAffirmNoError(err1);
  3676. firstSidePartitionId = side[0];
  3677. // NTMS - get partition information (using size 0 - LMID relates 1:1 to Partition
  3678. partitionInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  3679. partitionInfo.dwType = NTMS_PARTITION;
  3680. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
  3681. err2 = GetNtmsObjectInformation(hSession, &firstSidePartitionId, &partitionInfo);
  3682. WsbAffirmNoError(err2);
  3683. // NTMS - get physical media information
  3684. NTMS_GUID physicalMediaId = partitionInfo.Info.Partition.PhysicalMedia;
  3685. mediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  3686. mediaInfo.dwType = NTMS_PHYSICAL_MEDIA;
  3687. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
  3688. err2 = GetNtmsObjectInformation(hSession, &physicalMediaId, &mediaInfo);
  3689. WsbAffirmNoError(err2);
  3690. // Check whether there are more than one side
  3691. if (mediaInfo.Info.PhysicalMedia.dwNumberOfPartitions > 1) {
  3692. // Enumerate physical meida - expect 2 sides here.
  3693. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  3694. sideNo = 2;
  3695. err1 = EnumerateNtmsObject(hSession, &physicalMediaId, side, &sideNo, NTMS_PARTITION, 0);
  3696. WsbAffirmNoError(err1);
  3697. WsbAffirm(sideNo > 1, RMS_E_NOT_FOUND);
  3698. // Look for a side whos partition id is different from first side
  3699. for (DWORD i=0; i<sideNo; i++) {
  3700. if (firstSidePartitionId != side[i]) {
  3701. *pbValid = TRUE; // Valid second side found
  3702. // Get its LMID
  3703. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
  3704. err2 = GetNtmsObjectInformation(hSession, &side[i], &partitionInfo);
  3705. WsbAffirmNoError(err2);
  3706. *pSecondSideId = partitionInfo.Info.Partition.LogicalMedia;
  3707. }
  3708. }
  3709. } // of if two sides
  3710. } WsbCatchAndDo( hr,
  3711. WsbTrace(OLESTR("CRmsNTMS::CheckSecondSide - of %ls failed: hr = <%ls>\n"),WsbGuidAsString(firstSideId),WsbHrAsString(hr));
  3712. if (err1 != NO_ERROR ) {
  3713. // EnumerateNtmsObject
  3714. switch (HRESULT_CODE(hr)) {
  3715. case ERROR_OBJECT_NOT_FOUND:
  3716. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  3717. break;
  3718. case ERROR_INVALID_PARAMETER:
  3719. case ERROR_INVALID_HANDLE:
  3720. case ERROR_NOT_ENOUGH_MEMORY:
  3721. case ERROR_INSUFFICIENT_BUFFER:
  3722. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3723. OLESTR("EnumerateNtmsObject"), OLESTR(""),
  3724. WsbHrAsString(hr), NULL);
  3725. break;
  3726. default:
  3727. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3728. OLESTR("EnumerateNtmsObject"), OLESTR("Unexpected Error: "),
  3729. WsbHrAsString(hr), NULL);
  3730. break;
  3731. }
  3732. }
  3733. else if (err2 != NO_ERROR) {
  3734. // GetNtmsObjectInformation
  3735. switch (HRESULT_CODE(hr)) {
  3736. case ERROR_OBJECT_NOT_FOUND:
  3737. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  3738. break;
  3739. case ERROR_INVALID_HANDLE:
  3740. case ERROR_INVALID_PARAMETER:
  3741. case ERROR_NOT_ENOUGH_MEMORY:
  3742. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3743. OLESTR("GetNtmsObjectInformation"), OLESTR(""),
  3744. WsbHrAsString(hr), NULL);
  3745. break;
  3746. default:
  3747. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3748. OLESTR("GetNtmsObjectInformation"), OLESTR("Unexpected Error: "),
  3749. WsbHrAsString(hr), NULL);
  3750. break;
  3751. }
  3752. }
  3753. );
  3754. WsbTraceOut(OLESTR("CRmsNTMS::CheckSecondSide"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  3755. return(hr);
  3756. }
  3757. HRESULT
  3758. CRmsNTMS::EnsureAllSidesNotAllocated(
  3759. IN REFGUID mediaId
  3760. )
  3761. {
  3762. HRESULT hr = S_OK;
  3763. DWORD err1 = NO_ERROR;
  3764. DWORD err2 = NO_ERROR;
  3765. WsbTraceIn(OLESTR("CRmsNTMS::EnsureAllSidesNotAllocated"), OLESTR(""));
  3766. try {
  3767. WsbAssert(mediaId != GUID_NULL, E_INVALIDARG);
  3768. NTMS_OBJECTINFORMATION partitionInfo;
  3769. memset( &partitionInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  3770. NTMS_OBJECTINFORMATION mediaInfo;
  3771. memset( &mediaInfo, 0, sizeof( NTMS_OBJECTINFORMATION ) );
  3772. HANDLE hSession = m_SessionHandle;
  3773. NTMS_GUID physicalMediaId = mediaId;
  3774. mediaInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  3775. mediaInfo.dwType = NTMS_PHYSICAL_MEDIA;
  3776. partitionInfo.dwSize = sizeof( NTMS_OBJECTINFORMATION );
  3777. partitionInfo.dwType = NTMS_PARTITION;
  3778. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PHYSICAL_MEDIA)\n"));
  3779. err2 = GetNtmsObjectInformation(hSession, &physicalMediaId, &mediaInfo);
  3780. WsbAffirmNoError(err2);
  3781. // Check whether there are more than one side
  3782. if (mediaInfo.Info.PhysicalMedia.dwNumberOfPartitions > 1) {
  3783. // Enumerate physical meida - expect 2 sides here.
  3784. NTMS_GUID side[2];
  3785. DWORD sideNo = 2;
  3786. WsbTraceAlways(OLESTR("EnumerateNtmsObject()\n"));
  3787. err1 = EnumerateNtmsObject(hSession, &physicalMediaId, side, &sideNo, NTMS_PARTITION, 0);
  3788. WsbAffirmNoError(err1);
  3789. // Look for a side which is allocated
  3790. for (DWORD i=0; i<sideNo; i++) {
  3791. WsbTraceAlways(OLESTR("GetNtmsObjectInformation(NTMS_PARTITION)\n"));
  3792. err2 = GetNtmsObjectInformation(hSession, &side[i], &partitionInfo);
  3793. WsbAffirmNoError(err2);
  3794. if (GUID_NULL != partitionInfo.Info.Partition.LogicalMedia) {
  3795. hr = S_FALSE;
  3796. break;
  3797. }
  3798. }
  3799. } // of if two sides
  3800. } WsbCatchAndDo( hr,
  3801. WsbTrace(OLESTR("CRmsNTMS::EnsureAllSidesNotAllocated - of %ls failed: hr = <%ls>\n"),WsbGuidAsString(mediaId),WsbHrAsString(hr));
  3802. if (err1 != NO_ERROR ) {
  3803. // EnumerateNtmsObject
  3804. switch (HRESULT_CODE(hr)) {
  3805. case ERROR_OBJECT_NOT_FOUND:
  3806. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  3807. break;
  3808. case ERROR_INVALID_PARAMETER:
  3809. case ERROR_INVALID_HANDLE:
  3810. case ERROR_NOT_ENOUGH_MEMORY:
  3811. case ERROR_INSUFFICIENT_BUFFER:
  3812. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3813. OLESTR("EnumerateNtmsObject"), OLESTR(""),
  3814. WsbHrAsString(hr), NULL);
  3815. break;
  3816. default:
  3817. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3818. OLESTR("EnumerateNtmsObject"), OLESTR("Unexpected Error: "),
  3819. WsbHrAsString(hr), NULL);
  3820. break;
  3821. }
  3822. }
  3823. else if (err2 != NO_ERROR) {
  3824. // GetNtmsObjectInformation
  3825. switch (HRESULT_CODE(hr)) {
  3826. case ERROR_OBJECT_NOT_FOUND:
  3827. hr = RMS_E_CARTRIDGE_NOT_FOUND;
  3828. break;
  3829. case ERROR_INVALID_HANDLE:
  3830. case ERROR_INVALID_PARAMETER:
  3831. case ERROR_NOT_ENOUGH_MEMORY:
  3832. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3833. OLESTR("GetNtmsObjectInformation"), OLESTR(""),
  3834. WsbHrAsString(hr), NULL);
  3835. break;
  3836. default:
  3837. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3838. OLESTR("GetNtmsObjectInformation"), OLESTR("Unexpected Error: "),
  3839. WsbHrAsString(hr), NULL);
  3840. break;
  3841. }
  3842. }
  3843. );
  3844. WsbTraceOut(OLESTR("CRmsNTMS::EnsureAllSidesNotAllocated"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  3845. return(hr);
  3846. }
  3847. STDMETHODIMP
  3848. CRmsNTMS::DismountAll(
  3849. IN REFGUID fromMediaSet,
  3850. IN DWORD dwOptions)
  3851. /*++
  3852. Implements:
  3853. IRmsNTMS::DismountAll
  3854. --*/
  3855. {
  3856. HRESULT hr = S_OK;
  3857. WsbTraceIn( OLESTR("CRmsNTMS::DismountAll"), OLESTR("") );
  3858. try {
  3859. WsbAssert(GUID_NULL != fromMediaSet, E_INVALIDARG);
  3860. HANDLE hFindMedia = NULL;
  3861. DWORD err1 = NO_ERROR;
  3862. HANDLE hSession = m_SessionHandle;
  3863. NTMS_OBJECTINFORMATION physicalMediaInfo;
  3864. NTMS_GUID setId = fromMediaSet;
  3865. NTMS_GUID partId = GUID_NULL;
  3866. // Dismount all mounted medias from the given pool
  3867. hr = findFirstNtmsObject(NTMS_PHYSICAL_MEDIA, setId, NULL, GUID_NULL, &hFindMedia, &physicalMediaInfo);
  3868. while(S_OK == hr) {
  3869. switch (physicalMediaInfo.Info.PhysicalMedia.MediaState) {
  3870. case NTMS_MEDIASTATE_LOADED:
  3871. case NTMS_MEDIASTATE_MOUNTED:
  3872. // Dismount the media
  3873. try {
  3874. partId = physicalMediaInfo.Info.PhysicalMedia.MountedPartition;
  3875. WsbAffirm(GUID_NULL != partId, E_UNEXPECTED);
  3876. DWORD dwNtmsOptions = 0;
  3877. WsbTraceAlways(OLESTR("DismountNtmsMedia()\n"));
  3878. if (! ( dwOptions & RMS_DISMOUNT_IMMEDIATE )) {
  3879. dwNtmsOptions |= NTMS_DISMOUNT_DEFERRED;
  3880. }
  3881. err1 = DismountNtmsMedia(hSession, &partId, 1, dwNtmsOptions);
  3882. WsbAffirmNoError(err1);
  3883. } WsbCatchAndDo(hr,
  3884. if (err1 != NO_ERROR) {
  3885. WsbLogEvent(RMS_MESSAGE_NTMS_FAULT, 0, NULL,
  3886. OLESTR("DismountNtmsMedia"), OLESTR(""),
  3887. WsbHrAsString(hr), NULL);
  3888. }
  3889. );
  3890. break;
  3891. default:
  3892. // Media is not mounted - skip it
  3893. break;
  3894. }
  3895. hr = findNextNtmsObject(hFindMedia, &physicalMediaInfo);
  3896. }
  3897. findCloseNtmsObject(hFindMedia);
  3898. hr = S_OK;
  3899. } WsbCatch(hr);
  3900. WsbTraceOut( OLESTR("CRmsNTMS::DismountAll"), OLESTR("hr = <%ls>"), WsbHrAsString(hr) );
  3901. return hr;
  3902. }