/*++ Copyright (c) 2000 Microsoft Corporation Module Name: cliadmin.cpp Abstract: Implements CLI ADMIN sub-interface Author: Ran Kalach [rankala] 3-March-2000 Revision History: --*/ #include "stdafx.h" #include "HsmConn.h" #include "engine.h" #include "rsstrdef.h" #include "mstask.h" static GUID g_nullGuid = GUID_NULL; // Internal utilities and classes for VOLUME interface HRESULT DisplayServiceStatus(void); HRESULT IsHsmInitialized(IN IHsmServer *pHsm); HRESULT AdminSet( IN DWORD RecallLimit, IN DWORD AdminExempt, IN DWORD MediaCopies, IN DWORD Concurrency, IN PVOID Schedule ) /*++ Routine Description: Sets Remote Storage general parameters Arguments: RecallLimit - The runaway recall limit to set AdminExempt - Whether to set administrators exempt for the recall limit MediaCopies - Number of media copy sets Concurrency - How many migrate jobs/recalls can be executed concurrently Schedule - The schedule for the global migration ("Manage") job of all managed volumes Return Value: S_OK - If all the parameters are set successfully Notes: The scheduling implementation of HSM (in the Engine) allows only one scheduling for the global Manage job. The scheduling given here overrides any former scheduling. However, the user can add another scheduling to the same task using the Task Scheduler UI. Enabling that via HSM, requires changing the CHsmServer::CreateTaskEx implementation --*/ { HRESULT hr = S_OK; WsbTraceIn(OLESTR("AdminSet"), OLESTR("")); try { CWsbStringPtr param; // Verify that input parameters are valid WsbAffirmHr(ValidateLimitsArg(RecallLimit, IDS_RECALL_LIMIT, HSMADMIN_MIN_RECALL_LIMIT, INVALID_DWORD_ARG)); WsbAffirmHr(ValidateLimitsArg(MediaCopies, IDS_MEDIA_COPIES_PRM, HSMADMIN_MIN_COPY_SETS, HSMADMIN_MAX_COPY_SETS)); WsbAffirmHr(ValidateLimitsArg(Concurrency, IDS_CONCURRENCY_PRM, HSMADMIN_MIN_CONCURRENT_TASKS, INVALID_DWORD_ARG)); // Set parameters, if an error occurs we abort if ((INVALID_DWORD_ARG != RecallLimit) || (INVALID_DWORD_ARG != AdminExempt)) { // Need Fsa server and Fsa filter here CComPtr pFsa; CComPtr pFsaFilter; WsbAffirmHr(HsmConnectFromId(HSMCONN_TYPE_FSA, g_nullGuid, IID_IFsaServer, (void**)&pFsa)); WsbAffirmHr(pFsa->GetFilter( &pFsaFilter)); // Recall limit if (INVALID_DWORD_ARG != RecallLimit) { WsbAffirmHr(pFsaFilter->SetMaxRecalls(RecallLimit)); } // Admin exempt if (INVALID_DWORD_ARG != AdminExempt) { BOOL bAdminExempt = (0 == AdminExempt) ? FALSE : TRUE; WsbAffirmHr(pFsaFilter->SetAdminExemption(bAdminExempt)); } } if ( (INVALID_DWORD_ARG != MediaCopies) || (INVALID_DWORD_ARG != Concurrency) || (INVALID_POINTER_ARG != Schedule) ) { // Need Hsm server CComPtr pHsm; WsbAffirmHr(HsmConnectFromId(HSMCONN_TYPE_HSM, g_nullGuid, IID_IHsmServer, (void**)&pHsm)); // Concurrency if (INVALID_DWORD_ARG != Concurrency) { WsbAffirmHr(pHsm->SetCopyFilesUserLimit(Concurrency)); } // Media copies if (INVALID_DWORD_ARG != MediaCopies) { CComPtr pStoragePool; CComPtr pCollection; ULONG count; // Get the storage pools collection. There should only be one member. WsbAffirmHr(pHsm->GetStoragePools(&pCollection)); WsbAffirmHr(pCollection->GetEntries(&count)); WsbAffirm(1 == count, E_FAIL); WsbAffirmHr(pCollection->At(0, IID_IHsmStoragePool, (void **)&pStoragePool)); WsbAffirmHr(pStoragePool->SetNumMediaCopies((USHORT)MediaCopies)); } // Scheduling if (INVALID_POINTER_ARG != Schedule) { CWsbStringPtr taskName, taskComment; TASK_TRIGGER_TYPE taskType; PHSM_JOB_SCHEDULE pSchedule = (PHSM_JOB_SCHEDULE)Schedule; SYSTEMTIME runTime; DWORD runOccurrence; // Set default valuess GetSystemTime(&runTime); runOccurrence = 0; // Set input switch (pSchedule->Frequency) { case Daily: taskType = TASK_TIME_TRIGGER_DAILY; runTime = pSchedule->Parameters.Daily.Time; runOccurrence = pSchedule->Parameters.Daily.Occurrence; break; case Weekly: taskType = TASK_TIME_TRIGGER_WEEKLY; runTime = pSchedule->Parameters.Weekly.Time; runOccurrence = pSchedule->Parameters.Weekly.Occurrence; break; case Monthly: taskType = TASK_TIME_TRIGGER_MONTHLYDATE; runTime = pSchedule->Parameters.Monthly.Time; break; case Once: taskType = TASK_TIME_TRIGGER_ONCE; runTime = pSchedule->Parameters.Once.Time; break; case WhenIdle: taskType = TASK_EVENT_TRIGGER_ON_IDLE; runOccurrence = pSchedule->Parameters.WhenIdle.Occurrence; break; case SystemStartup: taskType = TASK_EVENT_TRIGGER_AT_SYSTEMSTART; break; case Login: taskType = TASK_EVENT_TRIGGER_AT_LOGON; break; default: WsbThrow(E_INVALIDARG); } // Create the task with the new scheduling // Note: Task parameters should not be localized - this is a parameter for RsLaunch.exe WsbAffirmHr(WsbGetResourceString(IDS_HSM_SCHED_TASK_TITLE, &taskName)); WsbAffirmHr(WsbGetResourceString(IDS_HSM_SCHED_COMMENT, &taskComment)); WsbAffirmHr(pHsm->CreateTaskEx(taskName, L"run manage", taskComment, taskType, runTime, runOccurrence, TRUE)); } } } WsbCatch(hr); WsbTraceOut(OLESTR("AdminSet"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return hr; } // Local structure for AdminShow typedef struct _FSA_VOLUME_DATA { WCHAR *Name; BOOL Managed; } FSA_VOLUME_DATA, *PFSA_VOLUME_DATA; #define DATA_ALLOC_SIZE 10 HRESULT AdminShow( IN BOOL RecallLimit, IN BOOL AdminExempt, IN BOOL MediaCopies, IN BOOL Concurrency, IN BOOL Schedule, IN BOOL General, IN BOOL Manageables, IN BOOL Managed, IN BOOL Media ) /*++ Routine Description: Shows (prints to stdout) Remote Storage general parameters Arguments: RecallLimit - The runaway recall limit AdminExempt - Whether administrators are exempt from the recall limit MediaCopies - Number of media copy sets Concurrency - How many migrate jobs/recalls can be executed concurrently Schedule - The schedule for the global migration ("Manage") job of all managed volumes General - General information: version, status, number of volumes managed, number of tape cartridges used, data in remote storage Manageables - List of volumes that may be managed by HSM Managed - List of volumes that are managed by HSM Media - List of medias that are allocated to HSM Return Value: S_OK - If all the required parameters are printed successfully Notes: The schedule is printed in a form of a list (like the volume list), not like a single parameter. The reason is that a user can specify several schedules for the global Manage job. --*/ { HRESULT hr = S_OK; // Volume saved data PFSA_VOLUME_DATA pVolumesData = NULL; ULONG volDataSize = 0; // Media save data BSTR* pMediasData = NULL; ULONG mediaDataSize = 0; CComPtr pDb; CComPtr pDbSession; WsbTraceIn(OLESTR("AdminShow"), OLESTR("")); try { CComPtr pFsa; CComPtr pHsm; CWsbStringPtr param; CWsbStringPtr data; WCHAR longData[100]; LPVOID pTemp; // Volume data LONGLONG dataInStorage = 0; ULONG manageableCount = 0; ULONG managedCount = 0; // Media data ULONG mediaAllocated = 0; // Get required HSM servers if (RecallLimit || AdminExempt || Manageables || Managed || General) { // Need Fsa server hr = HsmConnectFromId(HSMCONN_TYPE_FSA, g_nullGuid, IID_IFsaServer, (void**)&pFsa); if (S_OK != hr) { // Just print status before aborting if (General) { DisplayServiceStatus(); } } WsbAffirmHr(hr); } if (MediaCopies || Concurrency || General || Media) { // Need Hsm (Engine) server hr = HsmConnectFromId(HSMCONN_TYPE_HSM, g_nullGuid, IID_IHsmServer, (void**)&pHsm); if (S_OK != hr) { // Just print status before aborting if (General) { DisplayServiceStatus(); } } WsbAffirmHr(hr); } // // Get basic information required according to the input settings // // Volumes data if (General || Manageables || Managed) { // Need to collect volumes information CComPtr pEnum; CComPtr pResource; HRESULT hrEnum; BOOL bManaged; LONGLONG totalSpace = 0; LONGLONG freeSpace = 0; LONGLONG premigrated = 0; LONGLONG truncated = 0; LONGLONG totalPremigrated = 0; LONGLONG totalTruncated = 0; WsbAffirmHr(pFsa->EnumResources(&pEnum)); hrEnum = pEnum->First(IID_IFsaResource, (void**)&pResource); WsbAffirm((S_OK == hrEnum) || (WSB_E_NOTFOUND == hrEnum), hrEnum); if (Manageables || Managed) { volDataSize = DATA_ALLOC_SIZE; pVolumesData = (PFSA_VOLUME_DATA)WsbAlloc(volDataSize * sizeof(FSA_VOLUME_DATA)); WsbAffirm(0 != pVolumesData, E_OUTOFMEMORY); } while(S_OK == hrEnum) { // Don't count or display unavailable volumes if (S_OK != pResource->IsAvailable()) { goto skip_volume; } bManaged = (pResource->IsManaged() == S_OK); if (Manageables) { if (volDataSize == manageableCount) { volDataSize += DATA_ALLOC_SIZE; pTemp = WsbRealloc(pVolumesData, volDataSize * sizeof(FSA_VOLUME_DATA)); WsbAffirm(0 != pTemp, E_OUTOFMEMORY); pVolumesData = (PFSA_VOLUME_DATA)pTemp; } pVolumesData[manageableCount].Name = NULL; WsbAffirmHr(CliGetVolumeDisplayName(pResource, &(pVolumesData[manageableCount].Name))); pVolumesData[manageableCount].Managed = bManaged; } manageableCount++; if(bManaged) { if (General) { WsbAffirmHr(pResource->GetSizes(&totalSpace, &freeSpace, &premigrated, &truncated)); totalPremigrated += premigrated; totalTruncated += truncated; } if (Managed && (!Manageables)) { // Collect data only for managed volumes if (volDataSize == managedCount) { volDataSize += DATA_ALLOC_SIZE; pTemp = WsbRealloc(pVolumesData, volDataSize * sizeof(FSA_VOLUME_DATA)); WsbAffirm(0 != pTemp, E_OUTOFMEMORY); pVolumesData = (PFSA_VOLUME_DATA)pTemp; } pVolumesData[managedCount].Name = NULL; WsbAffirmHr(CliGetVolumeDisplayName(pResource, &(pVolumesData[managedCount].Name))); pVolumesData[managedCount].Managed = TRUE; } managedCount++; } skip_volume: // Prepare for next iteration pResource = 0; hrEnum = pEnum->Next( IID_IFsaResource, (void**)&pResource ); } if (Manageables) { volDataSize = manageableCount; } else if (Managed) { volDataSize = managedCount; } if (General) { dataInStorage = totalPremigrated + totalTruncated; } } // Medias data if (General || Media) { CComPtr pMediaInfo; GUID mediaSubsystemId; CComPtr pRms; CComPtr pRmsCart; HRESULT hrFind; WsbAffirmHr(pHsm->GetHsmMediaMgr(&pRms)); WsbAffirmHr(pHsm->GetSegmentDb(&pDb)); WsbAffirmHr(pDb->Open(&pDbSession)); WsbAffirmHr(pDb->GetEntity(pDbSession, HSM_MEDIA_INFO_REC_TYPE, IID_IMediaInfo, (void**)&pMediaInfo)); if (Media) { mediaDataSize = DATA_ALLOC_SIZE; pMediasData = (BSTR *)WsbAlloc(mediaDataSize * sizeof(BSTR)); WsbAffirm(0 != mediaDataSize, E_OUTOFMEMORY); } for (hr = pMediaInfo->First(); S_OK == hr; hr = pMediaInfo->Next()) { WsbAffirmHr(pMediaInfo->GetMediaSubsystemId(&mediaSubsystemId)); hrFind = pRms->FindCartridgeById(mediaSubsystemId, &pRmsCart); if (S_OK == hrFind) { // Otherwise, the media is not valid anymore, it could have been deallocated if (Media) { if (mediaDataSize == mediaAllocated) { mediaDataSize += DATA_ALLOC_SIZE; pTemp = WsbRealloc(pMediasData, mediaDataSize * sizeof(BSTR)); WsbAffirm(0 != pTemp, E_OUTOFMEMORY); pMediasData = (BSTR *)pTemp; } pMediasData[mediaAllocated] = NULL; WsbAffirmHr(pRmsCart->GetName(&(pMediasData[mediaAllocated]))); if ( (NULL == pMediasData[mediaAllocated]) || (0 == wcscmp(pMediasData[mediaAllocated], OLESTR(""))) ) { // Try decsription if (NULL != pMediasData[mediaAllocated]) { WsbFreeString(pMediasData[mediaAllocated]); } WsbAffirmHr(pRmsCart->GetDescription(&(pMediasData[mediaAllocated]))); } } mediaAllocated++; pRmsCart = 0; } } if (Media) { mediaDataSize = mediaAllocated; } hr = S_OK; if(pDb) { pDb->Close(pDbSession); pDb = 0; } } // // Print parameters // // General parameters if (General) { WsbTraceAndPrint(CLI_MESSAGE_GENERAL_PARMS, NULL); // Status WsbAffirmHr(DisplayServiceStatus()); // Manageable && Managed WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_NOF_MANAGEABLES)); swprintf(longData, OLESTR("%lu"), manageableCount); WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL); WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_NOF_MANAGED)); swprintf(longData, OLESTR("%lu"), managedCount); WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL); // Tapes WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_NOF_CARTRIDGES)); swprintf(longData, OLESTR("%lu"), mediaAllocated); WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL); // Data in RS WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_REMOTE_DATA)); WsbAffirmHr(ShortSizeFormat64(dataInStorage, longData)); WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL); // Version { CComPtr pWsbHsm; CWsbStringPtr ntProductVersionHsm; ULONG ntProductBuildHsm; ULONG buildVersionHsm; WsbAffirmHr(pHsm->QueryInterface(IID_IWsbServer, (void **)&pWsbHsm)); WsbAffirmHr(pWsbHsm->GetNtProductBuild(&ntProductBuildHsm)); WsbAffirmHr(pWsbHsm->GetNtProductVersion(&ntProductVersionHsm, 0)); WsbAffirmHr(pWsbHsm->GetBuildVersion(&buildVersionHsm)); WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_HSM_VERSION)); WsbAffirmHr(data.Realloc(wcslen(ntProductVersionHsm) + 30)); swprintf(data, L"%ls.%d [%ls]", (WCHAR*)ntProductVersionHsm, ntProductBuildHsm, RsBuildVersionAsString(buildVersionHsm)); WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, (WCHAR *)data, NULL); } } // Manageable volumes if (Manageables) { WsbTraceAndPrint(CLI_MESSAGE_MANAGEABLE_VOLS, NULL); for (ULONG i=0; i pSchedAgent; CComPtr pTask; CWsbStringPtr manageJobName; // Initialize scheduling agent WsbAffirmHr(CoCreateInstance(CLSID_CSchedulingAgent, 0, CLSCTX_SERVER, IID_ISchedulingAgent, (void **)&pSchedAgent)); pSchedAgent->SetTargetComputer(NULL); // local machine // Get the relevant task WsbAffirmHr(WsbGetResourceString(IDS_HSM_SCHED_TASK_TITLE, &manageJobName)); hr = pSchedAgent->Activate(manageJobName, IID_ITask, (IUnknown**)&pTask); if (E_INVALIDARG == hr) { // Print no scheduling message (Manage job is not found as a scheduled task) WsbTraceAndPrint(CLI_MESSAGE_NO_SCHEDULING, NULL); hr = S_OK; } else if (S_OK == hr) { // Get scheduling strings and print WORD wTriggerCount; WsbAffirmHr(pTask->GetTriggerCount(&wTriggerCount)); if (wTriggerCount == 0) { WsbTraceAndPrint(CLI_MESSAGE_NO_SCHEDULING, NULL); } else { WsbTraceAndPrint(CLI_MESSAGE_SCHEDULING_LIST, NULL); } for (WORD triggerIndex = 0; triggerIndex < wTriggerCount; triggerIndex++) { WCHAR *pTriggerString = NULL; WsbAffirmHr(pTask->GetTriggerString(triggerIndex, &pTriggerString)); // Print WsbTraceAndPrint(CLI_MESSAGE_VALUE_DISPLAY, pTriggerString, NULL); CoTaskMemFree(pTriggerString); } } else { WsbAffirmHr(hr); } } // Limits and Media Copies if (RecallLimit || AdminExempt) { // Need Fsa filter here CComPtr pFsaFilter; WsbAffirmHr(pFsa->GetFilter(&pFsaFilter)); if (RecallLimit) { ULONG maxRecalls; WsbAffirmHr(pFsaFilter->GetMaxRecalls(&maxRecalls)); WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_RECALL_LIMIT)); swprintf(longData, OLESTR("%lu"), maxRecalls); WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL); } if (AdminExempt) { BOOL adminExempt; WsbAffirmHr(pFsaFilter->GetAdminExemption(&adminExempt)); WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_ADMIN_EXEMPT)); WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, WsbBoolAsString(adminExempt), NULL); } } if (Concurrency) { ULONG concurrentTasks; WsbAffirmHr(pHsm->GetCopyFilesUserLimit(&concurrentTasks)); WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_CONCURRENCY)); swprintf(longData, OLESTR("%lu"), concurrentTasks); WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL); } if (MediaCopies) { CComPtr pStoragePool; CComPtr pCollection; ULONG count; USHORT numCopies; // Get the storage pools collection. There should only be one member. WsbAffirmHr(pHsm->GetStoragePools(&pCollection)); WsbAffirmHr(pCollection->GetEntries(&count)); WsbAffirm(1 == count, E_FAIL); WsbAffirmHr(pCollection->At(0, IID_IHsmStoragePool, (void **)&pStoragePool)); WsbAffirmHr(pStoragePool->GetNumMediaCopies(&numCopies)); WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_MEDIA_COPIES)); swprintf(longData, OLESTR("%ld"), (int)numCopies); WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, longData, NULL); } } WsbCatchAndDo(hr, if(pDb) { pDb->Close(pDbSession); pDb = 0; } ); // Free stored data if (pVolumesData) { for (ULONG i=0; i"), WsbHrAsString(hr)); return hr; } // // Internal utilities // HRESULT DisplayServiceStatus(void) /*++ Routine Description: Displays HSM service status. Arguments: None Return Value: S_OK - If status is retrieved and displayed succeessfully Notes: The function handle cases such as the service not runnig, pending, not initialized, etc. --*/ { HRESULT hr = S_OK; WsbTraceIn(OLESTR("DisplayServiceStatus"), OLESTR("")); try { CWsbStringPtr param, data; ULONG statusId = INVALID_DWORD_ARG; DWORD serviceStatus; HRESULT hrService; hrService = WsbGetServiceStatus(NULL, APPID_RemoteStorageEngine, &serviceStatus); if (S_OK != hrService) { // HSM service not registered at all WsbTrace(OLESTR("DisplayServiceStatus: Got hr = <%ls> from WsbGetServiceStatus\n"), WsbHrAsString(hrService)); statusId = IDS_SERVICE_STATUS_NOT_REGISTERED; } else { if (SERVICE_RUNNING == serviceStatus) { CComPtr pHsm; HRESULT hrSetup; WsbAffirmHr(HsmConnectFromId(HSMCONN_TYPE_HSM, g_nullGuid, IID_IHsmServer, (void**)&pHsm)); hrSetup = IsHsmInitialized(pHsm); if (S_FALSE == hrSetup) { // HSM running but no initialized yet (Startup Wizard was not completed yet) statusId = IDS_SERVICE_STATUS_NOT_SETUP; } else if (S_OK == hrSetup) { // Service is running, life is good statusId = IDS_SERVICE_STATUS_RUNNING; } else { // Unexpected error WsbAffirmHr(hrSetup); } } else { // Service is not running, set exact string according to status switch(serviceStatus) { case SERVICE_STOPPED: statusId = IDS_SERVICE_STATUS_STOPPED; break; case SERVICE_START_PENDING: statusId = IDS_SERVICE_STATUS_START_PENDING; break; case SERVICE_STOP_PENDING: statusId = IDS_SERVICE_STATUS_STOP_PENDING; break; case SERVICE_CONTINUE_PENDING: statusId = IDS_SERVICE_STATUS_CONTINUE_PENDING; break; case SERVICE_PAUSE_PENDING: statusId = IDS_SERVICE_STATUS_PAUSE_PENDING; break; case SERVICE_PAUSED: statusId = IDS_SERVICE_STATUS_PAUSED; break; default: WsbThrow(E_FAIL); } } } WsbAffirm(INVALID_DWORD_ARG != statusId, E_UNEXPECTED) WsbAffirmHr(param.LoadFromRsc(g_hInstance, IDS_HSM_STATUS)); WsbAffirmHr(data.LoadFromRsc(g_hInstance, statusId)); WsbTraceAndPrint(CLI_MESSAGE_PARAM_DISPLAY, (WCHAR *)param, (WCHAR *)data, NULL); } WsbCatch(hr); WsbTraceOut(OLESTR("DisplayServiceStatus"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return (hr); } HRESULT IsHsmInitialized(IN IHsmServer *pHsm) /*++ Routine Description: Check if HSM is initialized, i.e. if Startup wizard was completed successfully Arguments: pHsm - The HSM server to check with Return Value: S_OK - HSM initialized S_FALSE - HSM not initialized --*/ { HRESULT hr = S_FALSE; WsbTraceIn(OLESTR("IsHsmInitialized"), OLESTR("")); try { GUID guid; CWsbBstrPtr poolName; CComPtr pCollection; ULONG count; CComPtr pPool; WsbAffirmHr(pHsm->GetStoragePools(&pCollection)); WsbAffirmHr(pCollection->GetEntries(&count)); WsbAffirm(1 == count, E_FAIL); WsbAffirmHr(pCollection->At(0, IID_IHsmStoragePool, (void **)&pPool)); WsbAffirmHr(pPool->GetMediaSet(&guid, &poolName)); if(! IsEqualGUID(guid, GUID_NULL)) { hr = S_OK; } } WsbCatch(hr); WsbTraceOut(OLESTR("IsHsmInitialized"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return (hr); } HRESULT AdminJob(IN BOOL Enable) /*++ Routine Description: Enable/Disable HSM jobs Arguments: None Return Value: S_OK - Success HSM_E_DISABLE_RUNNING_JOBS - Returned by Engine when trying to disbale jobs while jobs are running Other - Other unexpected error --*/ { HRESULT hr = S_FALSE; WsbTraceIn(OLESTR("AdminJob"), OLESTR("")); try { CComPtr pHsm; WsbAffirmHr(HsmConnectFromId(HSMCONN_TYPE_HSM, g_nullGuid, IID_IHsmServer, (void**)&pHsm)); if (Enable) { hr = pHsm->EnableAllJobs(); } else { hr = pHsm->DisableAllJobs(); } } WsbCatch(hr); WsbTraceOut(OLESTR("AdminJob"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return (hr); }