Leaked source code of windows server 2003
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.

1915 lines
53 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved.
  3. Module Name:
  4. RsAdUtil.cpp
  5. Abstract:
  6. Utility functions for GUI - for us in HSMADMIN files only
  7. Author:
  8. Art Bragg [abragg] 04-Mar-1997
  9. Revision History:
  10. Chris Timmes [ctimmes] 21-Nov-1997
  11. - modified RsCreateAndRunFsaJob(), RsCreateAndRunMediaCopyJob(),and
  12. RsCreateAndRunMediaRecreateJob() to use the new Engine method CreateTask(), which
  13. creates a task in the NT Task Scheduler. Change required due to changing Sakkara
  14. to run under LocalSystem account.
  15. --*/
  16. #include "stdafx.h"
  17. HRESULT
  18. RsGetStatusString (
  19. DWORD serviceStatus,
  20. HRESULT hrSetup,
  21. CString& sStatus
  22. )
  23. {
  24. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  25. switch( serviceStatus ) {
  26. case SERVICE_STOPPED:
  27. sStatus.LoadString(IDS_SERVICE_STATUS_STOPPED);
  28. break;
  29. case SERVICE_START_PENDING:
  30. sStatus.LoadString(IDS_SERVICE_STATUS_START_PENDING);
  31. break;
  32. case SERVICE_STOP_PENDING:
  33. sStatus.LoadString(IDS_SERVICE_STATUS_STOP_PENDING);
  34. break;
  35. case SERVICE_RUNNING:
  36. //
  37. // See if we are setup yet
  38. //
  39. if( S_FALSE == hrSetup ) {
  40. sStatus.LoadString(IDS_SERVICE_STATUS_NOT_SETUP);
  41. } else {
  42. sStatus.LoadString(IDS_SERVICE_STATUS_RUNNING);
  43. }
  44. break;
  45. case SERVICE_CONTINUE_PENDING:
  46. sStatus.LoadString(IDS_SERVICE_STATUS_CONTINUE_PENDING);
  47. break;
  48. case SERVICE_PAUSE_PENDING:
  49. sStatus.LoadString(IDS_SERVICE_STATUS_PAUSE_PENDING);
  50. break;
  51. case SERVICE_PAUSED:
  52. sStatus.LoadString(IDS_SERVICE_STATUS_PAUSED);
  53. break;
  54. }
  55. return S_OK;
  56. }
  57. WCHAR *
  58. RsNotifyEventAsString (
  59. IN MMC_NOTIFY_TYPE event
  60. )
  61. /*++
  62. Routine Description:
  63. For debug purposes, converts the event type into a UNICODE string.
  64. Arguments:
  65. event - The event type
  66. Return Value:
  67. String representing notify code - not I18N'd.
  68. --*/
  69. {
  70. #define CASE_EVENT(x) case x: return TEXT(#x); break;
  71. switch( event )
  72. {
  73. CASE_EVENT( MMCN_ACTIVATE )
  74. CASE_EVENT( MMCN_ADD_IMAGES )
  75. CASE_EVENT( MMCN_BTN_CLICK )
  76. CASE_EVENT( MMCN_CLICK )
  77. CASE_EVENT( MMCN_COLUMN_CLICK )
  78. CASE_EVENT( MMCN_CONTEXTMENU )
  79. CASE_EVENT( MMCN_CUTORMOVE )
  80. CASE_EVENT( MMCN_DBLCLICK )
  81. CASE_EVENT( MMCN_DELETE )
  82. CASE_EVENT( MMCN_DESELECT_ALL )
  83. CASE_EVENT( MMCN_EXPAND )
  84. CASE_EVENT( MMCN_HELP )
  85. CASE_EVENT( MMCN_MENU_BTNCLICK )
  86. CASE_EVENT( MMCN_MINIMIZED )
  87. CASE_EVENT( MMCN_PASTE )
  88. CASE_EVENT( MMCN_PROPERTY_CHANGE )
  89. CASE_EVENT( MMCN_QUERY_PASTE )
  90. CASE_EVENT( MMCN_REFRESH )
  91. CASE_EVENT( MMCN_REMOVE_CHILDREN )
  92. CASE_EVENT( MMCN_RENAME )
  93. CASE_EVENT( MMCN_SELECT )
  94. CASE_EVENT( MMCN_SHOW )
  95. CASE_EVENT( MMCN_VIEW_CHANGE )
  96. CASE_EVENT( MMCN_SNAPINHELP )
  97. CASE_EVENT( MMCN_CONTEXTHELP )
  98. CASE_EVENT( MMCN_INITOCX )
  99. CASE_EVENT( MMCN_FILTER_CHANGE )
  100. CASE_EVENT( MMCN_FILTERBTN_CLICK )
  101. CASE_EVENT( MMCN_RESTORE_VIEW )
  102. CASE_EVENT( MMCN_PRINT )
  103. CASE_EVENT( MMCN_PRELOAD )
  104. CASE_EVENT( MMCN_LISTPAD )
  105. CASE_EVENT( MMCN_EXPANDSYNC )
  106. default:
  107. static WCHAR buf[32];
  108. swprintf( buf, L"Unknown Event[0x%p]", event );
  109. return( buf );
  110. }
  111. }
  112. WCHAR *
  113. RsClipFormatAsString (
  114. IN CLIPFORMAT cf
  115. )
  116. /*++
  117. Routine Description:
  118. For debug purposes, converts the event type into a UNICODE string.
  119. Arguments:
  120. event - The event type
  121. Return Value:
  122. String representing notify code - not I18N'd.
  123. --*/
  124. {
  125. static WCHAR buf[128];
  126. GetClipboardFormatName( cf, buf, 128 );
  127. return( buf );
  128. }
  129. HRESULT
  130. RsIsRemoteStorageSetup(
  131. void
  132. )
  133. /*++
  134. Routine Description:
  135. Reports back if Remote Storage has been set up on this machine.
  136. Arguments:
  137. none.
  138. Return Value:
  139. S_OK if setup
  140. S_FALSE if not
  141. --*/
  142. {
  143. WsbTraceIn( L"RsIsRemoteStorageSetup", L"" );
  144. HRESULT hr = S_FALSE;
  145. try {
  146. //
  147. // First, see if service is registered
  148. //
  149. CWsbStringPtr hsmName;
  150. WsbTrace( L"Checking if service is registered\n" );
  151. WsbAffirmHr( WsbGetServiceInfo( APPID_RemoteStorageEngine, &hsmName, 0 ) );
  152. //
  153. // Second, contact the engine. this will start the service if it
  154. // is not already started.
  155. //
  156. CWsbStringPtr computerName;
  157. WsbAffirmHr( WsbGetComputerName( computerName ) );
  158. CComPtr<IHsmServer> pHsm;
  159. WsbTrace( L"Contacting Engine\n" );
  160. WsbAffirmHr( HsmConnectFromName( HSMCONN_TYPE_HSM, computerName, IID_IHsmServer, (void**)&pHsm ) );
  161. //
  162. // Third, see if it has a storage pool ID
  163. //
  164. hr = RsIsRemoteStorageSetupEx( pHsm );
  165. } WsbCatch( hr );
  166. WsbTraceOut( L"RsIsRemoteStorageSetup", L"hr = <%ls>", WsbHrAsString( hr ) );
  167. return( hr );
  168. }
  169. void
  170. RsReportError( HRESULT hrToReport, int textId, ... )
  171. /*++
  172. Routine Description:
  173. Reports an error to the user.
  174. Arguments:
  175. hrToReport - the hr that was thrown
  176. textId - Resource Id of context of the error
  177. ... - Substitution arguments for textId
  178. Return Value:
  179. none
  180. --*/
  181. {
  182. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  183. //
  184. // Make sure we don't report S_OK, S_FALSE
  185. //
  186. if( FAILED( hrToReport ) ) {
  187. CString errorText;
  188. CString formatString;
  189. //
  190. // Substitute in the text context string
  191. //
  192. va_list list;
  193. va_start( list, textId );
  194. formatString.LoadString( textId );
  195. LPTSTR p;
  196. p = errorText.GetBuffer( 1024 );
  197. vswprintf( p, (LPCTSTR) formatString, list );
  198. errorText.ReleaseBuffer();
  199. va_end( list );
  200. CWsbStringPtr hrText;
  201. CString msgText;
  202. CString headerText;
  203. //
  204. // Put together the complete text
  205. //
  206. hrText = WsbHrAsString( hrToReport );
  207. headerText.LoadString( IDS_ERROR_HEADER );
  208. msgText = headerText + L"\n\r\n\r" + errorText + L"\n\r\n\r" + hrText;
  209. //
  210. // Show the message
  211. //
  212. AfxMessageBox( msgText, RS_MB_ERROR );
  213. }
  214. }
  215. HRESULT
  216. RsIsRemoteStorageSetupEx(
  217. IHsmServer * pHsmServer
  218. )
  219. /*++
  220. Routine Description:
  221. Reports back if Remote Storage has been set up on this machine.
  222. Arguments:
  223. none.
  224. Return Value:
  225. S_OK if setup
  226. S_FALSE if not
  227. --*/
  228. {
  229. WsbTraceIn( L"RsIsRemoteStorageSetupEx", L"" );
  230. HRESULT hr = S_FALSE;
  231. try {
  232. //
  233. // If it has a Media Set ID, it's set up.
  234. //
  235. GUID guid;
  236. CWsbBstrPtr poolName;
  237. CComPtr<IHsmStoragePool> pPool;
  238. WsbAffirmHr( RsGetStoragePool( pHsmServer, &pPool ) );
  239. WsbAffirmHr( pPool->GetMediaSet( &guid, &poolName ) );
  240. if( ! IsEqualGUID( guid, GUID_NULL ) ) {
  241. hr = S_OK;
  242. }
  243. } WsbCatch( hr );
  244. WsbTraceOut( L"RsIsRemoteStorageSetupEx", L"hr = <%ls>", WsbHrAsString( hr ) );
  245. return( hr );
  246. }
  247. HRESULT
  248. RsIsSupportedMediaAvailable(
  249. void
  250. )
  251. /*++
  252. Routine Description:
  253. Checks to see if NTMS is setup, and setup with useable media.
  254. Arguments:
  255. none.
  256. Return Value:
  257. TRUE if NTMS is configured with supported media
  258. FALSE if NTMS is not configured with supported media
  259. --*/
  260. {
  261. WsbTraceIn( L"RsIsSupportedMediaAvailable", L"" );
  262. HRESULT hr = S_FALSE;
  263. try {
  264. //
  265. // First, contact the RMS engine and ask it if
  266. // RMS has supported media.
  267. //
  268. CWsbStringPtr computerName;
  269. WsbAffirmHr( WsbGetComputerName( computerName ) );
  270. CComPtr<IHsmServer> pHsm;
  271. CComPtr<IRmsServer> pRms;
  272. WsbTrace( L"Contacting HSM Server to get RMS\n" );
  273. WsbAffirmHr( HsmConnectFromName( HSMCONN_TYPE_HSM, computerName, IID_IHsmServer, (void**)&pHsm ) );
  274. WsbAffirmPointer(pHsm);
  275. WsbAffirmHr(pHsm->GetHsmMediaMgr(&pRms));
  276. WsbTrace( L"Connected to RMS\n" );
  277. //
  278. // Second, wait for RMS to finish initializing, thus
  279. // to have all media sets added
  280. //
  281. {
  282. CComObject<CRmsSink> *pSink = new CComObject<CRmsSink>;
  283. CComPtr<IUnknown> pSinkUnk = pSink;
  284. WsbAffirmHr( pSink->Construct( pRms ) );
  285. WsbAffirmHr( pSink->WaitForReady( ) );
  286. WsbAffirmHr( pSink->DoUnadvise( ) );
  287. }
  288. //
  289. // Fourth
  290. // Ask it
  291. //
  292. CComPtr<IWsbIndexedCollection> pMediaSets;
  293. WsbAffirmHr( pRms->GetMediaSets( &pMediaSets ) );
  294. ULONG numEntries;
  295. WsbTrace( L"Checking for Media Sets\n" );
  296. WsbAffirmHr( pMediaSets->GetEntries( &numEntries ) );
  297. WsbTrace( L"NumMediaSets = 0x%lu\n", numEntries );
  298. if( numEntries > 0 ) {
  299. //
  300. // All conditions met, return TRUE
  301. //
  302. WsbTrace( L"Supported Media Found\n" );
  303. hr = S_OK;
  304. }
  305. } WsbCatch( hr );
  306. WsbTraceOut( L"RsIsSupportedMediaAvailable", L"hr = <%ls>", WsbHrAsString( hr ) );
  307. return( hr );
  308. }
  309. USHORT
  310. RsGetCopyStatus(
  311. IN REFGUID CopyId,
  312. IN HRESULT CopyHr,
  313. IN SHORT CopyNextDataSet,
  314. IN SHORT LastGoodNextDataSet
  315. )
  316. /*++
  317. Routine Description:
  318. Compares the two times and returns an appropriate defined value
  319. based upon comparison (for Media Copies)
  320. Arguments:
  321. MasterTime - the time of last update to master
  322. CopyTime - the time of last update to copy
  323. copyStatus - returned value
  324. Return Value:
  325. none
  326. --*/
  327. {
  328. WsbTraceIn( L"RsGetCopyStatus", L"CopyId = <%ls>, CopyHr = <%ls>, CopyNextDataSet = <%hd>, LastGoodNextDataSet = <%hd>", WsbGuidAsString( CopyId ), WsbHrAsString( CopyHr ), CopyNextDataSet, LastGoodNextDataSet );
  329. USHORT copyStatus;
  330. //
  331. // Certain errors need to be masked out because they do not necessarily
  332. // mean the media copy has an error - just that something happened that
  333. // was unexpected, like timed out mounts or canceled mounts
  334. //
  335. switch( CopyHr ) {
  336. case RMS_E_CANCELLED:
  337. case RMS_E_REQUEST_REFUSED:
  338. case RMS_E_WRITE_PROTECT:
  339. case RMS_E_MEDIA_OFFLINE:
  340. case RMS_E_TIMEOUT:
  341. case RMS_E_SCRATCH_NOT_FOUND:
  342. case RMS_E_CARTRIDGE_UNAVAILABLE:
  343. case RMS_E_CARTRIDGE_DISABLED:
  344. CopyHr = S_OK;
  345. break;
  346. }
  347. if( IsEqualGUID( CopyId, GUID_NULL ) ) {
  348. copyStatus = RS_MEDIA_COPY_STATUS_NONE;
  349. } else if( RMS_E_CARTRIDGE_NOT_FOUND == CopyHr ) {
  350. copyStatus = RS_MEDIA_COPY_STATUS_MISSING;
  351. } else if( FAILED( CopyHr ) ) {
  352. copyStatus = RS_MEDIA_COPY_STATUS_ERROR;
  353. } else if( CopyNextDataSet < LastGoodNextDataSet ) {
  354. copyStatus = RS_MEDIA_COPY_STATUS_OUTSYNC;
  355. } else {
  356. copyStatus = RS_MEDIA_COPY_STATUS_INSYNC;
  357. }
  358. WsbTraceOut( L"RsGetCopyStatus", L"copyStatus = <%hu>", copyStatus );
  359. return copyStatus;
  360. }
  361. HRESULT
  362. RsGetCopyStatusStringVerb(
  363. IN USHORT copyStatus,
  364. IN BOOL plural,
  365. OUT CString & statusString
  366. )
  367. /*++
  368. Routine Description:
  369. Creates and returns a status string based on the status, with
  370. a verb on it, for example "is synchronized"
  371. Arguments:
  372. copyStatus - defined status for media copies
  373. plural - true if verb should be plural
  374. String - Resulting string
  375. Return Value:
  376. non.
  377. --*/
  378. {
  379. HRESULT hr = S_OK;
  380. WsbTraceIn( L"RsGetCopyStatusStringVerb", L"CopyStatus = <%hu> ", copyStatus );
  381. switch ( copyStatus ) {
  382. case RS_MEDIA_COPY_STATUS_NONE:
  383. if ( plural )
  384. statusString.LoadString( IDS_CAR_COPYSET_NONE_PLURAL );
  385. else
  386. statusString.LoadString( IDS_CAR_COPYSET_NONE_SINGULAR );
  387. break;
  388. case RS_MEDIA_COPY_STATUS_ERROR:
  389. statusString.LoadString( IDS_CAR_COPYSET_ERROR_SP );
  390. break;
  391. case RS_MEDIA_COPY_STATUS_MISSING:
  392. if ( plural )
  393. statusString.LoadString( IDS_CAR_COPYSET_MISSING_PLURAL );
  394. else
  395. statusString.LoadString( IDS_CAR_COPYSET_MISSING_SINGULAR );
  396. break;
  397. case RS_MEDIA_COPY_STATUS_OUTSYNC:
  398. if ( plural )
  399. statusString.LoadString( IDS_CAR_COPYSET_OUTSYNC_PLURAL );
  400. else
  401. statusString.LoadString( IDS_CAR_COPYSET_OUTSYNC_SINGULAR );
  402. break;
  403. case RS_MEDIA_COPY_STATUS_INSYNC:
  404. if ( plural )
  405. statusString.LoadString( IDS_CAR_COPYSET_INSYNC_PLURAL );
  406. else
  407. statusString.LoadString( IDS_CAR_COPYSET_INSYNC_SINGULAR );
  408. break;
  409. default:
  410. statusString = L"";
  411. hr = E_INVALIDARG;
  412. break;
  413. }
  414. WsbTraceOut( L"RsGetCopyStatusStringVerb", L"String = <%ls>", statusString );
  415. return hr;
  416. }
  417. HRESULT
  418. RsGetCopyStatusString(
  419. IN USHORT copyStatus,
  420. OUT CString & statusString
  421. )
  422. /*++
  423. Routine Description:
  424. Creates and returns a status string based on the status
  425. Arguments:
  426. copyStatus - defined status for media copies
  427. String - Resulting string
  428. Return Value:
  429. non.
  430. --*/
  431. {
  432. HRESULT hr = S_OK;
  433. WsbTraceIn( L"RsGetCopyStatusString", L"CopyStatus = <%hu> ", copyStatus );
  434. switch ( copyStatus ) {
  435. case RS_MEDIA_COPY_STATUS_NONE:
  436. statusString.LoadString( IDS_CAR_COPYSET_NONE );
  437. break;
  438. case RS_MEDIA_COPY_STATUS_ERROR:
  439. statusString.LoadString( IDS_CAR_COPYSET_ERROR );
  440. break;
  441. case RS_MEDIA_COPY_STATUS_MISSING:
  442. statusString.LoadString( IDS_CAR_COPYSET_MISSING );
  443. break;
  444. case RS_MEDIA_COPY_STATUS_OUTSYNC:
  445. statusString.LoadString( IDS_CAR_COPYSET_OUTSYNC );
  446. break;
  447. case RS_MEDIA_COPY_STATUS_INSYNC:
  448. statusString.LoadString( IDS_CAR_COPYSET_INSYNC );
  449. break;
  450. default:
  451. statusString = L"";
  452. hr = E_INVALIDARG;
  453. break;
  454. }
  455. WsbTraceOut( L"RsGetCopyStatusString", L"String = <%ls>", statusString );
  456. return hr;
  457. }
  458. USHORT
  459. RsGetCartStatus(
  460. IN HRESULT LastHr,
  461. IN BOOL ReadOnly,
  462. IN BOOL Recreate,
  463. IN SHORT NextDataSet,
  464. IN SHORT LastGoodNextDataSet
  465. )
  466. /*++
  467. Routine Description:
  468. Returns a constant appropriate the status of a piece of media.
  469. Arguments:
  470. MasterTime - the time of last update to master
  471. CopyTime - the time of last update to copy
  472. Return Value:
  473. defined constant for media status
  474. --*/
  475. {
  476. USHORT cartStatus;
  477. if( Recreate ) {
  478. cartStatus = RS_MEDIA_STATUS_RECREATE;
  479. } else if( NextDataSet < LastGoodNextDataSet ) {
  480. cartStatus = RS_MEDIA_STATUS_ERROR_INCOMPLETE;
  481. } else if( SUCCEEDED( LastHr ) || ( RMS_E_CARTRIDGE_DISABLED == LastHr ) ) {
  482. cartStatus = ( ReadOnly ? RS_MEDIA_STATUS_READONLY : RS_MEDIA_STATUS_NORMAL );
  483. } else if( RMS_E_CARTRIDGE_NOT_FOUND == LastHr ) {
  484. cartStatus = RS_MEDIA_STATUS_ERROR_MISSING;
  485. } else {
  486. cartStatus = ( ReadOnly ? RS_MEDIA_STATUS_ERROR_RO : RS_MEDIA_STATUS_ERROR_RW );
  487. }
  488. return cartStatus;
  489. }
  490. HRESULT
  491. RsGetCartStatusStringVerb(
  492. IN USHORT cartStatus,
  493. IN BOOL plural,
  494. OUT CString & statusString
  495. )
  496. /*++
  497. Routine Description:
  498. Retreives a string appropriate the status of a piece of media with
  499. a verb on it, for example "is read-only"
  500. Arguments:
  501. cartStatus
  502. String - Resulting string
  503. Return Value:
  504. non.
  505. --*/
  506. {
  507. HRESULT hr = S_OK;
  508. switch( cartStatus ) {
  509. case RS_MEDIA_STATUS_RECREATE:
  510. if( plural ) {
  511. statusString.LoadString( IDS_CAR_STATUS_RECREATE_PLURAL );
  512. } else {
  513. statusString.LoadString( IDS_CAR_STATUS_RECREATE_SINGULAR );
  514. }
  515. break;
  516. case RS_MEDIA_STATUS_READONLY:
  517. if( plural ) {
  518. statusString.LoadString( IDS_CAR_STATUS_READONLY_PLURAL );
  519. } else {
  520. statusString.LoadString( IDS_CAR_STATUS_READONLY_SINGULAR );
  521. }
  522. break;
  523. case RS_MEDIA_STATUS_NORMAL:
  524. if( plural ) {
  525. statusString.LoadString( IDS_CAR_STATUS_NORMAL_PLURAL );
  526. } else {
  527. statusString.LoadString( IDS_CAR_STATUS_NORMAL_SINGULAR );
  528. }
  529. break;
  530. case RS_MEDIA_STATUS_ERROR_RO:
  531. statusString.LoadString( IDS_CAR_STATUS_ERROR_RO_SP );
  532. break;
  533. case RS_MEDIA_STATUS_ERROR_RW:
  534. statusString.LoadString( IDS_CAR_STATUS_ERROR_RW_SP );
  535. break;
  536. case RS_MEDIA_STATUS_ERROR_INCOMPLETE:
  537. if( plural ) {
  538. statusString.LoadString( IDS_CAR_STATUS_ERROR_INCOMPLETE_PLURAL );
  539. } else {
  540. statusString.LoadString( IDS_CAR_STATUS_ERROR_INCOMPLETE_SINGULAR );
  541. }
  542. break;
  543. case RS_MEDIA_STATUS_ERROR_MISSING:
  544. if( plural ) {
  545. statusString.LoadString( IDS_CAR_STATUS_ERROR_MISSING_PLURAL );
  546. } else {
  547. statusString.LoadString( IDS_CAR_STATUS_ERROR_MISSING_SINGULAR );
  548. }
  549. break;
  550. default:
  551. statusString = L"";
  552. hr = E_INVALIDARG;
  553. }
  554. return hr;
  555. }
  556. HRESULT
  557. RsGetCartStatusString(
  558. IN USHORT cartStatus,
  559. OUT CString & statusString
  560. )
  561. /*++
  562. Routine Description:
  563. Retreives a string appropriate the status of a piece of media.
  564. Arguments:
  565. cartStatus
  566. String - Resulting string
  567. Return Value:
  568. non.
  569. --*/
  570. {
  571. HRESULT hr = S_OK;
  572. switch( cartStatus ) {
  573. case RS_MEDIA_STATUS_RECREATE:
  574. statusString.LoadString( IDS_CAR_STATUS_RECREATE );
  575. break;
  576. case RS_MEDIA_STATUS_READONLY:
  577. statusString.LoadString( IDS_CAR_STATUS_READONLY );
  578. break;
  579. case RS_MEDIA_STATUS_NORMAL:
  580. statusString.LoadString( IDS_CAR_STATUS_NORMAL );
  581. break;
  582. case RS_MEDIA_STATUS_ERROR_RO:
  583. statusString.LoadString( IDS_CAR_STATUS_ERROR_RO );
  584. break;
  585. case RS_MEDIA_STATUS_ERROR_RW:
  586. statusString.LoadString( IDS_CAR_STATUS_ERROR_RW );
  587. break;
  588. case RS_MEDIA_STATUS_ERROR_MISSING:
  589. statusString.LoadString( IDS_CAR_STATUS_ERROR_MISSING );
  590. break;
  591. case RS_MEDIA_STATUS_ERROR_INCOMPLETE:
  592. statusString.LoadString( IDS_CAR_STATUS_ERROR_INCOMPLETE );
  593. break;
  594. default:
  595. statusString = L"";
  596. hr = E_INVALIDARG;
  597. }
  598. return( hr );
  599. }
  600. HRESULT
  601. RsGetCartMultiStatusString(
  602. IN USHORT statusRecreate,
  603. IN USHORT statusReadOnly,
  604. IN USHORT statusNormal,
  605. IN USHORT statusRO,
  606. IN USHORT statusRW,
  607. IN USHORT statusMissing,
  608. OUT CString &outString )
  609. {
  610. HRESULT hr = S_OK;
  611. try {
  612. outString = L"";
  613. CString statusString;
  614. CString formatString;
  615. BOOL skipSeparator = TRUE; // used to omit first prepended comma
  616. #define INSERT_SEPARATOR if( ! skipSeparator ) { outString += ", "; } else { skipSeparator = FALSE; }
  617. if( statusNormal > 0 ) {
  618. INSERT_SEPARATOR
  619. WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_NORMAL, ( statusNormal != 1 ), statusString ) );
  620. formatString.Format( L"%d %s", statusNormal, statusString );
  621. outString += formatString;
  622. }
  623. if( statusReadOnly > 0 ) {
  624. INSERT_SEPARATOR
  625. WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_READONLY, ( statusReadOnly != 1 ), statusString ) );
  626. formatString.Format( L"%d %s", statusReadOnly, statusString );
  627. outString += formatString;
  628. }
  629. if( statusRecreate > 0 ) {
  630. INSERT_SEPARATOR
  631. WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_RECREATE, ( statusRecreate != 1 ), statusString ) );
  632. formatString.Format( L"%d %s", statusRecreate, statusString );
  633. outString += formatString;
  634. }
  635. if( statusRO > 0 ) {
  636. INSERT_SEPARATOR
  637. WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_ERROR_RO, ( statusRO != 1 ), statusString ) );
  638. formatString.Format( L"%d %s", statusRO, statusString );
  639. outString += formatString;
  640. }
  641. if( statusRW > 0 ) {
  642. INSERT_SEPARATOR
  643. WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_ERROR_RW, ( statusRW != 1 ), statusString ) );
  644. formatString.Format( L"%d %s", statusRW, statusString );
  645. outString += formatString;
  646. }
  647. if( statusMissing > 0 ) {
  648. INSERT_SEPARATOR
  649. WsbAffirmHr( RsGetCartStatusStringVerb( RS_MEDIA_STATUS_ERROR_MISSING, ( statusMissing != 1 ), statusString ) );
  650. formatString.Format( L"%d %s", statusMissing, statusString );
  651. outString += formatString;
  652. }
  653. } WsbCatch( hr );
  654. return( hr );
  655. }
  656. HRESULT
  657. RsGetCopyMultiStatusString(
  658. IN USHORT statusNone,
  659. IN USHORT statusError,
  660. IN USHORT statusOutSync,
  661. IN USHORT statusInSync,
  662. OUT CString &outString
  663. )
  664. {
  665. HRESULT hr = S_OK;
  666. try {
  667. outString = L"";
  668. CString statusString;
  669. CString formatString;
  670. WsbAffirmHr( RsGetCopyStatusStringVerb( RS_MEDIA_COPY_STATUS_INSYNC, ( statusInSync != 1), statusString ) );
  671. formatString.Format( L"%d %s, ", statusInSync, statusString );
  672. outString += formatString;
  673. WsbAffirmHr( RsGetCopyStatusStringVerb( RS_MEDIA_COPY_STATUS_OUTSYNC, ( statusOutSync != 1), statusString ) );
  674. formatString.Format( L"%d %s, ", statusOutSync, statusString );
  675. outString += formatString;
  676. WsbAffirmHr( RsGetCopyStatusStringVerb( RS_MEDIA_COPY_STATUS_NONE, ( statusNone != 1), statusString ) );
  677. formatString.Format( L"%d %s, ", statusNone, statusString );
  678. outString += formatString;
  679. WsbAffirmHr( RsGetCopyStatusStringVerb( RS_MEDIA_COPY_STATUS_ERROR, ( statusError != 1 ), statusString ) );
  680. formatString.Format( L"%d %s, ", statusError, statusString );
  681. outString += formatString;
  682. WsbAffirmHr( RsGetCopyStatusStringVerb( RS_MEDIA_COPY_STATUS_MISSING, ( statusError != 1 ), statusString ) );
  683. formatString.Format( L"%d %s", statusError, statusString );
  684. outString += formatString;
  685. } WsbCatch (hr);
  686. return hr;
  687. }
  688. HRESULT
  689. RsCreateAndRunFsaJob(
  690. IN HSM_JOB_DEF_TYPE jobType,
  691. IN IHsmServer *pHsmServer,
  692. IN IFsaResource *pFsaResource,
  693. IN BOOL ShowMsg
  694. )
  695. ///////////////////////////////////////////////////////////////////////
  696. //
  697. // RsCreateAndRunFsaJob
  698. //
  699. // Creates a job in the engine of the given type, since scanning of a
  700. // resource is required by the job, and since the job is partitioned
  701. // across the Remote Storage major components. Puts the job in the
  702. // NT Task Scheduler and runs it now via a call to the Engine's CreateTask()
  703. // method. The Task Scheduler task is Disabled, so it will not be run
  704. // according to a schedule.
  705. //
  706. //
  707. {
  708. WsbTraceIn( L"RsCreateAndRunFsaJob", L"jobType = <%d>", jobType );
  709. HRESULT hr = S_OK;
  710. CComPtr<IWsbCreateLocalObject> pLocalObject;
  711. CComPtr<IHsmJob> pExistJob;
  712. CComPtr<IHsmJob> pNewJob;
  713. CWsbStringPtr pszExistJobName;
  714. try {
  715. WsbAssertPointer( pFsaResource );
  716. WsbAssertPointer( pHsmServer );
  717. //
  718. // First check to see if volume is available. If not, return
  719. // S_FALSE
  720. //
  721. HRESULT hrAvailable = pFsaResource->IsAvailable( );
  722. WsbAffirmHr( hrAvailable );
  723. HRESULT hrDeletePending = pFsaResource->IsDeletePending( );
  724. WsbAffirmHr( hrDeletePending );
  725. WsbAffirm( ( S_OK == hrAvailable ) && ( S_OK != hrDeletePending ), S_FALSE );
  726. //
  727. // Get the volume name
  728. //
  729. CWsbStringPtr szWsbVolumeName;
  730. WsbAffirmHr( pFsaResource->GetName( &szWsbVolumeName, 0 ) );
  731. //
  732. // Create a job name
  733. //
  734. CString jobName;
  735. RsCreateJobName( jobType, pFsaResource, jobName );
  736. //
  737. // Exit with an error if a job of this name is active already
  738. //
  739. if (S_OK == pHsmServer->FindJobByName( (LPWSTR)(LPCWSTR)jobName, &pExistJob)) {
  740. if (S_OK == pExistJob->IsActive()) {
  741. WsbThrow(JOB_E_ALREADYACTIVE);
  742. }
  743. }
  744. //
  745. // Inform the user, then create the job in the Engine, finally create
  746. // and start the job in the NT Task Scheduler.
  747. //
  748. CString szJobType;
  749. WsbAffirmHr( RsGetJobTypeString( jobType, szJobType ) );
  750. CWsbStringPtr computerName;
  751. WsbAffirmHr( pHsmServer->GetName( &computerName ) );
  752. CString message;
  753. AfxFormatString2( message, IDS_RUN_JOB, jobName, computerName );
  754. if( !ShowMsg || ( AfxMessageBox( message, MB_ICONINFORMATION | MB_OKCANCEL |
  755. MB_DEFBUTTON2 ) == IDOK ) ) {
  756. //
  757. // Get the one and only (for Sakkara) storage pool Id
  758. //
  759. GUID storagePoolId;
  760. WsbAffirmHr( RsGetStoragePoolId( pHsmServer, &storagePoolId ) );
  761. //
  762. // Get a CreateLocalobject interface with which to create the job
  763. //
  764. WsbAffirmHr( RsQueryInterface( pHsmServer, IWsbCreateLocalObject, pLocalObject ) );
  765. //
  766. // Create the new job in the engine
  767. //
  768. WsbAffirmHr( pLocalObject->CreateInstance( CLSID_CHsmJob, IID_IHsmJob, (void**) &pNewJob ) );
  769. WsbAffirmHr( pNewJob->InitAs(
  770. (LPWSTR)(LPCWSTR)jobName, NULL, jobType, storagePoolId,
  771. pHsmServer, TRUE, pFsaResource));
  772. //
  773. // Get the jobs collection from the engine
  774. //
  775. CComPtr<IWsbIndexedCollection> pJobs;
  776. WsbAffirmHr( pHsmServer->GetJobs( &pJobs ) );
  777. //
  778. // If any jobs exist with this name, delete them
  779. //
  780. ULONG cCount;
  781. WsbAffirmHr (pJobs->GetEntries( &cCount ) );
  782. for( UINT i = 0; i < cCount; i++ ) {
  783. pExistJob.Release( );
  784. WsbAffirmHr( pJobs->At( i, IID_IHsmJob, (void **) &pExistJob ) );
  785. WsbAffirmHr( pExistJob->GetName( &pszExistJobName, 0 ) );
  786. if( pszExistJobName.IsEqual( jobName ) ) {
  787. WsbAffirmHr( pJobs->RemoveAndRelease( pExistJob ) );
  788. i--; cCount--;
  789. }
  790. }
  791. //
  792. // Add the new job to the engine collection
  793. //
  794. WsbAffirmHr( pJobs->Add( pNewJob ) );
  795. //
  796. // Set up to call the Engine to create an entry in NT Task Scheduler
  797. //
  798. // Create the parameter string to the program NT Scheduler
  799. // will run (for Sakkara this is RsLaunch).
  800. //
  801. CString szParameters;
  802. szParameters.Format( L"run \"%ls\"", jobName );
  803. //
  804. // Create the comment string for the NT Scheduler entry
  805. //
  806. CString commentString;
  807. AfxFormatString2( commentString, IDS_GENERIC_JOB_COMMENT, szJobType, szWsbVolumeName);
  808. //
  809. // Declare and initialize the schedule components passed to
  810. // the engine. Since this task is Disabled these are simply
  811. // set to 0 (COM requires populating all arguments).
  812. //
  813. TASK_TRIGGER_TYPE jobTriggerType = TASK_TIME_TRIGGER_ONCE;
  814. WORD jobStartHour = 0;
  815. WORD jobStartMinute = 0;
  816. //
  817. // Indicate this is a Disabled task
  818. //
  819. BOOL scheduledJob = FALSE;
  820. //
  821. // Create and run the task
  822. //
  823. WsbAffirmHr( pHsmServer->CreateTask( jobName, szParameters,
  824. commentString, jobTriggerType,
  825. jobStartHour, jobStartMinute,
  826. scheduledJob ) );
  827. }
  828. } WsbCatch( hr );
  829. WsbTraceOut( L"RsCreateAndRunFsaJob", L"hr = <%ls>", WsbHrAsString( hr ) );
  830. return( hr );
  831. }
  832. HRESULT
  833. RsCreateAndRunDirectFsaJob(
  834. IN HSM_JOB_DEF_TYPE jobType,
  835. IN IHsmServer *pHsmServer,
  836. IN IFsaResource *pFsaResource,
  837. IN BOOL waitJob
  838. )
  839. ///////////////////////////////////////////////////////////////////////
  840. //
  841. // RsCreateAndRunFsaJob
  842. //
  843. // Creates a job in the engine of the given type and run it.
  844. // Wait for the job if required.
  845. // Notes:
  846. // 1) This job is not created and ran through the Task Scheduler
  847. // 2) Most of the code is taken from StartJob in clivol.cpp
  848. // In the future we should consider using this code instead of replicating
  849. //
  850. {
  851. WsbTraceIn( L"RsCreateAndRunDirectFsaJob", L"jobType = <%d>", jobType );
  852. HRESULT hr = S_OK;
  853. try {
  854. CComPtr<IHsmJob> pJob;
  855. CString jobName;
  856. // Create job name
  857. WsbAffirmHr(RsCreateJobName(jobType, pFsaResource, jobName));
  858. // If job exists - use it, otherwize, craete and add an appropriate job object
  859. hr = pHsmServer->FindJobByName((LPWSTR)(LPCWSTR)jobName, &pJob);
  860. if (S_OK == hr) {
  861. // Job already exists
  862. } else if (WSB_E_NOTFOUND == hr) {
  863. // No such job yet
  864. CComPtr<IWsbCreateLocalObject> pCreateObj;
  865. CComPtr<IWsbIndexedCollection> pJobs;
  866. CComPtr<IWsbIndexedCollection> pCollection;
  867. CComPtr<IHsmStoragePool> pStoragePool;
  868. GUID poolId;
  869. ULONG count;
  870. hr = S_OK;
  871. pJob = 0;
  872. // Create and add the job
  873. WsbAffirmHr(pHsmServer->QueryInterface(IID_IWsbCreateLocalObject, (void**) &pCreateObj));
  874. WsbAffirmHr(pCreateObj->CreateInstance(CLSID_CHsmJob, IID_IHsmJob, (void**) &pJob));
  875. WsbAffirmHr(pHsmServer->GetStoragePools(&pCollection));
  876. WsbAffirmHr(pCollection->GetEntries(&count));
  877. WsbAffirm(1 == count, E_FAIL);
  878. WsbAffirmHr(pCollection->At(0, IID_IHsmStoragePool, (void **)&pStoragePool));
  879. WsbAffirmHr(pStoragePool->GetId(&poolId));
  880. WsbAffirmHr(pJob->InitAs((LPWSTR)(LPCWSTR)jobName, NULL, jobType,
  881. poolId, pHsmServer, TRUE, pFsaResource));
  882. WsbAffirmHr(pHsmServer->GetJobs(&pJobs));
  883. WsbAffirmHr(pJobs->Add(pJob));
  884. } else {
  885. // Other error - abort
  886. WsbThrow(hr);
  887. }
  888. // Start the job
  889. WsbAffirmHr(pJob->Start());
  890. // Wait if required
  891. if (waitJob) {
  892. WsbAffirmHr(pJob->WaitUntilDone());
  893. }
  894. } WsbCatch(hr);
  895. WsbTraceOut( L"RsCreateAndRunDirectFsaJob", L"hr = <%ls>", WsbHrAsString( hr ) );
  896. return( hr );
  897. }
  898. HRESULT
  899. RsCancelDirectFsaJob(
  900. IN HSM_JOB_DEF_TYPE jobType,
  901. IN IHsmServer *pHsmServer,
  902. IN IFsaResource *pFsaResource
  903. )
  904. ///////////////////////////////////////////////////////////////////////
  905. //
  906. // RsCancelDirectFsaJob
  907. //
  908. // Cancel a job that was previously ran with RsCreateAndRunDirectFsaJob
  909. // Notes:
  910. // 1) This job is not cancelled through the Task Scheduler
  911. // 2) Most of the code is taken from CancelJob in clivol.cpp
  912. // In the future we should consider using this code instead of replicating
  913. //
  914. {
  915. WsbTraceIn( L"RsCancelDirectFsaJob", L"jobType = <%d>", jobType );
  916. HRESULT hr = S_OK;
  917. try {
  918. CComPtr<IHsmJob> pJob;
  919. CString jobName;
  920. // Create job name
  921. WsbAffirmHr(RsCreateJobName(jobType, pFsaResource, jobName));
  922. // If job exists, try to cancel it
  923. hr = pHsmServer->FindJobByName((LPWSTR)(LPCWSTR)jobName, &pJob);
  924. if (S_OK == hr) {
  925. // Cancel (we don't care if it's actually running or not)
  926. WsbAffirmHr(pJob->Cancel(HSM_JOB_PHASE_ALL));
  927. } else if (WSB_E_NOTFOUND == hr) {
  928. // No such job, for sure it is not running...
  929. hr = S_OK;
  930. } else {
  931. // Other error - abort
  932. WsbThrow(hr);
  933. }
  934. } WsbCatch(hr);
  935. WsbTraceOut( L"RsCancelDirectFsaJob", L"hr = <%ls>", WsbHrAsString( hr ) );
  936. return( hr );
  937. }
  938. HRESULT
  939. RsCreateJobName(
  940. IN HSM_JOB_DEF_TYPE jobType,
  941. IN IFsaResource * pResource,
  942. OUT CString& jobName
  943. )
  944. /////////////////////////////////////////////////////////////////////////////////
  945. //
  946. // RsCreateJobName
  947. //
  948. // Creates a job name for a volume type job
  949. //
  950. //
  951. {
  952. WsbTraceIn( L"RsCreateJobName", L"jobType = <%d>", jobType );
  953. HRESULT hr = S_OK;
  954. try {
  955. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  956. CString jobTypeString;
  957. RsGetJobTypeString( jobType, jobTypeString );
  958. CWsbStringPtr path;
  959. WsbAffirmHr( pResource->GetUserFriendlyName( &path, 0 ) );
  960. // For now, ignore the path if it's not a drive letter
  961. size_t pathLen = wcslen(path);
  962. if ((pathLen != 3) || (path[1] != L':')) {
  963. path = L"";
  964. }
  965. CString volumeString;
  966. if( path.IsEqual ( L"" ) ) {
  967. //
  968. // No drive letter - use the volume name and serial number instead
  969. //
  970. ULONG serial;
  971. CWsbStringPtr name;
  972. WsbAffirmHr( pResource->GetName( &name, 0 ) );
  973. WsbAffirmHr( pResource->GetSerial( &serial ) );
  974. if( name.IsEqual( L"" ) ) {
  975. //
  976. // No name, no drive letter - just have serial number
  977. //
  978. volumeString.Format( L"%8.8lx", serial );
  979. } else {
  980. volumeString.Format( L"%ls-%8.8lx", (OLECHAR*)name, serial );
  981. }
  982. } else {
  983. path[1] = L'\0';
  984. volumeString = path;
  985. }
  986. AfxFormatString2( jobName, IDS_JOB_NAME_PREFIX, jobTypeString, volumeString );
  987. } WsbCatch (hr);
  988. WsbTraceOut( L"RsCreateJobName", L"hr = <%ls>, jobName = <%ls>", WsbHrAsString( hr ), (LPCWSTR)jobName );
  989. return( hr );
  990. }
  991. HRESULT
  992. RsGetJobTypeString(
  993. IN HSM_JOB_DEF_TYPE jobType,
  994. OUT CString& szJobType
  995. )
  996. {
  997. WsbTraceIn( L"RsGetJobTypeString", L"jobType = <%d>", jobType );
  998. HRESULT hr = S_OK;
  999. try {
  1000. switch( jobType ) {
  1001. case HSM_JOB_DEF_TYPE_MANAGE:
  1002. szJobType.LoadString( IDS_JOB_MANAGE );
  1003. break;
  1004. case HSM_JOB_DEF_TYPE_RECALL:
  1005. szJobType.LoadString( IDS_JOB_RECALL );
  1006. break;
  1007. case HSM_JOB_DEF_TYPE_TRUNCATE:
  1008. szJobType.LoadString( IDS_JOB_TRUNCATE );
  1009. break;
  1010. case HSM_JOB_DEF_TYPE_UNMANAGE:
  1011. szJobType.LoadString( IDS_JOB_UNMANAGE );
  1012. break;
  1013. case HSM_JOB_DEF_TYPE_FULL_UNMANAGE:
  1014. szJobType.LoadString( IDS_JOB_FULL_UNMANAGE );
  1015. break;
  1016. case HSM_JOB_DEF_TYPE_QUICK_UNMANAGE:
  1017. szJobType.LoadString( IDS_JOB_QUICK_UNMANAGE );
  1018. break;
  1019. case HSM_JOB_DEF_TYPE_VALIDATE:
  1020. szJobType.LoadString( IDS_JOB_VALIDATE );
  1021. break;
  1022. default:
  1023. WsbAssert( FALSE, E_INVALIDARG );
  1024. }
  1025. } WsbCatch ( hr );
  1026. WsbTraceOut( L"RsGetJobTypeString", L"hr = <%ls>, szJobType = <%ls>", WsbHrAsString( hr ), (LPCWSTR)szJobType );
  1027. return( hr );
  1028. }
  1029. HRESULT
  1030. RsCreateAndRunMediaCopyJob(
  1031. IN IHsmServer * pHsmServer,
  1032. IN UINT SetNum,
  1033. IN BOOL ShowMsg
  1034. )
  1035. ///////////////////////////////////////////////////////////////////////
  1036. //
  1037. // RsCreateAndRunMediaCopyJob
  1038. //
  1039. // Creates and runs a task to synchronize (update) a specified copy set.
  1040. // Since the Media Copy Job is run via a single Engine method (there is no
  1041. // partitioning of the task across major components) and no scanning of
  1042. // files/resources/etc is required to run it, this method does not create
  1043. // a job in the Engine. It only creates a task in the NT Task Scheduler and
  1044. // runs it now via a call to the Engine's CreateTask() method. The Task
  1045. // Scheduler task is Disabled, so it will not be run according to a schedule.
  1046. //
  1047. //
  1048. {
  1049. WsbTraceIn( L"RsCreateAndRunMediaCopyJob", L"SetNum = <%u>", SetNum );
  1050. HRESULT hr = S_OK;
  1051. try {
  1052. WsbAssertPointer( pHsmServer );
  1053. // Create the task name to put in the scheduler
  1054. CString jobName, message;
  1055. jobName.Format( IDS_JOB_MEDIA_COPY_TITLE, SetNum );
  1056. CWsbStringPtr computerName;
  1057. WsbAffirmHr( pHsmServer->GetName( &computerName ) );
  1058. AfxFormatString2( message, IDS_RUN_JOB, jobName, computerName );
  1059. if( !ShowMsg || ( AfxMessageBox( message, MB_ICONINFORMATION |
  1060. MB_OKCANCEL ) == IDOK ) ) {
  1061. // Set up to call the Engine to create an entry in NT Task Scheduler
  1062. // Create the parameter string to the program NT Scheduler
  1063. // will run (for Sakkara this is RsLaunch)
  1064. CString szParameters;
  1065. szParameters.Format( L"sync %d", SetNum );
  1066. // Create the comment string for the NT Scheduler entry
  1067. CString commentString;
  1068. commentString.Format( IDS_MEDIA_COPY_JOB_COMMENT, SetNum );
  1069. // Declare and initialize the schedule components passed to
  1070. // the engine. Since this task is Disabled these are simply
  1071. // set to 0 (COM requires populating all arguments).
  1072. TASK_TRIGGER_TYPE jobTriggerType = TASK_TIME_TRIGGER_ONCE;
  1073. WORD jobStartHour = 0;
  1074. WORD jobStartMinute = 0;
  1075. // Indicate this is a Disabled task
  1076. BOOL scheduledJob = FALSE;
  1077. // Create and run the task
  1078. WsbAffirmHr( pHsmServer->CreateTask( jobName, szParameters,
  1079. commentString, jobTriggerType,
  1080. jobStartHour, jobStartMinute,
  1081. scheduledJob ) );
  1082. }
  1083. } WsbCatch (hr);
  1084. WsbTraceOut( L"RsCreateAndRunMediaCopyJob", L"hr = <%ls>", WsbHrAsString( hr ) );
  1085. return( hr );
  1086. }
  1087. HRESULT
  1088. RsCreateAndRunMediaRecreateJob(
  1089. IN IHsmServer * pHsmServer,
  1090. IN IMediaInfo * pMediaInfo,
  1091. IN REFGUID MediaId,
  1092. IN CString & MediaDescription,
  1093. IN SHORT CopyToUse
  1094. )
  1095. ///////////////////////////////////////////////////////////////////////
  1096. //
  1097. // RsCreateAndRunMediaRecreateJob
  1098. //
  1099. // Creates and runs a task to recreate the master of a piece of media.
  1100. // Since the Re-create Master Job is run via a single Engine method (there
  1101. // is no partitioning of the task across major components) and no scanning
  1102. // of files/resources/etc is required to run it, this method does not create
  1103. // a job in the Engine. It only creates a task in the NT Task Scheduler and
  1104. // runs it now via a call to the Engine's CreateTask() method. The Task
  1105. // Scheduler task is Disabled, so it will not be run according to a schedule.
  1106. //
  1107. //
  1108. {
  1109. WsbTraceIn(
  1110. L"RsCreateAndRunMediaRecreateJob", L"MediaId = <%ls>, Media Description = <%ls>, CopyToUse = <%hd>",
  1111. WsbGuidAsString( MediaId ), (LPCWSTR)MediaDescription, CopyToUse );
  1112. HRESULT hr = S_OK;
  1113. try {
  1114. WsbAssertPointer( pHsmServer );
  1115. WsbAssertPointer( pMediaInfo );
  1116. // Create the task name to put in the scheduler
  1117. CString jobName, message;
  1118. AfxFormatString1( jobName, IDS_JOB_MEDIA_RECREATE_TITLE, MediaDescription );
  1119. CWsbStringPtr computerName;
  1120. WsbAffirmHr( pHsmServer->GetName( &computerName ) );
  1121. AfxFormatString2( message, IDS_RUN_JOB, jobName, computerName );
  1122. if( IDOK == AfxMessageBox( message, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2 ) ) {
  1123. // Set up to call the Engine to create an entry in NT Task Scheduler
  1124. // Create the parameter string to the program NT Scheduler
  1125. // will run (for Sakkara this is RsLaunch). First convert
  1126. // the input MediaId GUID to a string since it is used in
  1127. // the job parameter string.
  1128. CWsbStringPtr stringId( MediaId );
  1129. CString szParameters;
  1130. szParameters.Format( L"recreate -i %ls -c %hd", (WCHAR*)stringId, CopyToUse );
  1131. // Create the comment string for the NT Scheduler entry
  1132. CString commentString;
  1133. commentString.LoadString( IDS_MEDIA_RECREATE_JOB_COMMENT );
  1134. // Declare and initialize the schedule components passed to
  1135. // the engine. Since this task is Disabled these are simply
  1136. // set to 0 (COM requires populating all arguments).
  1137. TASK_TRIGGER_TYPE jobTriggerType = TASK_TIME_TRIGGER_ONCE;
  1138. WORD jobStartHour = 0;
  1139. WORD jobStartMinute = 0;
  1140. // Indicate this is a Disabled task
  1141. BOOL scheduledJob = FALSE;
  1142. // The Re-create Master job requires the Recreate state of the master
  1143. // media that will be re-created to have been set. Do so here since
  1144. // the user has already confirmed they want to run this job. (The
  1145. // UI already has the Engine's Segment database open.)
  1146. WsbAffirmHr( pMediaInfo->SetRecreate( TRUE ) );
  1147. WsbAffirmHr( pMediaInfo->Write() );
  1148. // Create and run the task
  1149. WsbAffirmHr( pHsmServer->CreateTask( jobName, szParameters,
  1150. commentString, jobTriggerType,
  1151. jobStartHour, jobStartMinute,
  1152. scheduledJob ) );
  1153. }
  1154. } WsbCatch (hr);
  1155. WsbTraceOut( L"RsCreateAndRunMediaRecreateJob", L"hr = <%ls>", WsbHrAsString( hr ) );
  1156. return( hr );
  1157. }
  1158. HRESULT
  1159. RsGetStoragePoolId(
  1160. IN IHsmServer *pHsmServer,
  1161. OUT GUID *pStoragePoolId
  1162. )
  1163. {
  1164. WsbTraceIn( L"RsGetStoragePoolId", L"pHsmServer = <0x%p>, pStoragePoolId = <0x%p>", pHsmServer, pStoragePoolId );
  1165. HRESULT hr = S_OK;
  1166. try {
  1167. CComPtr <IHsmStoragePool> pStoragePool;
  1168. WsbAffirmHr( RsGetStoragePool( pHsmServer, &pStoragePool ) );
  1169. //
  1170. // Get the GUID of the storage pool
  1171. //
  1172. WsbAffirmHr( pStoragePool->GetId( pStoragePoolId ) );
  1173. } WsbCatch( hr );
  1174. WsbTraceOut( L"RsGetStoragePoolId", L"hr = <%ls>, *pStoragePoolId = <%ls>", WsbHrAsString( hr ), WsbPtrToGuidAsString( pStoragePoolId ) );
  1175. return( hr );
  1176. }
  1177. HRESULT
  1178. RsGetStoragePool(
  1179. IN IHsmServer *pHsmServer,
  1180. OUT IHsmStoragePool **ppStoragePool
  1181. )
  1182. {
  1183. WsbTraceIn( L"RsGetStoragePool", L"pHsmServer = <0x%p>, ppStoragePool = <0x%p>", pHsmServer, ppStoragePool );
  1184. ULONG count;
  1185. HRESULT hr = S_OK;
  1186. try {
  1187. CComPtr <IWsbIndexedCollection> pCollection;
  1188. //
  1189. // Get the storage pools collection. There should only be one member.
  1190. //
  1191. WsbAffirmHr( pHsmServer->GetStoragePools( &pCollection ) );
  1192. WsbAffirmHr( pCollection->GetEntries( &count ) );
  1193. WsbAffirm( 1 == count, E_FAIL );
  1194. WsbAffirmHr( pCollection->At( 0, IID_IHsmStoragePool, (void **) ppStoragePool ) );
  1195. } WsbCatch( hr );
  1196. WsbTraceOut( L"RsGetStoragePool", L"hr = <%ls>, *pStoragePoolId = <%ls>", WsbHrAsString( hr ), WsbPtrToPtrAsString( (void**)ppStoragePool ) );
  1197. return( hr );
  1198. }
  1199. HRESULT
  1200. RsGetInitialLVColumnProps(
  1201. int IdWidths,
  1202. int IdTitles,
  1203. CString **pColumnWidths,
  1204. CString **pColumnTitles,
  1205. int *pColumnCount
  1206. )
  1207. {
  1208. HRESULT hr = S_OK;
  1209. CString szResource;
  1210. OLECHAR* szData;
  1211. int colCount = 0;
  1212. int colWidths = 0;
  1213. int colTitles = 0;
  1214. int i = 0;
  1215. try {
  1216. if ( !pColumnWidths ) {
  1217. // Caller asked us to return number of columns
  1218. colCount = 0;
  1219. szResource.LoadString (IdTitles);
  1220. szData = szResource.GetBuffer( 0 );
  1221. szData = wcstok( szData, L":" );
  1222. while( szData ) {
  1223. colCount++;
  1224. szData = wcstok( NULL, L":" );
  1225. }
  1226. } else {
  1227. // Properites Widths
  1228. colWidths = 0;
  1229. szResource.LoadString (IdWidths);
  1230. szData = szResource.GetBuffer( 0 );
  1231. szData = wcstok( szData, L":" );
  1232. while( szData ) {
  1233. pColumnWidths[colWidths++] = new CString( szData );
  1234. szData = wcstok( NULL, L":" );
  1235. }
  1236. // Properites Titles
  1237. colTitles = 0;
  1238. szResource.LoadString (IdTitles);
  1239. szData = szResource.GetBuffer( 0 );
  1240. szData = wcstok( szData, L":" );
  1241. while( szData ) {
  1242. pColumnTitles[colTitles++] = new CString( szData );
  1243. szData = wcstok( NULL, L":" );
  1244. }
  1245. WsbAffirm( ( colTitles == colWidths ), E_FAIL );
  1246. colCount = colTitles;
  1247. }
  1248. *pColumnCount = colCount;
  1249. } WsbCatch (hr);
  1250. return hr;
  1251. }
  1252. HRESULT
  1253. RsServerSaveAll(
  1254. IN IUnknown * pUnkServer
  1255. )
  1256. {
  1257. WsbTraceIn( L"RsServerSaveAll", L"" );
  1258. HRESULT hr = S_OK;
  1259. try {
  1260. CComPtr<IWsbServer> pServer;
  1261. WsbAffirmHr( RsQueryInterface( pUnkServer, IWsbServer, pServer ) );
  1262. WsbAffirmHr( pServer->SaveAll( ) );
  1263. } WsbCatch( hr )
  1264. WsbTraceOut( L"RsServerSaveAll", L"hr = <%ls>", WsbHrAsString( hr ) );
  1265. return( hr );
  1266. }
  1267. HRESULT
  1268. RsGetVolumeDisplayName(
  1269. IFsaResource * pResource,
  1270. CString & DisplayName
  1271. )
  1272. {
  1273. WsbTraceIn( L"RsGetVolumeDisplayName", L"" );
  1274. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1275. HRESULT hr = S_OK;
  1276. try {
  1277. WsbAffirmPointer( pResource );
  1278. CWsbStringPtr label;
  1279. CWsbStringPtr userName;
  1280. WsbAffirmHr( pResource->GetName( &label, 0 ) );
  1281. WsbAffirmHr( pResource->GetUserFriendlyName( &userName, 0 ) );
  1282. // The user name is a drive letter.
  1283. if( userName.IsEqual( L"" ) ) {
  1284. if( label.IsEqual( L"" ) ) {
  1285. if (S_OK == pResource->IsAvailable()) {
  1286. DisplayName.LoadString( IDS_UNLABELED_VOLUME );
  1287. } else {
  1288. CString str1, str2;
  1289. str1.LoadString( IDS_UNLABELED_VOLUME );
  1290. str2.LoadString( IDS_VOL_NOT_AVAILABLE );
  1291. DisplayName.Format( L"%ls (%ls)", str1.GetBuffer(0), str2.GetBuffer(0) );
  1292. }
  1293. } else {
  1294. // If it's not a drive letter we use the label.
  1295. if (S_OK == pResource->IsAvailable()) {
  1296. DisplayName.Format( L"%ls", (WCHAR*)label );
  1297. } else {
  1298. CString str2;
  1299. str2.LoadString( IDS_VOL_NOT_AVAILABLE );
  1300. DisplayName.Format( L"%ls (%ls)", (WCHAR*)label, str2.GetBuffer(0) );
  1301. }
  1302. }
  1303. } else {
  1304. userName[(int)(wcslen(userName)-1)] = 0;
  1305. // The user name is a drive letter or a mount point path with a trailing backslash
  1306. // If the label is "", it's ignored in the formatting.
  1307. DisplayName.Format( L"%ls (%ls)", (WCHAR*)label, (WCHAR*)userName );
  1308. }
  1309. } WsbCatch( hr )
  1310. WsbTraceOut( L"RsGetVolumeDisplayName", L"hr = <%ls>, DisplayName = <%ls>", WsbHrAsString( hr ), (LPCWSTR)DisplayName );
  1311. return( hr );
  1312. }
  1313. // Temporary version that for unlabeled volumes w/ drive-letter puts in the
  1314. // size and free space
  1315. HRESULT
  1316. RsGetVolumeDisplayName2(
  1317. IFsaResource * pResource,
  1318. CString & DisplayName
  1319. )
  1320. {
  1321. WsbTraceIn( L"RsGetVolumeDisplayName2", L"" );
  1322. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1323. HRESULT hr = S_OK;
  1324. try {
  1325. WsbAffirmPointer( pResource );
  1326. CWsbStringPtr label;
  1327. CWsbStringPtr userName;
  1328. WsbAffirmHr( pResource->GetName( &label, 0 ) );
  1329. WsbAffirmHr( pResource->GetUserFriendlyName( &userName, 0 ) );
  1330. // The user name is a drive letter.
  1331. if( userName.IsEqual ( L"" ) ) {
  1332. if( label.IsEqual ( L"" ) ) {
  1333. LONGLONG totalSpace = 0;
  1334. LONGLONG freeSpace = 0;
  1335. LONGLONG premigrated = 0;
  1336. LONGLONG truncated = 0;
  1337. WsbAffirmHr( pResource->GetSizes( &totalSpace, &freeSpace, &premigrated, &truncated ) );
  1338. CString totalString, freeString;
  1339. RsGuiFormatLongLong4Char( totalSpace, totalString );
  1340. RsGuiFormatLongLong4Char( freeSpace, freeString );
  1341. AfxFormatString2( DisplayName, IDS_UNLABELED_VOLUME2, totalString, freeString );
  1342. } else {
  1343. // If it's not a drive letter we use the label.
  1344. DisplayName.Format( L"%ls", (WCHAR*)label );
  1345. }
  1346. } else {
  1347. userName[(int)(wcslen(userName)-1)] = 0;
  1348. // The user name is a drive letter or a mount point path with a trailing backslash
  1349. // If the label is "", it's ignored in the formatting.
  1350. DisplayName.Format( L"%ls (%ls)", (WCHAR*)label, (WCHAR*)userName );
  1351. }
  1352. } WsbCatch( hr )
  1353. WsbTraceOut( L"RsGetVolumeDisplayName2", L"hr = <%ls>, DisplayName = <%ls>", WsbHrAsString( hr ), (LPCWSTR)DisplayName );
  1354. return( hr );
  1355. }
  1356. HRESULT
  1357. RsGetVolumeSortKey(
  1358. IFsaResource * pResource,
  1359. CString & DisplayName
  1360. )
  1361. {
  1362. WsbTraceIn( L"RsGetVolumeSortKey", L"" );
  1363. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1364. HRESULT hr = S_OK;
  1365. try {
  1366. WsbAffirmPointer( pResource );
  1367. CWsbStringPtr label;
  1368. CWsbStringPtr userName;
  1369. WsbAffirmHr( pResource->GetName( &label, 0 ) );
  1370. WsbAffirmHr( pResource->GetUserFriendlyName( &userName, 0 ) );
  1371. DisplayName.Format( L"%ls %ls", (WCHAR*)userName, (WCHAR*)label );
  1372. } WsbCatch( hr )
  1373. WsbTraceOut( L"RsGetVolumeSortKey", L"hr = <%ls>, DisplayName = <%ls>", WsbHrAsString( hr ), (LPCWSTR)DisplayName );
  1374. return( hr );
  1375. }
  1376. HRESULT
  1377. RsIsVolumeAvailable(
  1378. IFsaResource * pResource
  1379. )
  1380. {
  1381. WsbTraceIn( L"RsIsVolumeAvailable", L"" );
  1382. HRESULT hr = S_OK;
  1383. try {
  1384. WsbAffirmPointer( pResource );
  1385. hr = pResource->IsAvailable();
  1386. } WsbCatch( hr )
  1387. WsbTraceOut( L"RsIsVolumeAvailable", L"hr = <%ls>", WsbHrAsString( hr ) );
  1388. return( hr );
  1389. }
  1390. HRESULT
  1391. RsIsWhiteOnBlack(
  1392. )
  1393. {
  1394. WsbTraceIn( L"RsIsWhiteOnBlack", L"" );
  1395. HRESULT hr = S_FALSE;
  1396. #define RS_CONTRAST_LIMIT 173
  1397. //
  1398. // Look to see if button background is within RS_CONTRAST_LIMIT
  1399. // units of black.
  1400. // Note that full white has a distance of 256 * sqrt(3) = 443
  1401. // Use Euclidean distance but compare before taking root
  1402. //
  1403. DWORD face3d = ::GetSysColor( COLOR_3DFACE );
  1404. DWORD blackDelta = GetRValue( face3d ) * GetRValue( face3d ) +
  1405. GetGValue( face3d ) * GetGValue( face3d ) +
  1406. GetBValue( face3d ) * GetBValue( face3d );
  1407. if( blackDelta < RS_CONTRAST_LIMIT * RS_CONTRAST_LIMIT ) {
  1408. hr = S_OK;
  1409. }
  1410. WsbTraceOut( L"RsIsWhiteOnBlack", L"hr = <%ls>", WsbHrAsString( hr ) );
  1411. return( hr );
  1412. }
  1413. HRESULT
  1414. RsIsRmsErrorNotReady(
  1415. HRESULT HrError
  1416. )
  1417. {
  1418. WsbTraceIn( L"RsIsRmsErrorNotReady", L"" );
  1419. HRESULT hr = S_FALSE;
  1420. try {
  1421. switch( HrError ) {
  1422. case RMS_E_NOT_READY_SERVER_STARTING:
  1423. case RMS_E_NOT_READY_SERVER_STARTED:
  1424. case RMS_E_NOT_READY_SERVER_INITIALIZING:
  1425. case RMS_E_NOT_READY_SERVER_STOPPING:
  1426. case RMS_E_NOT_READY_SERVER_STOPPED:
  1427. case RMS_E_NOT_READY_SERVER_DISABLED:
  1428. case RMS_E_NOT_READY_SERVER_LOCKED:
  1429. hr = S_OK;
  1430. }
  1431. } WsbCatch( hr );
  1432. WsbTraceOut( L"RsIsRmsErrorNotReady", L"hr = <%ls>", WsbHrAsString( hr ) );
  1433. return( hr );
  1434. }