HRESULT HostNetworkInterface::i_setVirtualBox(VirtualBox *pVirtualBox) { AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AssertReturn(mVirtualBox != pVirtualBox, S_OK); unconst(mVirtualBox) = pVirtualBox; #if !defined(RT_OS_WINDOWS) /* If IPv4 address hasn't been initialized */ if (m.IPAddress == 0 && mIfType == HostNetworkInterfaceType_HostOnly) { Bstr tmpAddr, tmpMask; HRESULT hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPAddress", mInterfaceName.c_str()).raw(), tmpAddr.asOutParam()); if (FAILED(hrc) || tmpAddr.isEmpty()) tmpAddr = getDefaultIPv4Address(mInterfaceName); hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPNetMask", mInterfaceName.c_str()).raw(), tmpMask.asOutParam()); if (FAILED(hrc) || tmpMask.isEmpty()) tmpMask = Bstr(VBOXNET_IPV4MASK_DEFAULT); m.IPAddress = inet_addr(Utf8Str(tmpAddr).c_str()); m.networkMask = inet_addr(Utf8Str(tmpMask).c_str()); } if (m.IPV6Address.isEmpty()) { Bstr bstrIPV4Addr; Bstr tmpPrefixLen; HRESULT hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6Address", mInterfaceName.c_str()).raw(), bstrIPV4Addr.asOutParam()); if (SUCCEEDED(hrc)) { m.IPV6Address = bstrIPV4Addr; if (!m.IPV6Address.isEmpty()) { hrc = mVirtualBox->GetExtraData(BstrFmt("HostOnly/%s/IPV6PrefixLen", mInterfaceName.c_str()).raw(), tmpPrefixLen.asOutParam()); if (SUCCEEDED(hrc) && !tmpPrefixLen.isEmpty()) m.IPV6NetworkMaskPrefixLength = Utf8Str(tmpPrefixLen).toUInt32(); else m.IPV6NetworkMaskPrefixLength = 64; } } } #endif return S_OK; }
/** * Sets the Guest Additions version information details. * * Gets called by vmmdevUpdateGuestInfo2 and vmmdevUpdateGuestInfo (to clear the * state). * * @param a_uFullVersion VBoxGuestInfo2::additionsMajor, * VBoxGuestInfo2::additionsMinor and * VBoxGuestInfo2::additionsBuild combined into * one value by VBOX_FULL_VERSION_MAKE. * * When this is 0, it's vmmdevUpdateGuestInfo * calling to reset the state. * * @param a_pszName Build type tag and/or publisher tag, empty * string if neiter of those are present. * @param a_uRevision See VBoxGuestInfo2::additionsRevision. * @param a_fFeatures See VBoxGuestInfo2::additionsFeatures. */ void Guest::setAdditionsInfo2(uint32_t a_uFullVersion, const char *a_pszName, uint32_t a_uRevision, uint32_t a_fFeatures) { AutoCaller autoCaller(this); AssertComRCReturnVoid(autoCaller.rc()); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); if (a_uFullVersion) { mData.mAdditionsVersionNew = BstrFmt(*a_pszName ? "%u.%u.%u_%s" : "%u.%u.%u", VBOX_FULL_VERSION_GET_MAJOR(a_uFullVersion), VBOX_FULL_VERSION_GET_MINOR(a_uFullVersion), VBOX_FULL_VERSION_GET_BUILD(a_uFullVersion), a_pszName); mData.mAdditionsVersionFull = a_uFullVersion; mData.mAdditionsRevision = a_uRevision; mData.mAdditionsFeatures = a_fFeatures; } else { Assert(!a_fFeatures && !a_uRevision && !*a_pszName); mData.mAdditionsVersionNew.setNull(); mData.mAdditionsVersionFull = 0; mData.mAdditionsRevision = 0; mData.mAdditionsFeatures = 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; }
HRESULT HostNetworkInterface::enableStaticIPConfigV6(const com::Utf8Str &aIPV6Address, ULONG aIPV6NetworkMaskPrefixLength) { #ifndef VBOX_WITH_HOSTNETIF_API return E_NOTIMPL; #else if (aIPV6NetworkMaskPrefixLength > 128) return E_INVALIDARG; int rc = S_OK; if ( m.realIPV6Address != aIPV6Address || m.realIPV6PrefixLength != aIPV6NetworkMaskPrefixLength) { BSTR bstr; aIPV6Address.cloneTo(&bstr); if (aIPV6NetworkMaskPrefixLength == 0) aIPV6NetworkMaskPrefixLength = 64; rc = NetIfEnableStaticIpConfigV6(mVirtualBox, this, m.IPV6Address.raw(), bstr, aIPV6NetworkMaskPrefixLength); if (RT_FAILURE(rc)) { LogRel(("Failed to EnableStaticIpConfigV6 with rc=%Rrc\n", rc)); return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL; } else { m.realIPV6Address = aIPV6Address; m.realIPV6PrefixLength = aIPV6NetworkMaskPrefixLength; if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%ls/IPV6Address", mInterfaceName.raw()).raw(), Bstr(aIPV6Address).raw()))) return E_FAIL; if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%ls/IPV6NetMask", mInterfaceName.raw()).raw(), BstrFmt("%u", aIPV6NetworkMaskPrefixLength).raw()))) return E_FAIL; } } return S_OK; #endif }
STDMETHODIMP HostNetworkInterface::EnableStaticIpConfigV6 (IN_BSTR aIPV6Address, ULONG aIPV6MaskPrefixLength) { #ifndef VBOX_WITH_HOSTNETIF_API return E_NOTIMPL; #else if (!aIPV6Address) return E_INVALIDARG; if (aIPV6MaskPrefixLength > 128) return E_INVALIDARG; AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); int rc = S_OK; if (m.realIPV6Address != aIPV6Address || m.realIPV6PrefixLength != aIPV6MaskPrefixLength) { if (aIPV6MaskPrefixLength == 0) aIPV6MaskPrefixLength = 64; rc = NetIfEnableStaticIpConfigV6(mVBox, this, m.IPV6Address.raw(), aIPV6Address, aIPV6MaskPrefixLength); if (RT_FAILURE(rc)) { LogRel(("Failed to EnableStaticIpConfigV6 with rc=%Rrc\n", rc)); return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL; } else { m.realIPV6Address = aIPV6Address; m.realIPV6PrefixLength = aIPV6MaskPrefixLength; if (FAILED(mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPV6Address", mInterfaceName.raw()).raw(), Bstr(aIPV6Address).raw()))) return E_FAIL; if (FAILED(mVBox->SetExtraData(BstrFmt("HostOnly/%ls/IPV6NetMask", mInterfaceName.raw()).raw(), BstrFmt("%u", aIPV6MaskPrefixLength).raw()))) return E_FAIL; } } return S_OK; #endif }
/** * 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; }
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; }
HRESULT HostNetworkInterface::enableStaticIPConfig(const com::Utf8Str &aIPAddress, const com::Utf8Str &aNetworkMask) { #ifndef VBOX_WITH_HOSTNETIF_API return E_NOTIMPL; #else if (aIPAddress.isEmpty()) { if (m.IPAddress) { int rc = NetIfEnableStaticIpConfig(mVirtualBox, this, m.IPAddress, 0, 0); if (RT_SUCCESS(rc)) { m.realIPAddress = 0; if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%ls/IPAddress", mInterfaceName.raw()).raw(), NULL))) return E_FAIL; if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%ls/IPNetMask", mInterfaceName.raw()).raw(), NULL))) return E_FAIL; return S_OK; } } else return S_OK; } ULONG ip, mask; ip = inet_addr(aIPAddress.c_str()); if (ip != INADDR_NONE) { if (aNetworkMask.isEmpty()) mask = 0xFFFFFF; else mask = inet_addr(aNetworkMask.c_str()); if (mask != INADDR_NONE) { if (m.realIPAddress == ip && m.realNetworkMask == mask) return S_OK; int rc = NetIfEnableStaticIpConfig(mVirtualBox, this, m.IPAddress, ip, mask); if (RT_SUCCESS(rc)) { m.realIPAddress = ip; m.realNetworkMask = mask; if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%ls/IPAddress", mInterfaceName.raw()).raw(), Bstr(aIPAddress).raw()))) return E_FAIL; if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%ls/IPNetMask", mInterfaceName.raw()).raw(), Bstr(aNetworkMask).raw()))) return E_FAIL; return S_OK; } else { LogRel(("Failed to EnableStaticIpConfig with rc=%Rrc\n", rc)); return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL; } } } return E_FAIL; #endif }
STDMETHODIMP Guest::COMGETTER(AdditionsVersion) (BSTR *aAdditionsVersion) { CheckComArgOutPointerValid(aAdditionsVersion); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT hr = S_OK; if ( mData.mAdditionsVersion.isEmpty() /* Only try alternative way if GA are active! */ && mData.mAdditionsRunLevel > AdditionsRunLevelType_None) { /* * If we got back an empty string from GetAdditionsVersion() we either * really don't have the Guest Additions version yet or the guest is running * older Guest Additions (< 3.2.0) which don't provide VMMDevReq_ReportGuestInfo2, * so get the version + revision from the (hopefully) provided guest properties * instead. */ Bstr addVersion; LONG64 u64Timestamp; Bstr flags; hr = mParent->machine()->GetGuestProperty(Bstr("/VirtualBox/GuestAdd/Version").raw(), addVersion.asOutParam(), &u64Timestamp, flags.asOutParam()); if (hr == S_OK) { Bstr addRevision; hr = mParent->machine()->GetGuestProperty(Bstr("/VirtualBox/GuestAdd/Revision").raw(), addRevision.asOutParam(), &u64Timestamp, flags.asOutParam()); if ( hr == S_OK && !addVersion.isEmpty() && !addRevision.isEmpty()) { /* Some Guest Additions versions had interchanged version + revision values, * so check if the version value at least has a dot to identify it and change * both values to reflect the right content. */ if (!Utf8Str(addVersion).contains(".")) { Bstr addTemp = addVersion; addVersion = addRevision; addRevision = addTemp; } Bstr additionsVersion = BstrFmt("%ls r%ls", addVersion.raw(), addRevision.raw()); additionsVersion.cloneTo(aAdditionsVersion); } /** @todo r=bird: else: Should not return failure! */ } else { /* If getting the version + revision above fails or they simply aren't there * because of *really* old Guest Additions we only can report the interface * version to at least have something. */ mData.mInterfaceVersion.cloneTo(aAdditionsVersion); /** @todo r=bird: hr is still indicating failure! */ } } else mData.mAdditionsVersion.cloneTo(aAdditionsVersion); return hr; }
Console::teleporterTrgServeConnection(RTSOCKET Sock, void *pvUser) { TeleporterStateTrg *pState = (TeleporterStateTrg *)pvUser; pState->mhSocket = Sock; /* * Disable Nagle and say hello. */ int vrc = RTTcpSetSendCoalescing(pState->mhSocket, false /*fEnable*/); AssertRC(vrc); vrc = RTTcpWrite(Sock, g_szWelcome, sizeof(g_szWelcome) - 1); if (RT_FAILURE(vrc)) { LogRel(("Teleporter: Failed to write welcome message: %Rrc\n", vrc)); return VINF_SUCCESS; } /* * Password (includes '\n', see teleporterTrg). */ const char *pszPassword = pState->mstrPassword.c_str(); unsigned off = 0; while (pszPassword[off]) { char ch; vrc = RTTcpRead(Sock, &ch, sizeof(ch), NULL); if ( RT_FAILURE(vrc) || pszPassword[off] != ch) { if (RT_FAILURE(vrc)) LogRel(("Teleporter: Password read failure (off=%u): %Rrc\n", off, vrc)); else LogRel(("Teleporter: Invalid password (off=%u)\n", off)); teleporterTcpWriteNACK(pState, VERR_AUTHENTICATION_FAILURE); return VINF_SUCCESS; } off++; } vrc = teleporterTcpWriteACK(pState); if (RT_FAILURE(vrc)) return VINF_SUCCESS; /* * Update the progress bar, with peer name if available. */ HRESULT hrc; RTNETADDR Addr; vrc = RTTcpGetPeerAddress(Sock, &Addr); if (RT_SUCCESS(vrc)) { LogRel(("Teleporter: Incoming VM from %RTnaddr!\n", &Addr)); hrc = pState->mptrProgress->SetNextOperation(BstrFmt(tr("Teleporting VM from %RTnaddr"), &Addr).raw(), 8); } else { LogRel(("Teleporter: Incoming VM!\n")); hrc = pState->mptrProgress->SetNextOperation(Bstr(tr("Teleporting VM")).raw(), 8); } AssertMsg(SUCCEEDED(hrc) || hrc == E_FAIL, ("%Rhrc\n", hrc)); /* * Stop the server and cancel the timeout timer. * * Note! After this point we must return VERR_TCP_SERVER_STOP, while prior * to it we must not return that value! */ RTTcpServerShutdown(pState->mhServer); RTTimerLRDestroy(*pState->mphTimerLR); *pState->mphTimerLR = NIL_RTTIMERLR; /* * Command processing loop. */ bool fDone = false; for (;;) { char szCmd[128]; vrc = teleporterTcpReadLine(pState, szCmd, sizeof(szCmd)); if (RT_FAILURE(vrc)) break; if (!strcmp(szCmd, "load")) { vrc = teleporterTcpWriteACK(pState); if (RT_FAILURE(vrc)) break; int vrc2 = VMR3AtErrorRegisterU(pState->mpUVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2); RTSocketRetain(pState->mhSocket); /* For concurrent access by I/O thread and EMT. */ pState->moffStream = 0; void *pvUser2 = static_cast<void *>(static_cast<TeleporterState *>(pState)); vrc = VMR3LoadFromStream(VMR3GetVM(pState->mpUVM), &g_teleporterTcpOps, pvUser2, teleporterProgressCallback, pvUser2); RTSocketRelease(pState->mhSocket); vrc2 = VMR3AtErrorDeregister(VMR3GetVM(pState->mpUVM), Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2); if (RT_FAILURE(vrc)) { LogRel(("Teleporter: VMR3LoadFromStream -> %Rrc\n", vrc)); teleporterTcpWriteNACK(pState, vrc, pState->mErrorText.c_str()); break; } /* The EOS might not have been read, make sure it is. */ pState->mfStopReading = false; size_t cbRead; vrc = teleporterTcpOpRead(pvUser2, pState->moffStream, szCmd, 1, &cbRead); if (vrc != VERR_EOF) { LogRel(("Teleporter: Draining teleporterTcpOpRead -> %Rrc\n", vrc)); teleporterTcpWriteNACK(pState, vrc); break; } vrc = teleporterTcpWriteACK(pState); } else if (!strcmp(szCmd, "cancel")) { /* Don't ACK this. */ LogRel(("Teleporter: Received cancel command.\n")); vrc = VERR_SSM_CANCELLED; } else if (!strcmp(szCmd, "lock-media")) { hrc = pState->mpControl->LockMedia(); if (SUCCEEDED(hrc)) { pState->mfLockedMedia = true; vrc = teleporterTcpWriteACK(pState); } else { vrc = VERR_FILE_LOCK_FAILED; teleporterTcpWriteNACK(pState, vrc); } } else if ( !strcmp(szCmd, "hand-over-resume") || !strcmp(szCmd, "hand-over-paused")) { /* * Point of no return. * * Note! Since we cannot tell whether a VMR3Resume failure is * destructive for the source or not, we have little choice * but to ACK it first and take any failures locally. * * Ideally, we should try resume it first and then ACK (or * NACK) the request since this would reduce latency and * make it possible to recover from some VMR3Resume failures. */ if ( pState->mptrProgress->notifyPointOfNoReturn() && pState->mfLockedMedia) { vrc = teleporterTcpWriteACK(pState); if (RT_SUCCESS(vrc)) { if (!strcmp(szCmd, "hand-over-resume")) vrc = VMR3Resume(VMR3GetVM(pState->mpUVM)); else pState->mptrConsole->setMachineState(MachineState_Paused); fDone = true; break; } } else { vrc = pState->mfLockedMedia ? VERR_WRONG_ORDER : VERR_SSM_CANCELLED; teleporterTcpWriteNACK(pState, vrc); } } else { LogRel(("Teleporter: Unknown command '%s' (%.*Rhxs)\n", szCmd, strlen(szCmd), szCmd)); vrc = VERR_NOT_IMPLEMENTED; teleporterTcpWriteNACK(pState, vrc); } if (RT_FAILURE(vrc)) break; } if (RT_SUCCESS(vrc) && !fDone) vrc = VERR_WRONG_ORDER; if (RT_FAILURE(vrc)) teleporterTrgUnlockMedia(pState); pState->mRc = vrc; pState->mhSocket = NIL_RTSOCKET; LogFlowFunc(("returns mRc=%Rrc\n", vrc)); return VERR_TCP_SERVER_STOP; }
HRESULT HostNetworkInterface::enableStaticIPConfigV6(const com::Utf8Str &aIPV6Address, ULONG aIPV6NetworkMaskPrefixLength) { #ifndef VBOX_WITH_HOSTNETIF_API return E_NOTIMPL; #else if (aIPV6NetworkMaskPrefixLength > 128) return mVirtualBox->setErrorBoth(E_INVALIDARG, VERR_INVALID_PARAMETER, "Invalid IPv6 prefix length"); int rc; RTNETADDRIPV6 AddrOld, AddrNew; char *pszZoneIgnored; bool fAddrChanged; rc = RTNetStrToIPv6Addr(aIPV6Address.c_str(), &AddrNew, &pszZoneIgnored); if (RT_FAILURE(rc)) { return mVirtualBox->setErrorBoth(E_INVALIDARG, rc, "Invalid IPv6 address"); } rc = RTNetStrToIPv6Addr(com::Utf8Str(m.realIPV6Address).c_str(), &AddrOld, &pszZoneIgnored); if (RT_SUCCESS(rc)) { fAddrChanged = (AddrNew.s.Lo != AddrOld.s.Lo || AddrNew.s.Hi != AddrOld.s.Hi); } else { fAddrChanged = true; } if ( fAddrChanged || m.realIPV6PrefixLength != aIPV6NetworkMaskPrefixLength) { if (aIPV6NetworkMaskPrefixLength == 0) aIPV6NetworkMaskPrefixLength = 64; rc = NetIfEnableStaticIpConfigV6(mVirtualBox, this, m.IPV6Address.c_str(), aIPV6Address.c_str(), aIPV6NetworkMaskPrefixLength); if (RT_FAILURE(rc)) { LogRel(("Failed to EnableStaticIpConfigV6 with rc=%Rrc\n", rc)); return rc == VERR_NOT_IMPLEMENTED ? E_NOTIMPL : E_FAIL; } else { m.realIPV6Address = aIPV6Address; m.realIPV6PrefixLength = aIPV6NetworkMaskPrefixLength; #if defined(RT_OS_WINDOWS) saveAdapterConfigIPv6(Bstr(aIPV6Address).raw(), aIPV6NetworkMaskPrefixLength); #else /* !defined(RT_OS_WINDOWS) */ if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPV6Address", mInterfaceName.c_str()).raw(), Bstr(aIPV6Address).raw()))) return E_FAIL; if (FAILED(mVirtualBox->SetExtraData(BstrFmt("HostOnly/%s/IPV6NetMask", mInterfaceName.c_str()).raw(), BstrFmt("%u", aIPV6NetworkMaskPrefixLength).raw()))) #endif /* !defined(RT_OS_WINDOWS) */ return E_FAIL; } } return S_OK; #endif }