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.

835 lines
29 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. cliadmin.cpp
  5. Abstract:
  6. Implements CLI ADMIN sub-interface
  7. Author:
  8. Ran Kalach [rankala] 3-March-2000
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "HsmConn.h"
  13. #include "engine.h"
  14. #include "rsstrdef.h"
  15. #include "mstask.h"
  16. static GUID g_nullGuid = GUID_NULL;
  17. // Internal utilities and classes for VOLUME interface
  18. HRESULT DisplayServiceStatus(void);
  19. HRESULT IsHsmInitialized(IN IHsmServer *pHsm);
  20. HRESULT
  21. AdminSet(
  22. IN DWORD RecallLimit,
  23. IN DWORD AdminExempt,
  24. IN DWORD MediaCopies,
  25. IN DWORD Concurrency,
  26. IN PVOID Schedule
  27. )
  28. /*++
  29. Routine Description:
  30. Sets Remote Storage general parameters
  31. Arguments:
  32. RecallLimit - The runaway recall limit to set
  33. AdminExempt - Whether to set administrators exempt for the recall limit
  34. MediaCopies - Number of media copy sets
  35. Concurrency - How many migrate jobs/recalls can be executed concurrently
  36. Schedule - The schedule for the global migration ("Manage") job of all managed volumes
  37. Return Value:
  38. S_OK - If all the parameters are set successfully
  39. Notes:
  40. The scheduling implementation of HSM (in the Engine) allows only one scheduling
  41. for the global Manage job. The scheduling given here overrides any former scheduling.
  42. However, the user can add another scheduling to the same task using the Task Scheduler UI.
  43. Enabling that via HSM, requires changing the CHsmServer::CreateTaskEx implementation
  44. --*/
  45. {
  46. HRESULT hr = S_OK;
  47. WsbTraceIn(OLESTR("AdminSet"), OLESTR(""));
  48. try {
  49. CWsbStringPtr param;
  50. // Verify that input parameters are valid
  51. WsbAffirmHr(ValidateLimitsArg(RecallLimit, IDS_RECALL_LIMIT, HSMADMIN_MIN_RECALL_LIMIT, INVALID_DWORD_ARG));
  52. WsbAffirmHr(ValidateLimitsArg(MediaCopies, IDS_MEDIA_COPIES_PRM, HSMADMIN_MIN_COPY_SETS, HSMADMIN_MAX_COPY_SETS));
  53. WsbAffirmHr(ValidateLimitsArg(Concurrency, IDS_CONCURRENCY_PRM, HSMADMIN_MIN_CONCURRENT_TASKS, INVALID_DWORD_ARG));
  54. // Set parameters, if an error occurs we abort
  55. if ((INVALID_DWORD_ARG != RecallLimit) || (INVALID_DWORD_ARG != AdminExempt)) {
  56. // Need Fsa server and Fsa filter here
  57. CComPtr<IFsaServer> pFsa;
  58. CComPtr<IFsaFilter> pFsaFilter;
  59. WsbAffirmHr(HsmConnectFromId(HSMCONN_TYPE_FSA, g_nullGuid, IID_IFsaServer, (void**)&pFsa));
  60. WsbAffirmHr(pFsa->GetFilter( &pFsaFilter));
  61. // Recall limit
  62. if (INVALID_DWORD_ARG != RecallLimit) {
  63. WsbAffirmHr(pFsaFilter->SetMaxRecalls(RecallLimit));
  64. }
  65. // Admin exempt
  66. if (INVALID_DWORD_ARG != AdminExempt) {
  67. BOOL bAdminExempt = (0 == AdminExempt) ? FALSE : TRUE;
  68. WsbAffirmHr(pFsaFilter->SetAdminExemption(bAdminExempt));
  69. }
  70. }
  71. if ( (INVALID_DWORD_ARG != MediaCopies) || (INVALID_DWORD_ARG != Concurrency) ||
  72. (INVALID_POINTER_ARG != Schedule) ) {
  73. // Need Hsm server
  74. CComPtr<IHsmServer> pHsm;
  75. WsbAffirmHr(HsmConnectFromId(HSMCONN_TYPE_HSM, g_nullGuid, IID_IHsmServer, (void**)&pHsm));
  76. // Concurrency
  77. if (INVALID_DWORD_ARG != Concurrency) {
  78. WsbAffirmHr(pHsm->SetCopyFilesUserLimit(Concurrency));
  79. }
  80. // Media copies
  81. if (INVALID_DWORD_ARG != MediaCopies) {
  82. CComPtr<IHsmStoragePool> pStoragePool;
  83. CComPtr<IWsbIndexedCollection> pCollection;
  84. ULONG count;
  85. // Get the storage pools collection. There should only be one member.
  86. WsbAffirmHr(pHsm->GetStoragePools(&pCollection));
  87. WsbAffirmHr(pCollection->GetEntries(&count));
  88. WsbAffirm(1 == count, E_FAIL);
  89. WsbAffirmHr(pCollection->At(0, IID_IHsmStoragePool, (void **)&pStoragePool));
  90. WsbAffirmHr(pStoragePool->SetNumMediaCopies((USHORT)MediaCopies));
  91. }
  92. // Scheduling
  93. if (INVALID_POINTER_ARG != Schedule) {
  94. CWsbStringPtr taskName, taskComment;
  95. TASK_TRIGGER_TYPE taskType;
  96. PHSM_JOB_SCHEDULE pSchedule = (PHSM_JOB_SCHEDULE)Schedule;
  97. SYSTEMTIME runTime;
  98. DWORD runOccurrence;
  99. // Set default valuess
  100. GetSystemTime(&runTime);
  101. runOccurrence = 0;
  102. // Set input
  103. switch (pSchedule->Frequency) {
  104. case Daily:
  105. taskType = TASK_TIME_TRIGGER_DAILY;
  106. runTime = pSchedule->Parameters.Daily.Time;
  107. runOccurrence = pSchedule->Parameters.Daily.Occurrence;
  108. break;
  109. case Weekly:
  110. taskType = TASK_TIME_TRIGGER_WEEKLY;
  111. runTime = pSchedule->Parameters.Weekly.Time;
  112. runOccurrence = pSchedule->Parameters.Weekly.Occurrence;
  113. break;
  114. case Monthly:
  115. taskType = TASK_TIME_TRIGGER_MONTHLYDATE;
  116. runTime = pSchedule->Parameters.Monthly.Time;
  117. break;
  118. case Once:
  119. taskType = TASK_TIME_TRIGGER_ONCE;
  120. runTime = pSchedule->Parameters.Once.Time;
  121. break;
  122. case WhenIdle:
  123. taskType = TASK_EVENT_TRIGGER_ON_IDLE;
  124. runOccurrence = pSchedule->Parameters.WhenIdle.Occurrence;
  125. break;
  126. case SystemStartup:
  127. taskType = TASK_EVENT_TRIGGER_AT_SYSTEMSTART;
  128. break;
  129. case Login:
  130. taskType = TASK_EVENT_TRIGGER_AT_LOGON;
  131. break;
  132. default:
  133. WsbThrow(E_INVALIDARG);
  134. }
  135. // Create the task with the new scheduling
  136. // Note: Task parameters should not be localized - this is a parameter for RsLaunch.exe
  137. WsbAffirmHr(WsbGetResourceString(IDS_HSM_SCHED_TASK_TITLE, &taskName));
  138. WsbAffirmHr(WsbGetResourceString(IDS_HSM_SCHED_COMMENT, &taskComment));
  139. WsbAffirmHr(pHsm->CreateTaskEx(taskName, L"run manage", taskComment,
  140. taskType, runTime, runOccurrence, TRUE));
  141. }
  142. }
  143. } WsbCatch(hr);
  144. WsbTraceOut(OLESTR("AdminSet"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  145. return hr;
  146. }
  147. // Local structure for AdminShow
  148. typedef struct _FSA_VOLUME_DATA {
  149. WCHAR *Name;
  150. BOOL Managed;
  151. } FSA_VOLUME_DATA, *PFSA_VOLUME_DATA;
  152. #define DATA_ALLOC_SIZE 10
  153. HRESULT
  154. AdminShow(
  155. IN BOOL RecallLimit,
  156. IN BOOL AdminExempt,
  157. IN BOOL MediaCopies,
  158. IN BOOL Concurrency,
  159. IN BOOL Schedule,
  160. IN BOOL General,
  161. IN BOOL Manageables,
  162. IN BOOL Managed,
  163. IN BOOL Media
  164. )
  165. /*++
  166. Routine Description:
  167. Shows (prints to stdout) Remote Storage general parameters
  168. Arguments:
  169. RecallLimit - The runaway recall limit
  170. AdminExempt - Whether administrators are exempt from the recall limit
  171. MediaCopies - Number of media copy sets
  172. Concurrency - How many migrate jobs/recalls can be executed concurrently
  173. Schedule - The schedule for the global migration ("Manage") job of all managed volumes
  174. General - General information: version, status, number of volumes managed,
  175. number of tape cartridges used, data in remote storage
  176. Manageables - List of volumes that may be managed by HSM
  177. Managed - List of volumes that are managed by HSM
  178. Media - List of medias that are allocated to HSM
  179. Return Value:
  180. S_OK - If all the required parameters are printed successfully
  181. Notes:
  182. The schedule is printed in a form of a list (like the volume list), not like a single parameter.
  183. The reason is that a user can specify several schedules for the global Manage job.
  184. --*/
  185. {
  186. HRESULT hr = S_OK;
  187. // Volume saved data
  188. PFSA_VOLUME_DATA pVolumesData = NULL;
  189. ULONG volDataSize = 0;
  190. // Media save data
  191. BSTR* pMediasData = NULL;
  192. ULONG mediaDataSize = 0;
  193. CComPtr<IWsbDb> pDb;
  194. CComPtr<IWsbDbSession> pDbSession;
  195. WsbTraceIn(OLESTR("AdminShow"), OLESTR(""));
  196. try {
  197. CComPtr<IFsaServer> pFsa;
  198. CComPtr<IHsmServer> pHsm;
  199. CWsbStringPtr param;
  200. CWsbStringPtr data;
  201. WCHAR longData[100];
  202. LPVOID pTemp;
  203. // Volume data
  204. LONGLONG dataInStorage = 0;
  205. ULONG manageableCount = 0;
  206. ULONG managedCount = 0;
  207. // Media data
  208. ULONG mediaAllocated = 0;
  209. // Get required HSM servers
  210. if (RecallLimit || AdminExempt || Manageables || Managed || General) {
  211. // Need Fsa server
  212. hr = HsmConnectFromId(HSMCONN_TYPE_FSA, g_nullGuid, IID_IFsaServer, (void**)&pFsa);
  213. if (S_OK != hr) {
  214. // Just print status before aborting
  215. if (General) {
  216. DisplayServiceStatus();
  217. }
  218. }
  219. WsbAffirmHr(hr);
  220. }
  221. if (MediaCopies || Concurrency || General || Media) {
  222. // Need Hsm (Engine) server
  223. hr = HsmConnectFromId(HSMCONN_TYPE_HSM, g_nullGuid, IID_IHsmServer, (void**)&pHsm);
  224. if (S_OK != hr) {
  225. // Just print status before aborting
  226. if (General) {
  227. DisplayServiceStatus();
  228. }
  229. }
  230. WsbAffirmHr(hr);
  231. }
  232. //
  233. // Get basic information required according to the input settings
  234. //
  235. // Volumes data
  236. if (General || Manageables || Managed) {
  237. // Need to collect volumes information
  238. CComPtr<IWsbEnum> pEnum;
  239. CComPtr<IFsaResource> pResource;
  240. HRESULT hrEnum;
  241. BOOL bManaged;
  242. LONGLONG totalSpace = 0;
  243. LONGLONG freeSpace = 0;
  244. LONGLONG premigrated = 0;
  245. LONGLONG truncated = 0;
  246. LONGLONG totalPremigrated = 0;
  247. LONGLONG totalTruncated = 0;
  248. WsbAffirmHr(pFsa->EnumResources(&pEnum));
  249. hrEnum = pEnum->First(IID_IFsaResource, (void**)&pResource);
  250. WsbAffirm((S_OK == hrEnum) || (WSB_E_NOTFOUND == hrEnum), hrEnum);
  251. if (Manageables || Managed) {
  252. volDataSize = DATA_ALLOC_SIZE;
  253. pVolumesData = (PFSA_VOLUME_DATA)WsbAlloc(volDataSize * sizeof(FSA_VOLUME_DATA));
  254. WsbAffirm(0 != pVolumesData, E_OUTOFMEMORY);
  255. }
  256. while(S_OK == hrEnum) {
  257. // Don't count or display unavailable volumes
  258. if (S_OK != pResource->IsAvailable()) {
  259. goto skip_volume;
  260. }
  261. bManaged = (pResource->IsManaged() == S_OK);
  262. if (Manageables) {
  263. if (volDataSize == manageableCount) {
  264. volDataSize += DATA_ALLOC_SIZE;
  265. pTemp = WsbRealloc(pVolumesData, volDataSize * sizeof(FSA_VOLUME_DATA));
  266. WsbAffirm(0 != pTemp, E_OUTOFMEMORY);
  267. pVolumesData = (PFSA_VOLUME_DATA)pTemp;
  268. }
  269. pVolumesData[manageableCount].Name = NULL;
  270. WsbAffirmHr(CliGetVolumeDisplayName(pResource, &(pVolumesData[manageableCount].Name)));
  271. pVolumesData[manageableCount].Managed = bManaged;
  272. }
  273. manageableCount++;
  274. if(bManaged) {
  275. if (General) {
  276. WsbAffirmHr(pResource->GetSizes(&totalSpace, &freeSpace, &premigrated, &truncated));
  277. totalPremigrated += premigrated;
  278. totalTruncated += truncated;
  279. }
  280. if (Managed && (!Manageables)) {
  281. // Collect data only for managed volumes
  282. if (volDataSize == managedCount) {
  283. volDataSize += DATA_ALLOC_SIZE;
  284. pTemp = WsbRealloc(pVolumesData, volDataSize * sizeof(FSA_VOLUME_DATA));
  285. WsbAffirm(0 != pTemp, E_OUTOFMEMORY);
  286. pVolumesData = (PFSA_VOLUME_DATA)pTemp;
  287. }
  288. pVolumesData[managedCount].Name = NULL;
  289. WsbAffirmHr(CliGetVolumeDisplayName(pResource, &(pVolumesData[managedCount].Name)));
  290. pVolumesData[managedCount].Managed = TRUE;
  291. }
  292. managedCount++;
  293. }
  294. skip_volume:
  295. // Prepare for next iteration
  296. pResource = 0;
  297. hrEnum = pEnum->Next( IID_IFsaResource, (void**)&pResource );
  298. }
  299. if (Manageables) {
  300. volDataSize = manageableCount;
  301. } else if (Managed) {
  302. volDataSize = managedCount;
  303. }
  304. if (General) {
  305. dataInStorage = totalPremigrated + totalTruncated;
  306. }
  307. }
  308. // Medias data
  309. if (General || Media) {
  310. CComPtr<IMediaInfo> pMediaInfo;
  311. GUID mediaSubsystemId;
  312. CComPtr<IRmsServer> pRms;
  313. CComPtr<IRmsCartridge> pRmsCart;
  314. HRESULT hrFind;
  315. WsbAffirmHr(pHsm->GetHsmMediaMgr(&pRms));
  316. WsbAffirmHr(pHsm->GetSegmentDb(&pDb));
  317. WsbAffirmHr(pDb->Open(&pDbSession));
  318. WsbAffirmHr(pDb->GetEntity(pDbSession, HSM_MEDIA_INFO_REC_TYPE, IID_IMediaInfo, (void**)&pMediaInfo));
  319. if (Media) {
  320. mediaDataSize = DATA_ALLOC_SIZE;
  321. pMediasData = (BSTR *)WsbAlloc(mediaDataSize * sizeof(BSTR));
  322. WsbAffirm(0 != mediaDataSize, E_OUTOFMEMORY);
  323. }
  324. for (hr = pMediaInfo->First(); S_OK == hr; hr = pMediaInfo->Next()) {
  325. WsbAffirmHr(pMediaInfo->GetMediaSubsystemId(&mediaSubsystemId));
  326. hrFind = pRms->FindCartridgeById(mediaSubsystemId, &pRmsCart);
  327. if (S_OK == hrFind) { // Otherwise, the media is not valid anymore, it could have been deallocated
  328. if (Media) {
  329. if (mediaDataSize == mediaAllocated) {
  330. mediaDataSize += DATA_ALLOC_SIZE;
  331. pTemp = WsbRealloc(pMediasData, mediaDataSize * sizeof(BSTR));
  332. WsbAffirm(0 != pTemp, E_OUTOFMEMORY);
  333. pMediasData = (BSTR *)pTemp;
  334. }
  335. pMediasData[mediaAllocated] = NULL;
  336. WsbAffirmHr(pRmsCart->GetName(&(pMediasData[mediaAllocated])));
  337. if ( (NULL == pMediasData[mediaAllocated]) ||
  338. (0 == wcscmp(pMediasData[mediaAllocated], OLESTR(""))) ) {
  339. // Try decsription
  340. if (NULL != pMediasData[mediaAllocated]) {
  341. WsbFreeString(pMediasData[mediaAllocated]);
  342. }
  343. WsbAffirmHr(pRmsCart->GetDescription(&(pMediasData[mediaAllocated])));
  344. }
  345. }
  346. mediaAllocated++;
  347. pRmsCart = 0;
  348. }
  349. }
  350. if (Media) {
  351. mediaDataSize = mediaAllocated;
  352. }
  353. hr = S_OK;
  354. if(pDb) {
  355. pDb->Close(pDbSession);
  356. pDb = 0;
  357. }
  358. }
  359. //
  360. // Print parameters
  361. //
  362. // General parameters
  363. if (General) {
  364. WsbTraceAndPrint(CLI_MESSAGE_GENERAL_PARMS, NULL);
  365. // Status
  366. WsbAffirmHr(DisplayServiceStatus());
  367. // Manageable && Managed
  368. WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_NOF_MANAGEABLES));
  369. swprintf(longData, OLESTR("%lu"), manageableCount);
  370. WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL);
  371. WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_NOF_MANAGED));
  372. swprintf(longData, OLESTR("%lu"), managedCount);
  373. WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL);
  374. // Tapes
  375. WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_NOF_CARTRIDGES));
  376. swprintf(longData, OLESTR("%lu"), mediaAllocated);
  377. WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL);
  378. // Data in RS
  379. WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_REMOTE_DATA));
  380. WsbAffirmHr(ShortSizeFormat64(dataInStorage, longData));
  381. WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL);
  382. // Version
  383. {
  384. CComPtr<IWsbServer> pWsbHsm;
  385. CWsbStringPtr ntProductVersionHsm;
  386. ULONG ntProductBuildHsm;
  387. ULONG buildVersionHsm;
  388. WsbAffirmHr(pHsm->QueryInterface(IID_IWsbServer, (void **)&pWsbHsm));
  389. WsbAffirmHr(pWsbHsm->GetNtProductBuild(&ntProductBuildHsm));
  390. WsbAffirmHr(pWsbHsm->GetNtProductVersion(&ntProductVersionHsm, 0));
  391. WsbAffirmHr(pWsbHsm->GetBuildVersion(&buildVersionHsm));
  392. WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_HSM_VERSION));
  393. WsbAffirmHr(data.Realloc(wcslen(ntProductVersionHsm) + 30));
  394. swprintf(data, L"%ls.%d [%ls]", (WCHAR*)ntProductVersionHsm, ntProductBuildHsm, RsBuildVersionAsString(buildVersionHsm));
  395. WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, (WCHAR *)data, NULL);
  396. }
  397. }
  398. // Manageable volumes
  399. if (Manageables) {
  400. WsbTraceAndPrint(CLI_MESSAGE_MANAGEABLE_VOLS, NULL);
  401. for (ULONG i=0; i<volDataSize; i++) {
  402. if (pVolumesData[i].Name) {
  403. WsbTraceAndPrint(CLI_MESSAGE_VALUE_DISPLAY, pVolumesData[i].Name, NULL);
  404. }
  405. }
  406. }
  407. // Managed volumes
  408. if (Managed) {
  409. WsbTraceAndPrint(CLI_MESSAGE_MANAGED_VOLS, NULL);
  410. for (ULONG i=0; i<volDataSize; i++) {
  411. if (pVolumesData[i].Name && pVolumesData[i].Managed) {
  412. WsbTraceAndPrint(CLI_MESSAGE_VALUE_DISPLAY, pVolumesData[i].Name, NULL);
  413. }
  414. }
  415. }
  416. // Allocated Medias
  417. if (Media) {
  418. WsbTraceAndPrint(CLI_MESSAGE_MEDIAS, NULL);
  419. for (ULONG i=0; i<mediaDataSize; i++) {
  420. if (NULL != pMediasData[i]) {
  421. WsbTraceAndPrint(CLI_MESSAGE_VALUE_DISPLAY, (WCHAR *)pMediasData[i], NULL);
  422. }
  423. }
  424. }
  425. // Schedule
  426. if (Schedule) {
  427. // Use Task Scheduler objects to get the data
  428. CComPtr<ISchedulingAgent> pSchedAgent;
  429. CComPtr<ITask> pTask;
  430. CWsbStringPtr manageJobName;
  431. // Initialize scheduling agent
  432. WsbAffirmHr(CoCreateInstance(CLSID_CSchedulingAgent, 0, CLSCTX_SERVER, IID_ISchedulingAgent, (void **)&pSchedAgent));
  433. pSchedAgent->SetTargetComputer(NULL); // local machine
  434. // Get the relevant task
  435. WsbAffirmHr(WsbGetResourceString(IDS_HSM_SCHED_TASK_TITLE, &manageJobName));
  436. hr = pSchedAgent->Activate(manageJobName, IID_ITask, (IUnknown**)&pTask);
  437. if (E_INVALIDARG == hr) {
  438. // Print no scheduling message (Manage job is not found as a scheduled task)
  439. WsbTraceAndPrint(CLI_MESSAGE_NO_SCHEDULING, NULL);
  440. hr = S_OK;
  441. } else if (S_OK == hr) {
  442. // Get scheduling strings and print
  443. WORD wTriggerCount;
  444. WsbAffirmHr(pTask->GetTriggerCount(&wTriggerCount));
  445. if (wTriggerCount == 0) {
  446. WsbTraceAndPrint(CLI_MESSAGE_NO_SCHEDULING, NULL);
  447. } else {
  448. WsbTraceAndPrint(CLI_MESSAGE_SCHEDULING_LIST, NULL);
  449. }
  450. for (WORD triggerIndex = 0; triggerIndex < wTriggerCount; triggerIndex++) {
  451. WCHAR *pTriggerString = NULL;
  452. WsbAffirmHr(pTask->GetTriggerString(triggerIndex, &pTriggerString));
  453. // Print
  454. WsbTraceAndPrint(CLI_MESSAGE_VALUE_DISPLAY, pTriggerString, NULL);
  455. CoTaskMemFree(pTriggerString);
  456. }
  457. } else {
  458. WsbAffirmHr(hr);
  459. }
  460. }
  461. // Limits and Media Copies
  462. if (RecallLimit || AdminExempt) {
  463. // Need Fsa filter here
  464. CComPtr<IFsaFilter> pFsaFilter;
  465. WsbAffirmHr(pFsa->GetFilter(&pFsaFilter));
  466. if (RecallLimit) {
  467. ULONG maxRecalls;
  468. WsbAffirmHr(pFsaFilter->GetMaxRecalls(&maxRecalls));
  469. WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_RECALL_LIMIT));
  470. swprintf(longData, OLESTR("%lu"), maxRecalls);
  471. WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL);
  472. }
  473. if (AdminExempt) {
  474. BOOL adminExempt;
  475. WsbAffirmHr(pFsaFilter->GetAdminExemption(&adminExempt));
  476. WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_ADMIN_EXEMPT));
  477. WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, WsbBoolAsString(adminExempt), NULL);
  478. }
  479. }
  480. if (Concurrency) {
  481. ULONG concurrentTasks;
  482. WsbAffirmHr(pHsm->GetCopyFilesUserLimit(&concurrentTasks));
  483. WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_CONCURRENCY));
  484. swprintf(longData, OLESTR("%lu"), concurrentTasks);
  485. WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL);
  486. }
  487. if (MediaCopies) {
  488. CComPtr<IHsmStoragePool> pStoragePool;
  489. CComPtr<IWsbIndexedCollection> pCollection;
  490. ULONG count;
  491. USHORT numCopies;
  492. // Get the storage pools collection. There should only be one member.
  493. WsbAffirmHr(pHsm->GetStoragePools(&pCollection));
  494. WsbAffirmHr(pCollection->GetEntries(&count));
  495. WsbAffirm(1 == count, E_FAIL);
  496. WsbAffirmHr(pCollection->At(0, IID_IHsmStoragePool, (void **)&pStoragePool));
  497. WsbAffirmHr(pStoragePool->GetNumMediaCopies(&numCopies));
  498. WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_MEDIA_COPIES));
  499. swprintf(longData, OLESTR("%ld"), (int)numCopies);
  500. WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL);
  501. }
  502. } WsbCatchAndDo(hr,
  503. if(pDb) {
  504. pDb->Close(pDbSession);
  505. pDb = 0;
  506. }
  507. );
  508. // Free stored data
  509. if (pVolumesData) {
  510. for (ULONG i=0; i<volDataSize; i++) {
  511. if (pVolumesData[i].Name) {
  512. WsbFree(pVolumesData[i].Name);
  513. }
  514. }
  515. WsbFree(pVolumesData);
  516. pVolumesData = NULL;
  517. }
  518. if (pMediasData) {
  519. for (ULONG i=0; i<mediaDataSize; i++) {
  520. if (NULL != pMediasData[i]) {
  521. WsbFreeString(pMediasData[i]);
  522. }
  523. }
  524. WsbFree(pMediasData);
  525. pMediasData = NULL;
  526. }
  527. WsbTraceOut(OLESTR("AdminShow"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  528. return hr;
  529. }
  530. //
  531. // Internal utilities
  532. //
  533. HRESULT DisplayServiceStatus(void)
  534. /*++
  535. Routine Description:
  536. Displays HSM service status.
  537. Arguments:
  538. None
  539. Return Value:
  540. S_OK - If status is retrieved and displayed succeessfully
  541. Notes:
  542. The function handle cases such as the service not runnig, pending, not initialized, etc.
  543. --*/
  544. {
  545. HRESULT hr = S_OK;
  546. WsbTraceIn(OLESTR("DisplayServiceStatus"), OLESTR(""));
  547. try {
  548. CWsbStringPtr param, data;
  549. ULONG statusId = INVALID_DWORD_ARG;
  550. DWORD serviceStatus;
  551. HRESULT hrService;
  552. hrService = WsbGetServiceStatus(NULL, APPID_RemoteStorageEngine, &serviceStatus);
  553. if (S_OK != hrService) {
  554. // HSM service not registered at all
  555. WsbTrace(OLESTR("DisplayServiceStatus: Got hr = <%ls> from WsbGetServiceStatus\n"), WsbHrAsString(hrService));
  556. statusId = IDS_SERVICE_STATUS_NOT_REGISTERED;
  557. } else {
  558. if (SERVICE_RUNNING == serviceStatus) {
  559. CComPtr<IHsmServer> pHsm;
  560. HRESULT hrSetup;
  561. WsbAffirmHr(HsmConnectFromId(HSMCONN_TYPE_HSM, g_nullGuid, IID_IHsmServer, (void**)&pHsm));
  562. hrSetup = IsHsmInitialized(pHsm);
  563. if (S_FALSE == hrSetup) {
  564. // HSM running but no initialized yet (Startup Wizard was not completed yet)
  565. statusId = IDS_SERVICE_STATUS_NOT_SETUP;
  566. } else if (S_OK == hrSetup) {
  567. // Service is running, life is good
  568. statusId = IDS_SERVICE_STATUS_RUNNING;
  569. } else {
  570. // Unexpected error
  571. WsbAffirmHr(hrSetup);
  572. }
  573. } else {
  574. // Service is not running, set exact string according to status
  575. switch(serviceStatus) {
  576. case SERVICE_STOPPED:
  577. statusId = IDS_SERVICE_STATUS_STOPPED;
  578. break;
  579. case SERVICE_START_PENDING:
  580. statusId = IDS_SERVICE_STATUS_START_PENDING;
  581. break;
  582. case SERVICE_STOP_PENDING:
  583. statusId = IDS_SERVICE_STATUS_STOP_PENDING;
  584. break;
  585. case SERVICE_CONTINUE_PENDING:
  586. statusId = IDS_SERVICE_STATUS_CONTINUE_PENDING;
  587. break;
  588. case SERVICE_PAUSE_PENDING:
  589. statusId = IDS_SERVICE_STATUS_PAUSE_PENDING;
  590. break;
  591. case SERVICE_PAUSED:
  592. statusId = IDS_SERVICE_STATUS_PAUSED;
  593. break;
  594. default:
  595. WsbThrow(E_FAIL);
  596. }
  597. }
  598. }
  599. WsbAffirm(INVALID_DWORD_ARG != statusId, E_UNEXPECTED)
  600. WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_HSM_STATUS));
  601. WsbAffirmHr(data.LoadFromRsc(g_hInstance, statusId));
  602. WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, (WCHAR *)data, NULL);
  603. } WsbCatch(hr);
  604. WsbTraceOut(OLESTR("DisplayServiceStatus"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  605. return (hr);
  606. }
  607. HRESULT IsHsmInitialized(IN IHsmServer *pHsm)
  608. /*++
  609. Routine Description:
  610. Check if HSM is initialized, i.e. if Startup wizard was completed successfully
  611. Arguments:
  612. pHsm - The HSM server to check with
  613. Return Value:
  614. S_OK - HSM initialized
  615. S_FALSE - HSM not initialized
  616. --*/
  617. {
  618. HRESULT hr = S_FALSE;
  619. WsbTraceIn(OLESTR("IsHsmInitialized"), OLESTR(""));
  620. try {
  621. GUID guid;
  622. CWsbBstrPtr poolName;
  623. CComPtr<IWsbIndexedCollection> pCollection;
  624. ULONG count;
  625. CComPtr<IHsmStoragePool> pPool;
  626. WsbAffirmHr(pHsm->GetStoragePools(&pCollection));
  627. WsbAffirmHr(pCollection->GetEntries(&count));
  628. WsbAffirm(1 == count, E_FAIL);
  629. WsbAffirmHr(pCollection->At(0, IID_IHsmStoragePool, (void **)&pPool));
  630. WsbAffirmHr(pPool->GetMediaSet(&guid, &poolName));
  631. if(! IsEqualGUID(guid, GUID_NULL)) {
  632. hr = S_OK;
  633. }
  634. } WsbCatch(hr);
  635. WsbTraceOut(OLESTR("IsHsmInitialized"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  636. return (hr);
  637. }
  638. HRESULT AdminJob(IN BOOL Enable)
  639. /*++
  640. Routine Description:
  641. Enable/Disable HSM jobs
  642. Arguments:
  643. None
  644. Return Value:
  645. S_OK - Success
  646. HSM_E_DISABLE_RUNNING_JOBS - Returned by Engine when trying to disbale jobs
  647. while jobs are running
  648. Other - Other unexpected error
  649. --*/
  650. {
  651. HRESULT hr = S_FALSE;
  652. WsbTraceIn(OLESTR("AdminJob"), OLESTR(""));
  653. try {
  654. CComPtr<IHsmServer> pHsm;
  655. WsbAffirmHr(HsmConnectFromId(HSMCONN_TYPE_HSM, g_nullGuid, IID_IHsmServer, (void**)&pHsm));
  656. if (Enable) {
  657. hr = pHsm->EnableAllJobs();
  658. } else {
  659. hr = pHsm->DisableAllJobs();
  660. }
  661. } WsbCatch(hr);
  662. WsbTraceOut(OLESTR("AdminJob"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  663. return (hr);
  664. }