/** * List host information. * * @returns See produceList. * @param pVirtualBox Reference to the IVirtualBox smart pointer. */ static HRESULT listHostInfo(const ComPtr<IVirtualBox> pVirtualBox) { HRESULT rc; ComPtr<IHost> Host; CHECK_ERROR(pVirtualBox, COMGETTER(Host)(Host.asOutParam())); RTPrintf("Host Information:\n\n"); LONG64 u64UtcTime = 0; CHECK_ERROR(Host, COMGETTER(UTCTime)(&u64UtcTime)); RTTIMESPEC timeSpec; char szTime[32]; RTPrintf("Host time: %s\n", RTTimeSpecToString(RTTimeSpecSetMilli(&timeSpec, u64UtcTime), szTime, sizeof(szTime))); ULONG processorOnlineCount = 0; CHECK_ERROR(Host, COMGETTER(ProcessorOnlineCount)(&processorOnlineCount)); RTPrintf("Processor online count: %lu\n", processorOnlineCount); ULONG processorCount = 0; CHECK_ERROR(Host, COMGETTER(ProcessorCount)(&processorCount)); RTPrintf("Processor count: %lu\n", processorCount); ULONG processorOnlineCoreCount = 0; CHECK_ERROR(Host, COMGETTER(ProcessorOnlineCoreCount)(&processorOnlineCoreCount)); RTPrintf("Processor online core count: %lu\n", processorOnlineCoreCount); ULONG processorCoreCount = 0; CHECK_ERROR(Host, COMGETTER(ProcessorCoreCount)(&processorCoreCount)); RTPrintf("Processor core count: %lu\n", processorCoreCount); ULONG processorSpeed = 0; Bstr processorDescription; for (ULONG i = 0; i < processorCount; i++) { CHECK_ERROR(Host, GetProcessorSpeed(i, &processorSpeed)); if (processorSpeed) RTPrintf("Processor#%u speed: %lu MHz\n", i, processorSpeed); else RTPrintf("Processor#%u speed: unknown\n", i); CHECK_ERROR(Host, GetProcessorDescription(i, processorDescription.asOutParam())); RTPrintf("Processor#%u description: %ls\n", i, processorDescription.raw()); } ULONG memorySize = 0; CHECK_ERROR(Host, COMGETTER(MemorySize)(&memorySize)); RTPrintf("Memory size: %lu MByte\n", memorySize); ULONG memoryAvailable = 0; CHECK_ERROR(Host, COMGETTER(MemoryAvailable)(&memoryAvailable)); RTPrintf("Memory available: %lu MByte\n", memoryAvailable); Bstr operatingSystem; CHECK_ERROR(Host, COMGETTER(OperatingSystem)(operatingSystem.asOutParam())); RTPrintf("Operating system: %ls\n", operatingSystem.raw()); Bstr oSVersion; CHECK_ERROR(Host, COMGETTER(OSVersion)(oSVersion.asOutParam())); RTPrintf("Operating system version: %ls\n", oSVersion.raw()); return rc; }
/** * Issued by the guest when a guest user changed its state. * * @return IPRT status code. * @param aUser Guest user name. * @param aDomain Domain of guest user account. Optional. * @param enmState New state to indicate. * @param pbDetails Pointer to state details. Optional. * @param cbDetails Size (in bytes) of state details. Pass 0 if not used. */ void Guest::i_onUserStateChange(Bstr aUser, Bstr aDomain, VBoxGuestUserState enmState, const uint8_t *pbDetails, uint32_t cbDetails) { LogFlowThisFunc(("\n")); AutoCaller autoCaller(this); AssertComRCReturnVoid(autoCaller.rc()); Bstr strDetails; /** @todo Implement state details here. */ fireGuestUserStateChangedEvent(mEventSource, aUser.raw(), aDomain.raw(), (GuestUserState_T)enmState, strDetails.raw()); LogFlowFuncLeave(); }
static void listAffectedMetrics(ComPtr<IVirtualBox> aVirtualBox, ComSafeArrayIn(IPerformanceMetric*, aMetrics)) { HRESULT rc; com::SafeIfaceArray<IPerformanceMetric> metrics(ComSafeArrayInArg(aMetrics)); if (metrics.size()) { ComPtr<IUnknown> object; Bstr metricName; RTPrintf("The following metrics were modified:\n\n" "Object Metric\n" "---------- --------------------\n"); for (size_t i = 0; i < metrics.size(); i++) { CHECK_ERROR(metrics[i], COMGETTER(Object)(object.asOutParam())); CHECK_ERROR(metrics[i], COMGETTER(MetricName)(metricName.asOutParam())); RTPrintf("%-10ls %-20ls\n", getObjectName(aVirtualBox, object).raw(), metricName.raw()); } RTPrintf("\n"); } else { RTMsgError("No metrics match the specified filter!"); } }
/** * Sets the Guest Additions version information details. * Gets called by vmmdevUpdateGuestInfo2. * * @param aAdditionsVersion * @param aVersionName */ void Guest::setAdditionsInfo2(Bstr aAdditionsVersion, Bstr aVersionName, Bstr aRevision) { AutoCaller autoCaller(this); AssertComRCReturnVoid(autoCaller.rc()); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); if (!aVersionName.isEmpty()) /* * aVersionName could be "x.y.z_BETA1_FOOBAR", so append revision manually to * become "x.y.z_BETA1_FOOBAR r12345". */ mData.mAdditionsVersion = BstrFmt("%ls r%ls", aVersionName.raw(), aRevision.raw()); else /* aAdditionsVersion is in x.y.zr12345 format. */ mData.mAdditionsVersion = aAdditionsVersion; }
static RTEXITCODE handleCreate(HandlerArg *a) { /* * Parse input. */ RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, a->argc, a->argv, NULL, 0, 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); int ch = RTGetOpt(&GetState, &ValueUnion); if (ch != 0) return errorGetOpt(USAGE_HOSTONLYIFS, ch, &ValueUnion); /* * Do the work. */ ComPtr<IHost> host; CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE); ComPtr<IHostNetworkInterface> hif; ComPtr<IProgress> progress; CHECK_ERROR2I_RET(host, CreateHostOnlyNetworkInterface(hif.asOutParam(), progress.asOutParam()), RTEXITCODE_FAILURE); /*HRESULT hrc =*/ showProgress(progress); CHECK_PROGRESS_ERROR_RET(progress, ("Failed to create the host-only adapter"), RTEXITCODE_FAILURE); Bstr bstrName; CHECK_ERROR2I(hif, COMGETTER(Name)(bstrName.asOutParam())); RTPrintf("Interface '%ls' was successfully created\n", bstrName.raw()); return RTEXITCODE_SUCCESS; }
/** * Helper function used with "VBoxManage snapshot ... dump". Called from DumpSnapshot() * for each hard disk attachment found in a virtual machine. This then writes out the * root (base) medium for that hard disk attachment and recurses into the children * tree of that medium, correlating it with the snapshots of the machine. * @param pCurrentStateMedium constant, the medium listed in the current machine data (latest diff image). * @param pMedium variant, initially the base medium, then a child of the base medium when recursing. * @param pRootSnapshot constant, the root snapshot of the machine, if any; this then looks into the child snapshots. * @param pCurrentSnapshot constant, the machine's current snapshot (so we can mark it in the output). * @param uLevel variant, the recursion level for output indentation. */ void DumpMediumWithChildren(ComPtr<IMedium> &pCurrentStateMedium, ComPtr<IMedium> &pMedium, ComPtr<ISnapshot> &pRootSnapshot, ComPtr<ISnapshot> &pCurrentSnapshot, uint32_t uLevel) { HRESULT rc; do { // print this medium Bstr bstrMediumName; CHECK_ERROR_BREAK(pMedium, COMGETTER(Name)(bstrMediumName.asOutParam())); RTPrintf("%*s \"%ls\"%s\n", uLevel * 2, "", // indent bstrMediumName.raw(), (pCurrentStateMedium == pMedium) ? " (CURSTATE)" : ""); // find and print the snapshot that uses this particular medium (diff image) FindAndPrintSnapshotUsingMedium(pMedium, pRootSnapshot, pCurrentSnapshot, uLevel, 0); // recurse into children SafeIfaceArray<IMedium> aChildren; CHECK_ERROR_BREAK(pMedium, COMGETTER(Children)(ComSafeArrayAsOutParam(aChildren))); for (uint32_t i = 0; i < aChildren.size(); ++i) { ComPtr<IMedium> pChild(aChildren[i]); DumpMediumWithChildren(pCurrentStateMedium, pChild, pRootSnapshot, pCurrentSnapshot, uLevel + 1); } } while (0); }
/** * @interface_method_impl{PDMIPCIRAWUP,pfnPciDeviceConstructComplete} */ DECLCALLBACK(int) PCIRawDev::drvDeviceConstructComplete(PPDMIPCIRAWCONNECTOR pInterface, const char *pcszName, uint32_t uHostPCIAddress, uint32_t uGuestPCIAddress, int rc) { PDRVMAINPCIRAWDEV pThis = RT_FROM_CPP_MEMBER(pInterface, DRVMAINPCIRAWDEV, IConnector); Console *pConsole = pThis->pPCIRawDev->getParent(); const ComPtr<IMachine>& machine = pConsole->machine(); ComPtr<IVirtualBox> vbox; HRESULT hrc = machine->COMGETTER(Parent)(vbox.asOutParam()); Assert(SUCCEEDED(hrc)); ComPtr<IEventSource> es; hrc = vbox->COMGETTER(EventSource)(es.asOutParam()); Assert(SUCCEEDED(hrc)); Bstr bstrId; hrc = machine->COMGETTER(Id)(bstrId.asOutParam()); Assert(SUCCEEDED(hrc)); ComObjPtr<PCIDeviceAttachment> pda; BstrFmt bstrName(pcszName); pda.createObject(); pda->init(machine, bstrName, uHostPCIAddress, uGuestPCIAddress, TRUE); Bstr msg(""); if (RT_FAILURE(rc)) msg = BstrFmt("runtime error %Rrc", rc); fireHostPCIDevicePlugEvent(es, bstrId.raw(), true /* plugged */, RT_SUCCESS(rc) /* success */, pda, msg.raw()); return VINF_SUCCESS; }
static int vmListBuild() { serviceLogVerbose(("Building VM list ...\n")); int rc = RTCritSectEnter(&g_csMachines); if (RT_SUCCESS(rc)) { /* * Make sure the list is empty. */ g_mapVM.clear(); /* * Get the list of all _running_ VMs */ com::SafeIfaceArray<IMachine> machines; HRESULT hrc = g_pVirtualBox->COMGETTER(Machines)(ComSafeArrayAsOutParam(machines)); if (SUCCEEDED(hrc)) { /* * Iterate through the collection */ for (size_t i = 0; i < machines.size(); ++i) { if (machines[i]) { Bstr strUUID; CHECK_ERROR_BREAK(machines[i], COMGETTER(Id)(strUUID.asOutParam())); BOOL fAccessible; CHECK_ERROR_BREAK(machines[i], COMGETTER(Accessible)(&fAccessible)); if (!fAccessible) { serviceLogVerbose(("Machine \"%ls\" is inaccessible, skipping\n", strUUID.raw())); continue; } rc = machineAdd(strUUID); if (RT_FAILURE(rc)) break; } } if (!machines.size()) serviceLogVerbose(("No machines to add found at the moment!\n")); } int rc2 = RTCritSectLeave(&g_csMachines); if (RT_SUCCESS(rc)) rc = rc2; } return rc; }
static int handleGetGuestProperty(HandlerArg *a) { HRESULT rc = S_OK; bool verbose = false; if ( a->argc == 3 && ( !strcmp(a->argv[2], "--verbose") || !strcmp(a->argv[2], "-verbose"))) verbose = true; else if (a->argc != 2) return errorSyntax(USAGE_GUESTPROPERTY, "Incorrect parameters"); ComPtr<IMachine> machine; CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), machine.asOutParam())); if (machine) { /* open a session for the VM - new or existing */ CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1); /* get the mutable session machine */ a->session->COMGETTER(Machine)(machine.asOutParam()); Bstr value; LONG64 i64Timestamp; Bstr flags; CHECK_ERROR(machine, GetGuestProperty(Bstr(a->argv[1]).raw(), value.asOutParam(), &i64Timestamp, flags.asOutParam())); if (value.isEmpty()) RTPrintf("No value set!\n"); else RTPrintf("Value: %ls\n", value.raw()); if (!value.isEmpty() && verbose) { RTPrintf("Timestamp: %lld\n", i64Timestamp); RTPrintf("Flags: %ls\n", flags.raw()); } } return SUCCEEDED(rc) ? 0 : 1; }
/** * List video capture devices. * * @returns See produceList. * @param pVirtualBox Reference to the IVirtualBox pointer. */ static HRESULT listVideoInputDevices(const ComPtr<IVirtualBox> pVirtualBox) { HRESULT rc; ComPtr<IHost> host; CHECK_ERROR(pVirtualBox, COMGETTER(Host)(host.asOutParam())); com::SafeIfaceArray<IHostVideoInputDevice> hostVideoInputDevices; CHECK_ERROR(host, COMGETTER(VideoInputDevices)(ComSafeArrayAsOutParam(hostVideoInputDevices))); RTPrintf("Video Input Devices: %u\n", hostVideoInputDevices.size()); for (size_t i = 0; i < hostVideoInputDevices.size(); ++i) { ComPtr<IHostVideoInputDevice> p = hostVideoInputDevices[i]; Bstr name; p->COMGETTER(Name)(name.asOutParam()); Bstr path; p->COMGETTER(Path)(path.asOutParam()); Bstr alias; p->COMGETTER(Alias)(alias.asOutParam()); RTPrintf("%ls \"%ls\"\n%ls\n", alias.raw(), name.raw(), path.raw()); } return rc; }
RTEXITCODE handleUSBDevSource(HandlerArg *a) { HRESULT rc = S_OK; /* at least: 0: command, 1: source id */ if (a->argc < 2) return errorSyntax(USAGE_USBDEVSOURCE, "Not enough parameters"); ComPtr<IHost> host; if (!strcmp(a->argv[0], "add")) { Bstr strBackend; Bstr strAddress; if (a->argc != 6) return errorSyntax(USAGE_USBDEVSOURCE, "Invalid number of parameters"); for (int i = 2; i < a->argc; i++) { if (!strcmp(a->argv[i], "--backend")) { i++; strBackend = a->argv[i]; } else if (!strcmp(a->argv[i], "--address")) { i++; strAddress = a->argv[i]; } else return errorSyntax(USAGE_USBDEVSOURCE, "Parameter \"%s\" is invalid", a->argv[i]); } SafeArray<BSTR> usbSourcePropNames; SafeArray<BSTR> usbSourcePropValues; CHECK_ERROR_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE); CHECK_ERROR_RET(host, AddUSBDeviceSource(strBackend.raw(), Bstr(a->argv[1]).raw(), strAddress.raw(), ComSafeArrayAsInParam(usbSourcePropNames), ComSafeArrayAsInParam(usbSourcePropValues)), RTEXITCODE_FAILURE); } else if (!strcmp(a->argv[0], "remove")) { CHECK_ERROR_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE); CHECK_ERROR_RET(host, RemoveUSBDeviceSource(Bstr(a->argv[1]).raw()), RTEXITCODE_FAILURE); } return SUCCEEDED(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; }
void GluePrintErrorInfo(const com::ErrorInfo &info) { bool haveResultCode = false; #if defined (RT_OS_WIN) haveResultCode = info.isFullAvailable(); bool haveComponent = true; bool haveInterfaceID = true; #else /* defined (RT_OS_WIN) */ haveResultCode = true; bool haveComponent = info.isFullAvailable(); bool haveInterfaceID = info.isFullAvailable(); #endif Utf8Str str; RTCList<Utf8Str> comp; Bstr bstrDetailsText = info.getText(); if (!bstrDetailsText.isEmpty()) str = Utf8StrFmt("%ls\n", bstrDetailsText.raw()); if (haveResultCode) comp.append(Utf8StrFmt("code %Rhrc (0x%RX32)", info.getResultCode(), info.getResultCode())); if (haveComponent) comp.append(Utf8StrFmt("component %ls", info.getComponent().raw())); if (haveInterfaceID) comp.append(Utf8StrFmt("interface %ls", info.getInterfaceName().raw())); if (!info.getCalleeName().isEmpty()) comp.append(Utf8StrFmt("callee %ls", info.getCalleeName().raw())); if (comp.size() > 0) { str += "Details: "; for (size_t i = 0; i < comp.size() - 1; ++i) str += comp.at(i) + ", "; str += comp.last(); str += "\n"; } // print and log RTMsgError("%s", str.c_str()); Log(("ERROR: %s", str.c_str())); }
/** * List extension packs. * * @returns See produceList. * @param pVirtualBox Reference to the IVirtualBox smart pointer. */ static HRESULT listExtensionPacks(const ComPtr<IVirtualBox> &pVirtualBox) { ComObjPtr<IExtPackManager> ptrExtPackMgr; CHECK_ERROR2_RET(pVirtualBox, COMGETTER(ExtensionPackManager)(ptrExtPackMgr.asOutParam()), hrcCheck); SafeIfaceArray<IExtPack> extPacks; CHECK_ERROR2_RET(ptrExtPackMgr, COMGETTER(InstalledExtPacks)(ComSafeArrayAsOutParam(extPacks)), hrcCheck); RTPrintf("Extension Packs: %u\n", extPacks.size()); HRESULT hrc = S_OK; for (size_t i = 0; i < extPacks.size(); i++) { /* Read all the properties. */ Bstr bstrName; CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Name)(bstrName.asOutParam()), hrc = hrcCheck; bstrName.setNull()); Bstr bstrDesc; CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Description)(bstrDesc.asOutParam()), hrc = hrcCheck; bstrDesc.setNull()); Bstr bstrVersion; CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Version)(bstrVersion.asOutParam()), hrc = hrcCheck; bstrVersion.setNull()); ULONG uRevision; CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Revision)(&uRevision), hrc = hrcCheck; uRevision = 0); Bstr bstrEdition; CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Edition)(bstrEdition.asOutParam()), hrc = hrcCheck; bstrEdition.setNull()); Bstr bstrVrdeModule; CHECK_ERROR2_STMT(extPacks[i], COMGETTER(VRDEModule)(bstrVrdeModule.asOutParam()),hrc=hrcCheck; bstrVrdeModule.setNull()); BOOL fUsable; CHECK_ERROR2_STMT(extPacks[i], COMGETTER(Usable)(&fUsable), hrc = hrcCheck; fUsable = FALSE); Bstr bstrWhy; CHECK_ERROR2_STMT(extPacks[i], COMGETTER(WhyUnusable)(bstrWhy.asOutParam()), hrc = hrcCheck; bstrWhy.setNull()); /* Display them. */ if (i) RTPrintf("\n"); RTPrintf("Pack no.%2zu: %ls\n" "Version: %ls\n" "Revision: %u\n" "Edition: %ls\n" "Description: %ls\n" "VRDE Module: %ls\n" "Usable: %RTbool\n" "Why unusable: %ls\n", i, bstrName.raw(), bstrVersion.raw(), uRevision, bstrEdition.raw(), bstrDesc.raw(), bstrVrdeModule.raw(), fUsable != FALSE, bstrWhy.raw()); /* Query plugins and display them. */ } return hrc; }
/** * Implementation for "VBoxManage snapshot ... dump". This goes thru the machine's * medium attachments and calls DumpMediumWithChildren() for each hard disk medium found, * which then dumps the parent/child tree of that medium together with the corresponding * snapshots. * @param pMachine Machine to dump snapshots for. */ void DumpSnapshot(ComPtr<IMachine> &pMachine) { HRESULT rc; do { // get root snapshot ComPtr<ISnapshot> pSnapshot; CHECK_ERROR_BREAK(pMachine, FindSnapshot(Bstr("").raw(), pSnapshot.asOutParam())); // get current snapshot ComPtr<ISnapshot> pCurrentSnapshot; CHECK_ERROR_BREAK(pMachine, COMGETTER(CurrentSnapshot)(pCurrentSnapshot.asOutParam())); // get media attachments SafeIfaceArray<IMediumAttachment> aAttachments; CHECK_ERROR_BREAK(pMachine, COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(aAttachments))); for (uint32_t i = 0; i < aAttachments.size(); ++i) { ComPtr<IMediumAttachment> pAttach(aAttachments[i]); DeviceType_T type; CHECK_ERROR_BREAK(pAttach, COMGETTER(Type)(&type)); if (type == DeviceType_HardDisk) { ComPtr<IMedium> pCurrentStateMedium; CHECK_ERROR_BREAK(pAttach, COMGETTER(Medium)(pCurrentStateMedium.asOutParam())); ComPtr<IMedium> pBaseMedium; CHECK_ERROR_BREAK(pCurrentStateMedium, COMGETTER(Base)(pBaseMedium.asOutParam())); Bstr bstrBaseMediumName; CHECK_ERROR_BREAK(pBaseMedium, COMGETTER(Name)(bstrBaseMediumName.asOutParam())); RTPrintf("[%RI32] Images and snapshots for medium \"%ls\"\n", i, bstrBaseMediumName.raw()); DumpMediumWithChildren(pCurrentStateMedium, pBaseMedium, pSnapshot, pCurrentSnapshot, 0); } } } while (0); }
static RTEXITCODE handleRemove(HandlerArg *a) { /* * Parse input. */ const char *pszName = NULL; int ch; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; RTGetOptInit(&GetState, a->argc, a->argv, NULL, 0, 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((ch = RTGetOpt(&GetState, &ValueUnion)) != 0) switch (ch) { case VINF_GETOPT_NOT_OPTION: if (pszName) return errorSyntax(USAGE_HOSTONLYIFS, "Only one interface name can be specified"); pszName = ValueUnion.psz; break; default: return errorGetOpt(USAGE_HOSTONLYIFS, ch, &ValueUnion); } if (!pszName) return errorSyntax(USAGE_HOSTONLYIFS, "No interface name was specified"); /* * Do the work. */ ComPtr<IHost> host; CHECK_ERROR2I_RET(a->virtualBox, COMGETTER(Host)(host.asOutParam()), RTEXITCODE_FAILURE); ComPtr<IHostNetworkInterface> hif; CHECK_ERROR2I_RET(host, FindHostNetworkInterfaceByName(Bstr(pszName).raw(), hif.asOutParam()), RTEXITCODE_FAILURE); Bstr guid; CHECK_ERROR2I_RET(hif, COMGETTER(Id)(guid.asOutParam()), RTEXITCODE_FAILURE); ComPtr<IProgress> progress; CHECK_ERROR2I_RET(host, RemoveHostOnlyNetworkInterface(guid.raw(), progress.asOutParam()), RTEXITCODE_FAILURE); /*HRESULT hrc =*/ showProgress(progress); CHECK_PROGRESS_ERROR_RET(progress, ("Failed to remove the host-only adapter"), RTEXITCODE_FAILURE); return RTEXITCODE_SUCCESS; }
STDMETHODIMP VFSExplorer::Update(IProgress **aProgress) { CheckComArgOutPointerValid(aProgress); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT rc = S_OK; ComObjPtr<Progress> progress; try { Bstr progressDesc = BstrFmt(tr("Update directory info for '%s'"), m->strPath.c_str()); /* Create the progress object */ progress.createObject(); rc = progress->init(mVirtualBox, static_cast<IVFSExplorer*>(this), progressDesc.raw(), TRUE /* aCancelable */); if (FAILED(rc)) throw rc; /* Initialize our worker task */ std::auto_ptr<TaskVFSExplorer> task(new TaskVFSExplorer(TaskVFSExplorer::Update, this, progress)); rc = task->startThread(); if (FAILED(rc)) throw rc; /* Don't destruct on success */ task.release(); } catch (HRESULT aRC) { rc = aRC; } if (SUCCEEDED(rc)) /* Return progress to the caller */ progress.queryInterfaceTo(aProgress); return rc; }
/** * Initializes the host object. * * @returns COM result indicator * @param aInterfaceName name of the network interface * @param aGuid GUID of the host network interface */ HRESULT HostNetworkInterface::init(Bstr aInterfaceName, Guid aGuid, HostNetworkInterfaceType_T ifType) { LogFlowThisFunc(("aInterfaceName={%ls}, aGuid={%s}\n", aInterfaceName.raw(), aGuid.toString().c_str())); ComAssertRet(!aInterfaceName.isEmpty(), E_INVALIDARG); ComAssertRet(!aGuid.isEmpty(), E_INVALIDARG); /* Enclose the state transition NotReady->InInit->Ready */ AutoInitSpan autoInitSpan(this); AssertReturn(autoInitSpan.isOk(), E_FAIL); unconst(mInterfaceName) = aInterfaceName; unconst(mGuid) = aGuid; mIfType = ifType; /* Confirm a successful initialization */ autoInitSpan.setSucceeded(); return S_OK; }
/** * Removes a specified machine from the list of handled machines. * Does not do locking -- needs to be done by caller! * * @return IPRT status code. * @param strUuid UUID of the specified machine. */ static int machineRemove(const Bstr &strUuid) { AssertReturn(!strUuid.isEmpty(), VERR_INVALID_PARAMETER); int rc = VINF_SUCCESS; mapVMIter it = g_mapVM.find(strUuid); if (it != g_mapVM.end()) { int rc2 = machineDestroy(strUuid); if (RT_FAILURE(rc)) { serviceLog(("Machine \"%ls\" failed to destroy, rc=%Rc\n")); if (RT_SUCCESS(rc)) rc = rc2; } } else { serviceLogVerbose(("Warning: Removing not added machine \"%ls\"\n", strUuid.raw())); rc = VERR_NOT_FOUND; } return rc; }
static int machineDestroy(const Bstr &strUuid) { AssertReturn(!strUuid.isEmpty(), VERR_INVALID_PARAMETER); int rc = VINF_SUCCESS; /* Let all modules know. */ for (unsigned j = 0; j < RT_ELEMENTS(g_aModules); j++) if (g_aModules[j].fEnabled) { int rc2 = g_aModules[j].pDesc->pfnOnMachineUnregistered(strUuid); if (RT_FAILURE(rc2)) serviceLog("OnMachineUnregistered: Module '%s' reported an error: %Rrc\n", g_aModules[j].pDesc->pszName, rc); /* Keep going. */ } /* Must log before erasing the iterator because of the UUID ref! */ serviceLogVerbose(("Removing machine \"%ls\"\n", strUuid.raw())); try { mapVMIter itVM = g_mapVM.find(strUuid); Assert(itVM != g_mapVM.end()); /* Remove machine from group(s). */ mapGroupsIterConst itGroups = itVM->second.groups.begin(); while (itGroups != itVM->second.groups.end()) { mapGroupIter itGroup = g_mapGroup.find(itGroups->first); Assert(itGroup != g_mapGroup.end()); vecGroupMembers vecMembers = itGroup->second; vecGroupMembersIter itMember = std::find(vecMembers.begin(), vecMembers.end(), strUuid); Assert(itMember != vecMembers.end()); vecMembers.erase(itMember); serviceLogVerbose(("Group \"%s\" has %ld machines left\n", itGroup->first.c_str(), vecMembers.size())); if (!vecMembers.size()) { serviceLogVerbose(("Deleting group \"%s\"\n", itGroup->first.c_str())); g_mapGroup.erase(itGroup); } ++itGroups; } #ifndef VBOX_WATCHDOG_GLOBAL_PERFCOL itVM->second.collector.setNull(); #endif itVM->second.machine.setNull(); /* * Remove machine from map. */ g_mapVM.erase(itVM); } catch (...) { AssertFailed(); } return rc; }
int handleGetExtraData(HandlerArg *a) { HRESULT rc = S_OK; if (a->argc != 2) return errorSyntax(USAGE_GETEXTRADATA, "Incorrect number of parameters"); /* global data? */ if (!strcmp(a->argv[0], "global")) { /* enumeration? */ if (!strcmp(a->argv[1], "enumerate")) { SafeArray<BSTR> aKeys; CHECK_ERROR(a->virtualBox, GetExtraDataKeys(ComSafeArrayAsOutParam(aKeys))); for (size_t i = 0; i < aKeys.size(); ++i) { Bstr bstrKey(aKeys[i]); Bstr bstrValue; CHECK_ERROR(a->virtualBox, GetExtraData(bstrKey.raw(), bstrValue.asOutParam())); RTPrintf("Key: %ls, Value: %ls\n", bstrKey.raw(), bstrValue.raw()); } } else { Bstr value; CHECK_ERROR(a->virtualBox, GetExtraData(Bstr(a->argv[1]).raw(), value.asOutParam())); if (!value.isEmpty()) RTPrintf("Value: %ls\n", value.raw()); else RTPrintf("No value set!\n"); } } else { ComPtr<IMachine> machine; CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), machine.asOutParam())); if (machine) { /* enumeration? */ if (!strcmp(a->argv[1], "enumerate")) { SafeArray<BSTR> aKeys; CHECK_ERROR(machine, GetExtraDataKeys(ComSafeArrayAsOutParam(aKeys))); for (size_t i = 0; i < aKeys.size(); ++i) { Bstr bstrKey(aKeys[i]); Bstr bstrValue; CHECK_ERROR(machine, GetExtraData(bstrKey.raw(), bstrValue.asOutParam())); RTPrintf("Key: %ls, Value: %ls\n", bstrKey.raw(), bstrValue.raw()); } } else { Bstr value; CHECK_ERROR(machine, GetExtraData(Bstr(a->argv[1]).raw(), value.asOutParam())); if (!value.isEmpty()) RTPrintf("Value: %ls\n", value.raw()); else RTPrintf("No value set!\n"); } } } return SUCCEEDED(rc) ? 0 : 1; }
/** * Adds a specified machine to the list (map) of handled machines. * Does not do locking -- needs to be done by caller! * * @return IPRT status code. * @param strUuid UUID of the specified machine. */ static int machineAdd(const Bstr &strUuid) { HRESULT rc; /** @todo Add exception handling! */ do { ComPtr <IMachine> machine; CHECK_ERROR_BREAK(g_pVirtualBox, FindMachine(strUuid.raw(), machine.asOutParam())); Assert(!machine.isNull()); /* * Get groups for this machine. */ com::SafeArray<BSTR> groups; CHECK_ERROR_BREAK(machine, COMGETTER(Groups)(ComSafeArrayAsOutParam(groups))); Utf8Str strGroups; for (size_t i = 0; i < groups.size(); i++) { if (i != 0) strGroups.append(","); strGroups.append(Utf8Str(groups[i])); } /* * Add machine to map. */ VBOXWATCHDOG_MACHINE m; m.machine = machine; int rc2 = groupAdd(m.groups, strGroups.c_str(), 0 /* Flags */); AssertRC(rc2); mapVMIter it = g_mapVM.find(strUuid); Assert(it == g_mapVM.end()); g_mapVM.insert(std::make_pair(strUuid, m)); serviceLogVerbose(("Added machine \"%ls\"\n", strUuid.raw())); /* * Get the machine's VM group(s). */ mapGroupsIterConst itGroup = m.groups.begin(); while (itGroup != m.groups.end()) { serviceLogVerbose(("Machine \"%ls\" is in VM group \"%s\"\n", strUuid.raw(), itGroup->first.c_str())); /* Add machine to group(s). */ mapGroupIter itGroups = g_mapGroup.find(itGroup->first); if (itGroups == g_mapGroup.end()) { vecGroupMembers vecMembers; vecMembers.push_back(strUuid); g_mapGroup.insert(std::make_pair(itGroup->first, vecMembers)); itGroups = g_mapGroup.find(itGroup->first); Assert(itGroups != g_mapGroup.end()); } else itGroups->second.push_back(strUuid); serviceLogVerbose(("Group \"%s\" has now %ld machine(s)\n", itGroup->first.c_str(), itGroups->second.size())); ++itGroup; } /* * Let all modules know. Typically all modules would register * their per-machine payload here. */ for (unsigned j = 0; j < RT_ELEMENTS(g_aModules); j++) if (g_aModules[j].fEnabled) { rc2 = g_aModules[j].pDesc->pfnOnMachineRegistered(strUuid); if (RT_FAILURE(rc2)) serviceLog("OnMachineRegistered: Module '%s' reported an error: %Rrc\n", g_aModules[j].pDesc->pszName, rc); /* Keep going. */ } } while (0); /** @todo Add std exception handling! */ return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_COM_IPRT_ERROR; /* @todo Find a better error! */ }
int handleCloneVM(HandlerArg *a) { HRESULT rc; const char *pszSrcName = NULL; const char *pszSnapshotName = NULL; CloneMode_T mode = CloneMode_MachineState; com::SafeArray<CloneOptions_T> options; const char *pszTrgName = NULL; const char *pszTrgBaseFolder = NULL; bool fRegister = false; Bstr bstrUuid; com::SafeArray<BSTR> groups; int c; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; // start at 0 because main() has hacked both the argc and argv given to us RTGetOptInit(&GetState, a->argc, a->argv, g_aCloneVMOptions, RT_ELEMENTS(g_aCloneVMOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((c = RTGetOpt(&GetState, &ValueUnion))) { switch (c) { case 's': // --snapshot pszSnapshotName = ValueUnion.psz; break; case 'n': // --name pszTrgName = ValueUnion.psz; break; case 'g': // --groups parseGroups(ValueUnion.psz, &groups); break; case 'p': // --basefolder pszTrgBaseFolder = ValueUnion.psz; break; case 'm': // --mode if (RT_FAILURE(parseCloneMode(ValueUnion.psz, &mode))) return errorArgument("Invalid clone mode '%s'\n", ValueUnion.psz); break; case 'o': // --options if (RT_FAILURE(parseCloneOptions(ValueUnion.psz, &options))) return errorArgument("Invalid clone options '%s'\n", ValueUnion.psz); break; case 'u': // --uuid bstrUuid = Guid(ValueUnion.Uuid).toUtf16().raw(); break; case 'r': // --register fRegister = true; break; case VINF_GETOPT_NOT_OPTION: if (!pszSrcName) pszSrcName = ValueUnion.psz; else return errorSyntax(USAGE_CLONEVM, "Invalid parameter '%s'", ValueUnion.psz); break; default: return errorGetOpt(USAGE_CLONEVM, c, &ValueUnion); } } /* Check for required options */ if (!pszSrcName) return errorSyntax(USAGE_CLONEVM, "VM name required"); /* Get the machine object */ ComPtr<IMachine> srcMachine; CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(pszSrcName).raw(), srcMachine.asOutParam()), RTEXITCODE_FAILURE); /* If a snapshot name/uuid was given, get the particular machine of this * snapshot. */ if (pszSnapshotName) { ComPtr<ISnapshot> srcSnapshot; CHECK_ERROR_RET(srcMachine, FindSnapshot(Bstr(pszSnapshotName).raw(), srcSnapshot.asOutParam()), RTEXITCODE_FAILURE); CHECK_ERROR_RET(srcSnapshot, COMGETTER(Machine)(srcMachine.asOutParam()), RTEXITCODE_FAILURE); } /* Default name necessary? */ if (!pszTrgName) pszTrgName = RTStrAPrintf2("%s Clone", pszSrcName); Bstr createFlags; if (!bstrUuid.isEmpty()) createFlags = BstrFmt("UUID=%ls", bstrUuid.raw()); Bstr bstrPrimaryGroup; if (groups.size()) bstrPrimaryGroup = groups[0]; Bstr bstrSettingsFile; CHECK_ERROR_RET(a->virtualBox, ComposeMachineFilename(Bstr(pszTrgName).raw(), bstrPrimaryGroup.raw(), createFlags.raw(), Bstr(pszTrgBaseFolder).raw(), bstrSettingsFile.asOutParam()), RTEXITCODE_FAILURE); ComPtr<IMachine> trgMachine; CHECK_ERROR_RET(a->virtualBox, CreateMachine(bstrSettingsFile.raw(), Bstr(pszTrgName).raw(), ComSafeArrayAsInParam(groups), NULL, createFlags.raw(), trgMachine.asOutParam()), RTEXITCODE_FAILURE); /* Start the cloning */ ComPtr<IProgress> progress; CHECK_ERROR_RET(srcMachine, CloneTo(trgMachine, mode, ComSafeArrayAsInParam(options), progress.asOutParam()), RTEXITCODE_FAILURE); rc = showProgress(progress); CHECK_PROGRESS_ERROR_RET(progress, ("Clone VM failed"), RTEXITCODE_FAILURE); if (fRegister) CHECK_ERROR_RET(a->virtualBox, RegisterMachine(trgMachine), RTEXITCODE_FAILURE); Bstr bstrNewName; CHECK_ERROR_RET(trgMachine, COMGETTER(Name)(bstrNewName.asOutParam()), RTEXITCODE_FAILURE); RTPrintf("Machine has been successfully cloned as \"%ls\"\n", bstrNewName.raw()); return RTEXITCODE_SUCCESS; }
int handleStartVM(HandlerArg *a) { HRESULT rc = S_OK; std::list<const char *> VMs; Bstr sessionType = "gui"; static const RTGETOPTDEF s_aStartVMOptions[] = { { "--type", 't', RTGETOPT_REQ_STRING }, { "-type", 't', RTGETOPT_REQ_STRING }, // deprecated }; int c; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; // start at 0 because main() has hacked both the argc and argv given to us RTGetOptInit(&GetState, a->argc, a->argv, s_aStartVMOptions, RT_ELEMENTS(s_aStartVMOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((c = RTGetOpt(&GetState, &ValueUnion))) { switch (c) { case 't': // --type if (!RTStrICmp(ValueUnion.psz, "gui")) { sessionType = "gui"; } #ifdef VBOX_WITH_VBOXSDL else if (!RTStrICmp(ValueUnion.psz, "sdl")) { sessionType = "sdl"; } #endif #ifdef VBOX_WITH_HEADLESS else if (!RTStrICmp(ValueUnion.psz, "capture")) { sessionType = "capture"; } else if (!RTStrICmp(ValueUnion.psz, "headless")) { sessionType = "headless"; } #endif else sessionType = ValueUnion.psz; break; case VINF_GETOPT_NOT_OPTION: VMs.push_back(ValueUnion.psz); break; default: if (c > 0) { if (RT_C_IS_PRINT(c)) return errorSyntax(USAGE_STARTVM, "Invalid option -%c", c); else return errorSyntax(USAGE_STARTVM, "Invalid option case %i", c); } else if (c == VERR_GETOPT_UNKNOWN_OPTION) return errorSyntax(USAGE_STARTVM, "unknown option: %s\n", ValueUnion.psz); else if (ValueUnion.pDef) return errorSyntax(USAGE_STARTVM, "%s: %Rrs", ValueUnion.pDef->pszLong, c); else return errorSyntax(USAGE_STARTVM, "error: %Rrs", c); } } /* check for required options */ if (VMs.empty()) return errorSyntax(USAGE_STARTVM, "at least one VM name or uuid required"); for (std::list<const char *>::const_iterator it = VMs.begin(); it != VMs.end(); ++it) { HRESULT rc2 = rc; const char *pszVM = *it; ComPtr<IMachine> machine; CHECK_ERROR(a->virtualBox, FindMachine(Bstr(pszVM).raw(), machine.asOutParam())); if (machine) { Bstr env; #if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) /* make sure the VM process will start on the same display as VBoxManage */ Utf8Str str; const char *pszDisplay = RTEnvGet("DISPLAY"); if (pszDisplay) str = Utf8StrFmt("DISPLAY=%s\n", pszDisplay); const char *pszXAuth = RTEnvGet("XAUTHORITY"); if (pszXAuth) str.append(Utf8StrFmt("XAUTHORITY=%s\n", pszXAuth)); env = str; #endif ComPtr<IProgress> progress; CHECK_ERROR(machine, LaunchVMProcess(a->session, sessionType.raw(), env.raw(), progress.asOutParam())); if (SUCCEEDED(rc) && !progress.isNull()) { RTPrintf("Waiting for VM \"%s\" to power on...\n", pszVM); CHECK_ERROR(progress, WaitForCompletion(-1)); if (SUCCEEDED(rc)) { BOOL completed = true; CHECK_ERROR(progress, COMGETTER(Completed)(&completed)); if (SUCCEEDED(rc)) { ASSERT(completed); LONG iRc; CHECK_ERROR(progress, COMGETTER(ResultCode)(&iRc)); if (SUCCEEDED(rc)) { if (FAILED(iRc)) { ProgressErrorInfo info(progress); com::GluePrintErrorInfo(info); } else { RTPrintf("VM \"%s\" has been successfully started.\n", pszVM); } } } } } } /* it's important to always close sessions */ a->session->UnlockMachine(); /* make sure that we remember the failed state */ if (FAILED(rc2)) rc = rc2; } return SUCCEEDED(rc) ? 0 : 1; }
int handleExtPack(HandlerArg *a) { if (a->argc < 1) return errorSyntax(USAGE_EXTPACK, "Incorrect number of parameters"); ComObjPtr<IExtPackManager> ptrExtPackMgr; CHECK_ERROR2_RET(a->virtualBox, COMGETTER(ExtensionPackManager)(ptrExtPackMgr.asOutParam()), RTEXITCODE_FAILURE); RTGETOPTSTATE GetState; RTGETOPTUNION ValueUnion; int ch; HRESULT hrc = S_OK; if (!strcmp(a->argv[0], "install")) { const char *pszName = NULL; bool fReplace = false; static const RTGETOPTDEF s_aInstallOptions[] = { { "--replace", 'r', RTGETOPT_REQ_NOTHING }, }; RTGetOptInit(&GetState, a->argc, a->argv, s_aInstallOptions, RT_ELEMENTS(s_aInstallOptions), 1, 0 /*fFlags*/); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'r': fReplace = true; break; case VINF_GETOPT_NOT_OPTION: if (pszName) return errorSyntax(USAGE_EXTPACK, "Too many extension pack names given to \"extpack uninstall\""); pszName = ValueUnion.psz; break; default: return errorGetOpt(USAGE_EXTPACK, ch, &ValueUnion); } } if (!pszName) return errorSyntax(USAGE_EXTPACK, "No extension pack name was given to \"extpack install\""); char szPath[RTPATH_MAX]; int vrc = RTPathAbs(pszName, szPath, sizeof(szPath)); if (RT_FAILURE(vrc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTPathAbs(%s,,) failed with rc=%Rrc", pszName, vrc); Bstr bstrTarball(szPath); Bstr bstrName; ComPtr<IExtPackFile> ptrExtPackFile; CHECK_ERROR2_RET(ptrExtPackMgr, OpenExtPackFile(bstrTarball.raw(), ptrExtPackFile.asOutParam()), RTEXITCODE_FAILURE); CHECK_ERROR2_RET(ptrExtPackFile, COMGETTER(Name)(bstrName.asOutParam()), RTEXITCODE_FAILURE); ComPtr<IProgress> ptrProgress; CHECK_ERROR2_RET(ptrExtPackFile, Install(fReplace, NULL, ptrProgress.asOutParam()), RTEXITCODE_FAILURE); hrc = showProgress(ptrProgress); CHECK_PROGRESS_ERROR_RET(ptrProgress, ("Failed to install \"%s\"", szPath), RTEXITCODE_FAILURE); RTPrintf("Successfully installed \"%ls\".\n", bstrName.raw()); } else if (!strcmp(a->argv[0], "uninstall")) { const char *pszName = NULL; bool fForced = false; static const RTGETOPTDEF s_aUninstallOptions[] = { { "--force", 'f', RTGETOPT_REQ_NOTHING }, }; RTGetOptInit(&GetState, a->argc, a->argv, s_aUninstallOptions, RT_ELEMENTS(s_aUninstallOptions), 1, 0); while ((ch = RTGetOpt(&GetState, &ValueUnion))) { switch (ch) { case 'f': fForced = true; break; case VINF_GETOPT_NOT_OPTION: if (pszName) return errorSyntax(USAGE_EXTPACK, "Too many extension pack names given to \"extpack uninstall\""); pszName = ValueUnion.psz; break; default: return errorGetOpt(USAGE_EXTPACK, ch, &ValueUnion); } } if (!pszName) return errorSyntax(USAGE_EXTPACK, "No extension pack name was given to \"extpack uninstall\""); Bstr bstrName(pszName); ComPtr<IProgress> ptrProgress; CHECK_ERROR2_RET(ptrExtPackMgr, Uninstall(bstrName.raw(), fForced, NULL, ptrProgress.asOutParam()), RTEXITCODE_FAILURE); hrc = showProgress(ptrProgress); CHECK_PROGRESS_ERROR_RET(ptrProgress, ("Failed to uninstall \"%s\"", pszName), RTEXITCODE_FAILURE); RTPrintf("Successfully uninstalled \"%s\".\n", pszName); } else if (!strcmp(a->argv[0], "cleanup")) { if (a->argc > 1) return errorSyntax(USAGE_EXTPACK, "Too many parameters given to \"extpack cleanup\""); CHECK_ERROR2_RET(ptrExtPackMgr, Cleanup(), RTEXITCODE_FAILURE); RTPrintf("Successfully performed extension pack cleanup\n"); } else return errorSyntax(USAGE_EXTPACK, "Unknown command \"%s\"", a->argv[0]); return RTEXITCODE_SUCCESS; }
int handleCreateVM(HandlerArg *a) { HRESULT rc; Bstr bstrBaseFolder; Bstr bstrName; Bstr bstrOsTypeId; Bstr bstrUuid; bool fRegister = false; com::SafeArray<BSTR> groups; int c; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; // start at 0 because main() has hacked both the argc and argv given to us RTGetOptInit(&GetState, a->argc, a->argv, g_aCreateVMOptions, RT_ELEMENTS(g_aCreateVMOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((c = RTGetOpt(&GetState, &ValueUnion))) { switch (c) { case 'n': // --name bstrName = ValueUnion.psz; break; case 'g': // --groups parseGroups(ValueUnion.psz, &groups); break; case 'p': // --basefolder bstrBaseFolder = ValueUnion.psz; break; case 'o': // --ostype bstrOsTypeId = ValueUnion.psz; break; case 'u': // --uuid bstrUuid = Guid(ValueUnion.Uuid).toUtf16().raw(); break; case 'r': // --register fRegister = true; break; default: return errorGetOpt(USAGE_CREATEVM, c, &ValueUnion); } } /* check for required options */ if (bstrName.isEmpty()) return errorSyntax(USAGE_CREATEVM, "Parameter --name is required"); do { Bstr createFlags; if (!bstrUuid.isEmpty()) createFlags = BstrFmt("UUID=%ls", bstrUuid.raw()); Bstr bstrPrimaryGroup; if (groups.size()) bstrPrimaryGroup = groups[0]; Bstr bstrSettingsFile; CHECK_ERROR_BREAK(a->virtualBox, ComposeMachineFilename(bstrName.raw(), bstrPrimaryGroup.raw(), createFlags.raw(), bstrBaseFolder.raw(), bstrSettingsFile.asOutParam())); ComPtr<IMachine> machine; CHECK_ERROR_BREAK(a->virtualBox, CreateMachine(bstrSettingsFile.raw(), bstrName.raw(), ComSafeArrayAsInParam(groups), bstrOsTypeId.raw(), createFlags.raw(), machine.asOutParam())); CHECK_ERROR_BREAK(machine, SaveSettings()); if (fRegister) { CHECK_ERROR_BREAK(a->virtualBox, RegisterMachine(machine)); } Bstr uuid; CHECK_ERROR_BREAK(machine, COMGETTER(Id)(uuid.asOutParam())); Bstr settingsFile; CHECK_ERROR_BREAK(machine, COMGETTER(SettingsFilePath)(settingsFile.asOutParam())); RTPrintf("Virtual machine '%ls' is created%s.\n" "UUID: %s\n" "Settings file: '%ls'\n", bstrName.raw(), fRegister ? " and registered" : "", Utf8Str(uuid).c_str(), settingsFile.raw()); } while (0); return SUCCEEDED(rc) ? 0 : 1; }
HRESULT Progress::waitForAsyncProgressCompletion(const ComPtr<IProgress> &aPProgressAsync) { LogFlowThisFuncEnter(); /* Note: we don't lock here, cause we just using public methods. */ HRESULT rc = S_OK; BOOL fCancelable = FALSE; BOOL fCompleted = FALSE; BOOL fCanceled = FALSE; ULONG prevPercent = UINT32_MAX; ULONG currentPercent = 0; ULONG cOp = 0; /* Is the async process cancelable? */ rc = aPProgressAsync->COMGETTER(Cancelable)(&fCancelable); if (FAILED(rc)) return rc; /* Loop as long as the sync process isn't completed. */ while (SUCCEEDED(aPProgressAsync->COMGETTER(Completed(&fCompleted)))) { /* We can forward any cancel request to the async process only when * it is cancelable. */ if (fCancelable) { rc = COMGETTER(Canceled)(&fCanceled); if (FAILED(rc)) return rc; if (fCanceled) { rc = aPProgressAsync->Cancel(); if (FAILED(rc)) return rc; } } /* Even if the user canceled the process, we have to wait until the async task has finished his work (cleanup and such). Otherwise there will be sync trouble (still wrong state, dead locks, ...) on the used objects. So just do nothing, but wait for the complete notification. */ if (!fCanceled) { /* Check if the current operation has changed. It is also possible that * in the meantime more than one async operation was finished. So we * have to loop as long as we reached the same operation count. */ ULONG curOp; for (;;) { rc = aPProgressAsync->COMGETTER(Operation(&curOp)); if (FAILED(rc)) return rc; if (cOp != curOp) { Bstr bstr; ULONG currentWeight; rc = aPProgressAsync->COMGETTER(OperationDescription(bstr.asOutParam())); if (FAILED(rc)) return rc; rc = aPProgressAsync->COMGETTER(OperationWeight(¤tWeight)); if (FAILED(rc)) return rc; rc = SetNextOperation(bstr.raw(), currentWeight); if (FAILED(rc)) return rc; ++cOp; } else break; } rc = aPProgressAsync->COMGETTER(OperationPercent(¤tPercent)); if (FAILED(rc)) return rc; if (currentPercent != prevPercent) { prevPercent = currentPercent; rc = SetCurrentOperationProgress(currentPercent); if (FAILED(rc)) return rc; } } if (fCompleted) break; /* Make sure the loop is not too tight */ rc = aPProgressAsync->WaitForCompletion(100); if (FAILED(rc)) return rc; } LogFlowThisFuncLeave(); return rc; }
/** * Sets the other progress object unless the operation has been completed / * canceled already. * * @returns false if failed/canceled, true if not. * @param pOtherProgress The other progress object. Must not be NULL. */ bool ProgressProxy::setOtherProgressObject(IProgress *pOtherProgress) { LogFlowThisFunc(("setOtherProgressObject: %p\n", pOtherProgress)); ComPtr<IProgress> ptrOtherProgress = pOtherProgress; /* * Query information from the other progress object before we grab the * lock. */ ULONG cOperations; HRESULT hrc = pOtherProgress->COMGETTER(OperationCount)(&cOperations); if (FAILED(hrc)) cOperations = 1; Bstr bstrOperationDescription; hrc = pOtherProgress->COMGETTER(Description)(bstrOperationDescription.asOutParam()); if (FAILED(hrc)) bstrOperationDescription = "oops"; /* * Take the lock and check for cancelation, cancel the other object if * we've been canceled already. */ AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); BOOL fCompletedOrCanceled = mCompleted || mCanceled; if (!fCompletedOrCanceled) { /* * Advance to the next object and operation. If the other object has * more operations than anticipated, adjust our internal count. */ mptrOtherProgress = ptrOtherProgress; mfMultiOperation = cOperations > 1; muOtherProgressStartWeight = m_ulOperationsCompletedWeight + m_ulCurrentOperationWeight; muOtherProgressWeight = m_ulTotalOperationsWeight - muOtherProgressStartWeight; Progress::SetNextOperation(bstrOperationDescription.raw(), muOtherProgressWeight); muOtherProgressStartOperation = m_ulCurrentOperation; m_cOperations = cOperations + m_ulCurrentOperation; /* * Check for cancelation and completion. */ BOOL f; hrc = ptrOtherProgress->COMGETTER(Completed)(&f); fCompletedOrCanceled = FAILED(hrc) || f; if (!fCompletedOrCanceled) { hrc = ptrOtherProgress->COMGETTER(Canceled)(&f); fCompletedOrCanceled = SUCCEEDED(hrc) && f; } if (fCompletedOrCanceled) { LogFlowThisFunc(("Other object completed or canceled, clearing...\n")); clearOtherProgressObjectInternal(false /*fEarly*/); } else { /* * Finally, mirror the cancelable property. * Note! Note necessary if we do passthru! */ if (mCancelable) { hrc = ptrOtherProgress->COMGETTER(Cancelable)(&f); if (SUCCEEDED(hrc) && !f) { LogFlowThisFunc(("The other progress object is not cancelable\n")); mCancelable = FALSE; } } } } else { LogFlowThisFunc(("mCompleted=%RTbool mCanceled=%RTbool - Canceling the other progress object!\n", mCompleted, mCanceled)); hrc = ptrOtherProgress->Cancel(); LogFlowThisFunc(("Cancel -> %Rhrc", hrc)); } LogFlowThisFunc(("Returns %RTbool\n", !fCompletedOrCanceled)); return !fCompletedOrCanceled; }
/** * Enumerates the properties in the guest property store. * * @returns 0 on success, 1 on failure * @note see the command line API description for parameters */ static int handleWaitGuestProperty(HandlerArg *a) { /* * Handle arguments */ bool fFailOnTimeout = false; const char *pszPatterns = NULL; uint32_t cMsTimeout = RT_INDEFINITE_WAIT; bool usageOK = true; if (a->argc < 2) usageOK = false; else pszPatterns = a->argv[1]; ComPtr<IMachine> machine; HRESULT rc; CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), machine.asOutParam())); if (!machine) usageOK = false; for (int i = 2; usageOK && i < a->argc; ++i) { if ( !strcmp(a->argv[i], "--timeout") || !strcmp(a->argv[i], "-timeout")) { if ( i + 1 >= a->argc || RTStrToUInt32Full(a->argv[i + 1], 10, &cMsTimeout) != VINF_SUCCESS) usageOK = false; else ++i; } else if (!strcmp(a->argv[i], "--fail-on-timeout")) fFailOnTimeout = true; else usageOK = false; } if (!usageOK) return errorSyntax(USAGE_GUESTPROPERTY, "Incorrect parameters"); /* * Set up the event listener and wait until found match or timeout. */ Bstr aMachStrGuid; machine->COMGETTER(Id)(aMachStrGuid.asOutParam()); Guid aMachGuid(aMachStrGuid); ComPtr<IEventSource> es; CHECK_ERROR(a->virtualBox, COMGETTER(EventSource)(es.asOutParam())); ComPtr<IEventListener> listener; CHECK_ERROR(es, CreateListener(listener.asOutParam())); com::SafeArray <VBoxEventType_T> eventTypes(1); eventTypes.push_back(VBoxEventType_OnGuestPropertyChanged); CHECK_ERROR(es, RegisterListener(listener, ComSafeArrayAsInParam(eventTypes), false)); uint64_t u64Started = RTTimeMilliTS(); bool fSignalled = false; do { unsigned cMsWait; if (cMsTimeout == RT_INDEFINITE_WAIT) cMsWait = 1000; else { uint64_t cMsElapsed = RTTimeMilliTS() - u64Started; if (cMsElapsed >= cMsTimeout) break; /* timed out */ cMsWait = RT_MIN(1000, cMsTimeout - (uint32_t)cMsElapsed); } ComPtr<IEvent> ev; rc = es->GetEvent(listener, cMsWait, ev.asOutParam()); if (ev) { VBoxEventType_T aType; rc = ev->COMGETTER(Type)(&aType); switch (aType) { case VBoxEventType_OnGuestPropertyChanged: { ComPtr<IGuestPropertyChangedEvent> gpcev = ev; Assert(gpcev); Bstr aNextStrGuid; gpcev->COMGETTER(MachineId)(aNextStrGuid.asOutParam()); if (aMachGuid != Guid(aNextStrGuid)) continue; Bstr aNextName; gpcev->COMGETTER(Name)(aNextName.asOutParam()); if (RTStrSimplePatternMultiMatch(pszPatterns, RTSTR_MAX, Utf8Str(aNextName).c_str(), RTSTR_MAX, NULL)) { Bstr aNextValue, aNextFlags; gpcev->COMGETTER(Value)(aNextValue.asOutParam()); gpcev->COMGETTER(Flags)(aNextFlags.asOutParam()); RTPrintf("Name: %ls, value: %ls, flags: %ls\n", aNextName.raw(), aNextValue.raw(), aNextFlags.raw()); fSignalled = true; } break; } default: AssertFailed(); } } } while (!fSignalled); es->UnregisterListener(listener); int rcRet = 0; if (!fSignalled) { RTMsgError("Time out or interruption while waiting for a notification."); if (fFailOnTimeout) rcRet = 2; } return rcRet; }
HRESULT showMediumInfo(const ComPtr<IVirtualBox> &pVirtualBox, const ComPtr<IMedium> &pMedium, const char *pszParentUUID, bool fOptLong) { HRESULT rc = S_OK; do { Bstr uuid; pMedium->COMGETTER(Id)(uuid.asOutParam()); RTPrintf("UUID: %ls\n", uuid.raw()); if (pszParentUUID) RTPrintf("Parent UUID: %s\n", pszParentUUID); /* check for accessibility */ MediumState_T enmState; CHECK_ERROR_BREAK(pMedium, RefreshState(&enmState)); pMedium->RefreshState(&enmState); const char *pszState = "unknown"; switch (enmState) { case MediumState_NotCreated: pszState = "not created"; break; case MediumState_Created: pszState = "created"; break; case MediumState_LockedRead: pszState = "locked read"; break; case MediumState_LockedWrite: pszState = "locked write"; break; case MediumState_Inaccessible: pszState = "inaccessible"; break; case MediumState_Creating: pszState = "creating"; break; case MediumState_Deleting: pszState = "deleting"; break; } RTPrintf("State: %s\n", pszState); if (fOptLong && enmState == MediumState_Inaccessible) { Bstr err; CHECK_ERROR_BREAK(pMedium, COMGETTER(LastAccessError)(err.asOutParam())); RTPrintf("Access Error: %ls\n", err.raw()); } if (fOptLong) { Bstr description; pMedium->COMGETTER(Description)(description.asOutParam()); if (!description.isEmpty()) RTPrintf("Description: %ls\n", description.raw()); } MediumType_T type; pMedium->COMGETTER(Type)(&type); const char *typeStr = "unknown"; switch (type) { case MediumType_Normal: if (pszParentUUID && Guid(pszParentUUID).isValid()) typeStr = "normal (differencing)"; else typeStr = "normal (base)"; break; case MediumType_Immutable: typeStr = "immutable"; break; case MediumType_Writethrough: typeStr = "writethrough"; break; case MediumType_Shareable: typeStr = "shareable"; break; case MediumType_Readonly: typeStr = "readonly"; break; case MediumType_MultiAttach: typeStr = "multiattach"; break; } RTPrintf("Type: %s\n", typeStr); /* print out information specific for differencing hard disks */ if (fOptLong && pszParentUUID && Guid(pszParentUUID).isValid()) { BOOL autoReset = FALSE; pMedium->COMGETTER(AutoReset)(&autoReset); RTPrintf("Auto-Reset: %s\n", autoReset ? "on" : "off"); } Bstr loc; pMedium->COMGETTER(Location)(loc.asOutParam()); RTPrintf("Location: %ls\n", loc.raw()); Bstr format; pMedium->COMGETTER(Format)(format.asOutParam()); RTPrintf("Storage format: %ls\n", format.raw()); if (fOptLong) { com::SafeArray<MediumVariant_T> safeArray_variant; pMedium->COMGETTER(Variant)(ComSafeArrayAsOutParam(safeArray_variant)); ULONG variant=0; for (size_t i = 0; i < safeArray_variant.size(); i++) variant |= safeArray_variant[i]; const char *variantStr = "unknown"; switch (variant & ~(MediumVariant_Fixed | MediumVariant_Diff)) { case MediumVariant_VmdkSplit2G: variantStr = "split2G"; break; case MediumVariant_VmdkStreamOptimized: variantStr = "streamOptimized"; break; case MediumVariant_VmdkESX: variantStr = "ESX"; break; case MediumVariant_Standard: variantStr = "default"; break; } const char *variantTypeStr = "dynamic"; if (variant & MediumVariant_Fixed) variantTypeStr = "fixed"; else if (variant & MediumVariant_Diff) variantTypeStr = "differencing"; RTPrintf("Format variant: %s %s\n", variantTypeStr, variantStr); } LONG64 logicalSize; pMedium->COMGETTER(LogicalSize)(&logicalSize); RTPrintf("Capacity: %lld MBytes\n", logicalSize >> 20); if (fOptLong) { LONG64 actualSize; pMedium->COMGETTER(Size)(&actualSize); RTPrintf("Size on disk: %lld MBytes\n", actualSize >> 20); } if (fOptLong) { com::SafeArray<BSTR> names; com::SafeArray<BSTR> values; pMedium->GetProperties(Bstr().raw(), ComSafeArrayAsOutParam(names), ComSafeArrayAsOutParam(values)); size_t cNames = names.size(); size_t cValues = values.size(); bool fFirst = true; for (size_t i = 0; i < cNames; i++) { Bstr value; if (i < cValues) value = values[i]; RTPrintf("%s%ls=%ls\n", fFirst ? "Property: " : " ", names[i], value.raw()); } } if (fOptLong) { bool fFirst = true; com::SafeArray<BSTR> machineIds; pMedium->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(machineIds)); for (size_t i = 0; i < machineIds.size(); i++) { ComPtr<IMachine> machine; CHECK_ERROR(pVirtualBox, FindMachine(machineIds[i], machine.asOutParam())); if (machine) { Bstr name; machine->COMGETTER(Name)(name.asOutParam()); machine->COMGETTER(Id)(uuid.asOutParam()); RTPrintf("%s%ls (UUID: %ls)", fFirst ? "In use by VMs: " : " ", name.raw(), machineIds[i]); fFirst = false; com::SafeArray<BSTR> snapshotIds; pMedium->GetSnapshotIds(machineIds[i], ComSafeArrayAsOutParam(snapshotIds)); for (size_t j = 0; j < snapshotIds.size(); j++) { ComPtr<ISnapshot> snapshot; machine->FindSnapshot(snapshotIds[j], snapshot.asOutParam()); if (snapshot) { Bstr snapshotName; snapshot->COMGETTER(Name)(snapshotName.asOutParam()); RTPrintf(" [%ls (UUID: %ls)]", snapshotName.raw(), snapshotIds[j]); } } RTPrintf("\n"); } } } if (fOptLong) { com::SafeIfaceArray<IMedium> children; pMedium->COMGETTER(Children)(ComSafeArrayAsOutParam(children)); bool fFirst = true; for (size_t i = 0; i < children.size(); i++) { ComPtr<IMedium> pChild(children[i]); if (pChild) { Bstr childUUID; pChild->COMGETTER(Id)(childUUID.asOutParam()); RTPrintf("%s%ls\n", fFirst ? "Child UUIDs: " : " ", childUUID.raw()); fFirst = false; } } } } while (0); return rc; }
int handleCloneHardDisk(HandlerArg *a) { HRESULT rc; int vrc; const char *pszSrc = NULL; const char *pszDst = NULL; Bstr format; MediumVariant_T DiskVariant = MediumVariant_Standard; bool fExisting = false; int c; RTGETOPTUNION ValueUnion; RTGETOPTSTATE GetState; // start at 0 because main() has hacked both the argc and argv given to us RTGetOptInit(&GetState, a->argc, a->argv, g_aCloneHardDiskOptions, RT_ELEMENTS(g_aCloneHardDiskOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); while ((c = RTGetOpt(&GetState, &ValueUnion))) { switch (c) { case 'o': // --format format = ValueUnion.psz; break; case 'F': // --static { unsigned uDiskVariant = (unsigned)DiskVariant; uDiskVariant |= MediumVariant_Fixed; DiskVariant = (MediumVariant_T)uDiskVariant; break; } case 'E': // --existing fExisting = true; break; case 'm': // --variant vrc = parseDiskVariant(ValueUnion.psz, &DiskVariant); if (RT_FAILURE(vrc)) return errorArgument("Invalid hard disk variant '%s'", ValueUnion.psz); break; case VINF_GETOPT_NOT_OPTION: if (!pszSrc) pszSrc = ValueUnion.psz; else if (!pszDst) pszDst = ValueUnion.psz; else return errorSyntax(USAGE_CLONEHD, "Invalid parameter '%s'", ValueUnion.psz); break; default: if (c > 0) { if (RT_C_IS_GRAPH(c)) return errorSyntax(USAGE_CLONEHD, "unhandled option: -%c", c); else return errorSyntax(USAGE_CLONEHD, "unhandled option: %i", c); } else if (c == VERR_GETOPT_UNKNOWN_OPTION) return errorSyntax(USAGE_CLONEHD, "unknown option: %s", ValueUnion.psz); else if (ValueUnion.pDef) return errorSyntax(USAGE_CLONEHD, "%s: %Rrs", ValueUnion.pDef->pszLong, c); else return errorSyntax(USAGE_CLONEHD, "error: %Rrs", c); } } if (!pszSrc) return errorSyntax(USAGE_CLONEHD, "Mandatory UUID or input file parameter missing"); if (!pszDst) return errorSyntax(USAGE_CLONEHD, "Mandatory output file parameter missing"); if (fExisting && (!format.isEmpty() || DiskVariant != MediumType_Normal)) return errorSyntax(USAGE_CLONEHD, "Specified options which cannot be used with --existing"); ComPtr<IMedium> srcDisk; ComPtr<IMedium> dstDisk; rc = openMedium(a, pszSrc, DeviceType_HardDisk, AccessMode_ReadOnly, srcDisk, false /* fForceNewUuidOnOpen */, false /* fSilent */); if (FAILED(rc)) return 1; do { /* open/create destination hard disk */ if (fExisting) { rc = openMedium(a, pszDst, DeviceType_HardDisk, AccessMode_ReadWrite, dstDisk, false /* fForceNewUuidOnOpen */, false /* fSilent */); if (FAILED(rc)) break; /* Perform accessibility check now. */ MediumState_T state; CHECK_ERROR_BREAK(dstDisk, RefreshState(&state)); CHECK_ERROR_BREAK(dstDisk, COMGETTER(Format)(format.asOutParam())); } else { /* use the format of the source hard disk if unspecified */ if (format.isEmpty()) CHECK_ERROR_BREAK(srcDisk, COMGETTER(Format)(format.asOutParam())); rc = createHardDisk(a, Utf8Str(format).c_str(), pszDst, dstDisk); if (FAILED(rc)) break; } ComPtr<IProgress> progress; com::SafeArray<MediumVariant_T> l_variants(sizeof(MediumVariant_T)*8); for (ULONG i = 0; i < l_variants.size(); ++i) { ULONG temp = DiskVariant; temp &= 1<<i; l_variants [i] = (MediumVariant_T)temp; } CHECK_ERROR_BREAK(srcDisk, CloneTo(dstDisk, ComSafeArrayAsInParam(l_variants), NULL, progress.asOutParam())); rc = showProgress(progress); CHECK_PROGRESS_ERROR_BREAK(progress, ("Failed to clone hard disk")); Bstr uuid; CHECK_ERROR_BREAK(dstDisk, COMGETTER(Id)(uuid.asOutParam())); RTPrintf("Clone hard disk created in format '%ls'. UUID: %s\n", format.raw(), Utf8Str(uuid).c_str()); } while (0); return SUCCEEDED(rc) ? 0 : 1; }