/* static */ GuestDnDMIMEList GuestDnD::toFilteredFormatList(const GuestDnDMIMEList &lstFormatsSupported, const com::Utf8Str &strFormatsWanted) { GuestDnDMIMEList lstFmt; RTCList<RTCString> lstFormats = strFormatsWanted.split("\r\n"); size_t i = 0; while (i < lstFormats.size()) { /* Only keep allowed format types. */ if (std::find(lstFormatsSupported.begin(), lstFormatsSupported.end(), lstFormats.at(i)) != lstFormatsSupported.end()) { lstFmt.push_back(lstFormats[i]); } i++; } return lstFmt; }
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 }
HRESULT StorageController::setName(const com::Utf8Str &aName) { /* the machine needs to be mutable */ AutoMutableStateDependency adep(m->pParent); if (FAILED(adep.rc())) return adep.rc(); AutoMultiWriteLock2 alock(m->pParent, this COMMA_LOCKVAL_SRC_POS); if (m->bd->strName != aName) { ComObjPtr<StorageController> ctrl; HRESULT rc = m->pParent->i_getStorageControllerByName(aName, ctrl, false /* aSetError */); if (SUCCEEDED(rc)) return setError(VBOX_E_OBJECT_IN_USE, tr("Storage controller named '%s' already exists"), aName.c_str()); Machine::MediumAttachmentList atts; rc = m->pParent->i_getMediumAttachmentsOfController(m->bd->strName, atts); for (Machine::MediumAttachmentList::const_iterator it = atts.begin(); it != atts.end(); ++it) { IMediumAttachment *iA = *it; MediumAttachment *pAttach = static_cast<MediumAttachment *>(iA); AutoWriteLock attlock(pAttach COMMA_LOCKVAL_SRC_POS); pAttach->i_updateName(aName); } m->bd.backup(); m->bd->strName = aName; m->pParent->i_setModified(Machine::IsModified_Storage); alock.release(); m->pParent->i_onStorageControllerChange(m->pParent->i_getId(), aName); } return S_OK; }
HRESULT DHCPServer::getMacOptions(const com::Utf8Str &aMAC, std::vector<com::Utf8Str> &aOption) { AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT hrc = S_OK; ComPtr<IMachine> machine; ComPtr<INetworkAdapter> nic; settings::VmSlot2OptionsIterator it; for(it = m->VmSlot2Options.begin(); it != m->VmSlot2Options.end(); ++it) { alock.release(); hrc = mVirtualBox->FindMachine(Bstr(it->first.VmName).raw(), machine.asOutParam()); alock.acquire(); if (FAILED(hrc)) continue; alock.release(); hrc = machine->GetNetworkAdapter(it->first.Slot, nic.asOutParam()); alock.acquire(); if (FAILED(hrc)) continue; com::Bstr mac; alock.release(); hrc = nic->COMGETTER(MACAddress)(mac.asOutParam()); alock.acquire(); if (FAILED(hrc)) /* no MAC address ??? */ break; if (!RTStrICmp(com::Utf8Str(mac).c_str(), aMAC.c_str())) return getVmSlotOptions(it->first.VmName, it->first.Slot, aOption); } /* end of for */ return hrc; }
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 }
HRESULT VRDEServer::setVRDEProperty(const com::Utf8Str &aKey, const com::Utf8Str &aValue) { LogFlowThisFunc(("\n")); /* the machine can also be in saved state for this property to change */ AutoMutableOrSavedOrRunningStateDependency adep(mParent); if (FAILED(adep.rc())) return adep.rc(); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /* Special processing for some "standard" properties. */ if (aKey == "TCP/Ports") { /* Verify the string. "0" means the default port. */ Utf8Str strPorts = aValue == "0"? VRDP_DEFAULT_PORT_STR: aValue; int vrc = i_vrdpServerVerifyPortsString(strPorts); if (RT_FAILURE(vrc)) return E_INVALIDARG; if (strPorts != mData->mProperties["TCP/Ports"]) { /* Port value is not verified here because it is up to VRDP transport to * use it. Specifying a wrong port number will cause a running server to * stop. There is no fool proof here. */ mData.backup(); mData->mProperties["TCP/Ports"] = strPorts; /* leave the lock before informing callbacks */ alock.release(); AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking mParent->i_setModified(Machine::IsModified_VRDEServer); mlock.release(); /* Avoid deadlock when i_onVRDEServerChange eventually calls SetExtraData. */ adep.release(); mParent->i_onVRDEServerChange(/* aRestart */ TRUE); } } else { /* Generic properties processing. * Look up the old value first; if nothing's changed then do nothing. */ Utf8Str strOldValue; settings::StringsMap::const_iterator it = mData->mProperties.find(aKey); if (it != mData->mProperties.end()) strOldValue = it->second; if (strOldValue != aValue) { if (aValue.isEmpty()) mData->mProperties.erase(aKey); else mData->mProperties[aKey] = aValue; /* leave the lock before informing callbacks */ alock.release(); AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); mParent->i_setModified(Machine::IsModified_VRDEServer); mlock.release(); /* Avoid deadlock when i_onVRDEServerChange eventually calls SetExtraData. */ adep.release(); mParent->i_onVRDEServerChange(/* aRestart */ TRUE); } } return S_OK; }
/** * Sets the general Guest Additions information like * API (interface) version and OS type. Gets called by * vmmdevUpdateGuestInfo. * * @param aInterfaceVersion * @param aOsType */ void Guest::i_setAdditionsInfo(com::Utf8Str aInterfaceVersion, VBOXOSTYPE aOsType) { RTTIMESPEC TimeSpecTS; RTTimeNow(&TimeSpecTS); AutoCaller autoCaller(this); AssertComRCReturnVoid(autoCaller.rc()); AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /* * Note: The Guest Additions API (interface) version is deprecated * and will not be used anymore! We might need it to at least report * something as version number if *really* ancient Guest Additions are * installed (without the guest version + revision properties having set). */ mData.mInterfaceVersion = aInterfaceVersion; /* * Older Additions rely on the Additions API version whether they * are assumed to be active or not. Since newer Additions do report * the Additions version *before* calling this function (by calling * VMMDevReportGuestInfo2, VMMDevReportGuestStatus, VMMDevReportGuestInfo, * in that order) we can tell apart old and new Additions here. Old * Additions never would set VMMDevReportGuestInfo2 (which set mData.mAdditionsVersion) * so they just rely on the aInterfaceVersion string (which gets set by * VMMDevReportGuestInfo). * * So only mark the Additions as being active (run level = system) when we * don't have the Additions version set. */ if (mData.mAdditionsVersionNew.isEmpty()) { if (aInterfaceVersion.isEmpty()) mData.mAdditionsRunLevel = AdditionsRunLevelType_None; else { mData.mAdditionsRunLevel = AdditionsRunLevelType_System; /* * To keep it compatible with the old Guest Additions behavior we need to set the * "graphics" (feature) facility to active as soon as we got the Guest Additions * interface version. */ i_facilityUpdate(VBoxGuestFacilityType_Graphics, VBoxGuestFacilityStatus_Active, 0 /*fFlags*/, &TimeSpecTS); } } /* * Older Additions didn't have this finer grained capability bit, * so enable it by default. Newer Additions will not enable this here * and use the setSupportedFeatures function instead. */ /** @todo r=bird: I don't get the above comment nor the code below... * One talks about capability bits, the one always does something to a facility. * Then there is the comment below it all, which is placed like it addresses the * mOSTypeId, but talks about something which doesn't remotely like mOSTypeId... * * Andy, could you please try clarify and make the comments shorter and more * coherent! Also, explain why this is important and what depends on it. * * PS. There is the VMMDEV_GUEST_SUPPORTS_GRAPHICS capability* report... It * should come in pretty quickly after this update, normally. */ i_facilityUpdate(VBoxGuestFacilityType_Graphics, i_facilityIsActive(VBoxGuestFacilityType_VBoxGuestDriver) ? VBoxGuestFacilityStatus_Active : VBoxGuestFacilityStatus_Inactive, 0 /*fFlags*/, &TimeSpecTS); /** @todo the timestamp isn't gonna be right here on saved state restore. */ /* * Note! There is a race going on between setting mAdditionsRunLevel and * mSupportsGraphics here and disabling/enabling it later according to * its real status when using new(er) Guest Additions. */ mData.mOSType = aOsType; mData.mOSTypeId = Global::OSTypeId(aOsType); }
HRESULT GuestDnDSource::drop(const com::Utf8Str &aFormat, DnDAction_T aAction, ComPtr<IProgress> &aProgress) { #if !defined(VBOX_WITH_DRAG_AND_DROP) || !defined(VBOX_WITH_DRAG_AND_DROP_GH) ReturnComNotImplemented(); #else /* VBOX_WITH_DRAG_AND_DROP */ /* Input validation. */ if (RT_UNLIKELY((aFormat.c_str()) == NULL || *(aFormat.c_str()) == '\0')) return setError(E_INVALIDARG, tr("No drop format specified")); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); uint32_t uAction = GuestDnD::toHGCMAction(aAction); /* If there is no usable action, ignore this request. */ if (isDnDIgnoreAction(uAction)) return S_OK; HRESULT hr = S_OK; const char *pcszFormat = aFormat.c_str(); bool fNeedsDropDir = DnDMIMENeedsDropDir(pcszFormat, strlen(pcszFormat)); LogFlowFunc(("strFormat=%s, uAction=0x%x, fNeedsDropDir=%RTbool\n", pcszFormat, uAction, fNeedsDropDir)); GuestDnDResponse *pResp = GuestDnDInst()->response(); if (pResp) { /* Reset any old data. */ pResp->reset(); pResp->resetProgress(m_pGuest); /* Set the format we are going to retrieve to have it around * when retrieving the data later. */ pResp->setFormat(aFormat); if (fNeedsDropDir) { char szDropDir[RTPATH_MAX]; int rc = DnDDirCreateDroppedFiles(szDropDir, sizeof(szDropDir)); LogFlowFunc(("rc=%Rrc, szDropDir=%s\n", rc, szDropDir)); if (RT_FAILURE(rc)) return setError(VBOX_E_IPRT_ERROR, tr("Unable to create the temporary drag and drop directory \"%s\" (%Rrc)\n"), szDropDir, rc); pResp->setDropDir(szDropDir); } VBOXHGCMSVCPARM paParms[4]; int i = 0; paParms[i++].setPointer((void*)aFormat.c_str(), (uint32_t)aFormat.length() + 1); paParms[i++].setUInt32((uint32_t)aFormat.length() + 1); paParms[i++].setUInt32(uAction); int rc = GuestDnDInst()->hostCall(DragAndDropSvc::HOST_DND_GH_EVT_DROPPED, i, paParms); if (RT_SUCCESS(rc)) { /* Query the progress object to the caller. */ pResp->queryProgressTo(aProgress.asOutParam()); } else hr = setError(VBOX_E_IPRT_ERROR, tr("Error signalling to drop data (%Rrc)\n"), rc); } LogFlowFunc(("Returning hr=%Rhrc\n", hr)); return hr; #endif /* VBOX_WITH_DRAG_AND_DROP */ }
HRESULT SystemProperties::setLoggingLevel(const com::Utf8Str &aLoggingLevel) { AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); HRESULT rc = i_setLoggingLevel(aLoggingLevel); alock.release(); if (SUCCEEDED(rc)) { AutoWriteLock vboxLock(mParent COMMA_LOCKVAL_SRC_POS); rc = mParent->i_saveSettings(); } else LogRel(("Cannot set passed logging level=%s, or the default one - Error=%Rhrc \n", aLoggingLevel.c_str(), rc)); return rc; }
// implementation of public methods ///////////////////////////////////////////////////////////////////////////// HRESULT Guest::createSession(const com::Utf8Str &aUser, const com::Utf8Str &aPassword, const com::Utf8Str &aDomain, const com::Utf8Str &aSessionName, ComPtr<IGuestSession> &aGuestSession) { #ifndef VBOX_WITH_GUEST_CONTROL ReturnComNotImplemented(); #else /* VBOX_WITH_GUEST_CONTROL */ AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); /* Do not allow anonymous sessions (with system rights) with public API. */ if (RT_UNLIKELY(!aUser.length())) return setError(E_INVALIDARG, tr("No user name specified")); LogFlowFuncEnter(); GuestSessionStartupInfo startupInfo; startupInfo.mName = aSessionName; GuestCredentials guestCreds; guestCreds.mUser = aUser; guestCreds.mPassword = aPassword; guestCreds.mDomain = aDomain; ComObjPtr<GuestSession> pSession; int vrc = i_sessionCreate(startupInfo, guestCreds, pSession); if (RT_SUCCESS(vrc)) { /* Return guest session to the caller. */ HRESULT hr2 = pSession.queryInterfaceTo(aGuestSession.asOutParam()); if (FAILED(hr2)) vrc = VERR_COM_OBJECT_NOT_FOUND; } if (RT_SUCCESS(vrc)) /* Start (fork) the session asynchronously * on the guest. */ vrc = pSession->i_startSessionAsync(); HRESULT hr = S_OK; if (RT_FAILURE(vrc)) { switch (vrc) { case VERR_MAX_PROCS_REACHED: hr = setErrorBoth(VBOX_E_MAXIMUM_REACHED, vrc, tr("Maximum number of concurrent guest sessions (%d) reached"), VBOX_GUESTCTRL_MAX_SESSIONS); break; /** @todo Add more errors here. */ default: hr = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Could not create guest session: %Rrc"), vrc); break; } } LogFlowThisFunc(("Returning rc=%Rhrc\n", hr)); return hr; #endif /* VBOX_WITH_GUEST_CONTROL */ }
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 }
int DHCPServer::addOption(settings::DhcpOptionMap &aMap, DhcpOpt_T aOption, const com::Utf8Str &aValue) { settings::DhcpOptValue OptValue; if (aOption != 0) { OptValue = settings::DhcpOptValue(aValue, DhcpOptEncoding_Legacy); } /* * This is a kludge to sneak in option encoding information * through existing API. We use option 0 and supply the real * option/value in the same format that encodeOption() above * produces for getter methods. */ else { uint8_t u8Code; uint32_t u32Enc; char *pszNext; int rc; rc = RTStrToUInt8Ex(aValue.c_str(), &pszNext, 10, &u8Code); if (!RT_SUCCESS(rc)) return VERR_PARSE_ERROR; switch (*pszNext) { case ':': /* support legacy format too */ { u32Enc = DhcpOptEncoding_Legacy; break; } case '=': { u32Enc = DhcpOptEncoding_Hex; break; } case '@': { rc = RTStrToUInt32Ex(pszNext + 1, &pszNext, 10, &u32Enc); if (!RT_SUCCESS(rc)) return VERR_PARSE_ERROR; if (*pszNext != '=') return VERR_PARSE_ERROR; break; } default: return VERR_PARSE_ERROR; } aOption = (DhcpOpt_T)u8Code; OptValue = settings::DhcpOptValue(pszNext + 1, (DhcpOptEncoding_T)u32Enc); } aMap[aOption] = OptValue; return VINF_SUCCESS; }