ConsoleImpl.cpp revision 96788c1af55ead9aaa2d17035c3777f2ea73023c
615eff12e0e3565c52758292e10080a25d872941William King * VBox Console COM Class implementation
15a44745412679c30a6d022733925af70a38b715David Lawrence * Copyright (C) 2006-2009 Sun Microsystems, Inc.
15a44745412679c30a6d022733925af70a38b715David Lawrence * This file is part of VirtualBox Open Source Edition (OSE), as
15a44745412679c30a6d022733925af70a38b715David Lawrence * available from http://www.virtualbox.org. This file is free software;
15a44745412679c30a6d022733925af70a38b715David Lawrence * you can redistribute it and/or modify it under the terms of the GNU
15a44745412679c30a6d022733925af70a38b715David Lawrence * General Public License (GPL) as published by the Free Software
15a44745412679c30a6d022733925af70a38b715David Lawrence * Foundation, in version 2 as it comes in the "COPYING" file of the
615eff12e0e3565c52758292e10080a25d872941William King * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
615eff12e0e3565c52758292e10080a25d872941William King * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
615eff12e0e3565c52758292e10080a25d872941William King * Clara, CA 95054 USA or visit http://www.sun.com if you need
615eff12e0e3565c52758292e10080a25d872941William King * additional information or have any questions.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence/** @todo Move the TAP mess back into the driver! */
615eff12e0e3565c52758292e10080a25d872941William King// generated header
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence#include <VBox/HostServices/VBoxClipboardSvc.h>
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence# include <VBox/HostServices/GuestPropertySvc.h>
b869f35f43100c71c6d06bd23934b4a2c5ed4cb7Brian Wellington// VMTask and friends
b869f35f43100c71c6d06bd23934b4a2c5ed4cb7Brian Wellington////////////////////////////////////////////////////////////////////////////////
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington * Task structure for asynchronous VM operations.
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington * Once created, the task structure adds itself as a Console caller. This means:
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington * 1. The user must check for #rc() before using the created structure
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington * (e.g. passing it as a thread function argument). If #rc() returns a
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington * failure, the Console object may not be used by the task (see
b869f35f43100c71c6d06bd23934b4a2c5ed4cb7Brian Wellington * Console::addCaller() for more details).
b869f35f43100c71c6d06bd23934b4a2c5ed4cb7Brian Wellington * 2. On successful initialization, the structure keeps the Console caller
b869f35f43100c71c6d06bd23934b4a2c5ed4cb7Brian Wellington * until destruction (to ensure Console remains in the Ready state and won't
615eff12e0e3565c52758292e10080a25d872941William King * be accidentally uninitialized). Forgetting to delete the created task
b3ef06344abad0105be99b622e615dcbd87911e1Brian Wellington * will lead to Console::uninit() stuck waiting for releasing all added
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington * If \a aUsesVMPtr parameter is true, the task structure will also add itself
615eff12e0e3565c52758292e10080a25d872941William King * as a Console::mpVM caller with the same meaning as above. See
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence * Console::addVMCaller() for more info.
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington bool isOk() const { return SUCCEEDED(rc()); }
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington /** Releases the Console caller before destruction. Not normally necessary. */
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington /** Releases the VM caller before destruction. Not normally necessary. */
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellingtonstruct VMTakeSnapshotTask : public VMProgressTask
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington : VMProgressTask(aConsole, aProgress, false /* aUsesVMPtr */),
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington Bstr bstrSavedStateFile; // received from BeginTakeSnapshot()
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellingtonstruct VMPowerUpTask : public VMProgressTask
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington : VMProgressTask(aConsole, aProgress, false /* aUsesVMPtr */),
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington Console::SharedFolderDataMap mSharedFolders;
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington typedef std::list< ComPtr<IMedium> > HardDiskList;
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington /* array of progress objects for hard disk reset operations */
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington typedef std::list< ComPtr<IProgress> > ProgressList;
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington VMSaveTask(Console *aConsole, Progress *aProgress)
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington : VMProgressTask(aConsole, aProgress, true /* aUsesVMPtr */),
615eff12e0e3565c52758292e10080a25d872941William King// constructor / destructor
a9bc95f22ef2dd4a12e79be99412c9f18b814a5dBrian Wellington/////////////////////////////////////////////////////////////////////////////
615eff12e0e3565c52758292e10080a25d872941William King for (ULONG slot = 0; slot < SchemaDefs::NetworkAdapterCount; ++slot)
615eff12e0e3565c52758292e10080a25d872941William King meAttachmentType[slot] = NetworkAttachmentType_Null;
615eff12e0e3565c52758292e10080a25d872941William King memset(mapNetworkLeds, 0, sizeof(mapNetworkLeds));
615eff12e0e3565c52758292e10080a25d872941William King memset(&mapSharedFolderLed, 0, sizeof(mapSharedFolderLed));
615eff12e0e3565c52758292e10080a25d872941William King// public initializer/uninitializer for internal purposes only
615eff12e0e3565c52758292e10080a25d872941William King/////////////////////////////////////////////////////////////////////////////
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian WellingtonHRESULT Console::init(IMachine *aMachine, IInternalMachineControl *aControl)
615eff12e0e3565c52758292e10080a25d872941William King AssertReturn(aMachine && aControl, E_INVALIDARG);
615eff12e0e3565c52758292e10080a25d872941William King /* Enclose the state transition NotReady->InInit->Ready */
7c37bc1a67a80209e05f6b1c01fa7fde7d0dd200Brian Wellington LogFlowThisFunc(("aMachine=%p, aControl=%p\n", aMachine, aControl));
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence memset(&mCallbackData, 0, sizeof(mCallbackData));
615eff12e0e3565c52758292e10080a25d872941William King /* Cache essential properties and objects */
615eff12e0e3565c52758292e10080a25d872941William King rc = mMachine->COMGETTER(State)(&mMachineState);
615eff12e0e3565c52758292e10080a25d872941William King rc = mMachine->COMGETTER(VRDPServer)(unconst(mVRDPServer).asOutParam());
1b6d529cb5ee0ad44f8518e1b8c2cbca54bbdf18David Lawrence /* Create associated child COM objects */
615eff12e0e3565c52758292e10080a25d872941William King /* Grab global and machine shared folder lists */
79d91e915023ffa5fac1bb2f91f19210bb18407cBrian Wellington /* Create other child objects */
79d91e915023ffa5fac1bb2f91f19210bb18407cBrian Wellington unconst(mConsoleVRDPServer) = new ConsoleVRDPServer(this);
b869f35f43100c71c6d06bd23934b4a2c5ed4cb7Brian Wellington unconst(mAudioSniffer) = new AudioSniffer(this);
b869f35f43100c71c6d06bd23934b4a2c5ed4cb7Brian Wellington /* Confirm a successful initialization when it's the case */
79d91e915023ffa5fac1bb2f91f19210bb18407cBrian Wellington * Uninitializes the Console object.
a9bc95f22ef2dd4a12e79be99412c9f18b814a5dBrian Wellington /* Enclose the state transition Ready->InUninit->NotReady */
a7d792804f564aa0889a94f64913b11bffd9738cBrian Wellington LogFlowThisFunc(("Already uninitialized.\n"));
0942b8e0d660895ae96ffbd447fd0290fe60539cMichael Graff LogFlowThisFunc(("initFailed()=%d\n", autoUninitSpan.initFailed()));
0942b8e0d660895ae96ffbd447fd0290fe60539cMichael Graff * Uninit all children that use addDependentChild()/removeDependentChild()
a9bc95f22ef2dd4a12e79be99412c9f18b814a5dBrian Wellington * in their init()/uninit() methods.
11836b7a55fa62ee6628e4e41845a0ef7084e383David Lawrence /* power down the VM if necessary */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King /* Release all callbacks. Do this after uninitializing the components,
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King * as some of them are well-behaved and unregister their callbacks.
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King * These would trigger error messages complaining about trying to
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King * unregister a non-registered callback. */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King /* dynamically allocated members of mCallbackData are uninitialized
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King * at the end of powerDown() */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King Assert(!mCallbackData.mpsc.valid && mCallbackData.mpsc.shape == NULL);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King HRESULT hrc = mMachine->GetExtraData(Bstr("VBoxInternal2/EnableGuestPropertiesVRDP"), value.asOutParam());
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King return true;
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King return false;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencevoid Console::updateGuestPropertiesVRDPLogon(uint32_t u32ClientId, const char *pszUser, const char *pszDomain)
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King rc = RTStrAPrintf(&pszPropertyName, "/VirtualBox/HostInfo/VRDP/Client/%u/Name", u32ClientId);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King mRemoteDisplayInfo->COMGETTER(ClientName)(clientName.asOutParam());
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King mMachine->SetGuestProperty(Bstr(pszPropertyName), clientName, Bstr("RDONLYGUEST"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King rc = RTStrAPrintf(&pszPropertyName, "/VirtualBox/HostInfo/VRDP/Client/%u/User", u32ClientId);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence mMachine->SetGuestProperty(Bstr(pszPropertyName), Bstr(pszUser), Bstr("RDONLYGUEST"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King rc = RTStrAPrintf(&pszPropertyName, "/VirtualBox/HostInfo/VRDP/Client/%u/Domain", u32ClientId);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King mMachine->SetGuestProperty(Bstr(pszPropertyName), Bstr(pszDomain), Bstr("RDONLYGUEST"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King rc = RTStrAPrintf(&pszClientId, "%d", u32ClientId);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/VRDP/LastConnectedClient"), Bstr(pszClientId), Bstr("RDONLYGUEST"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William Kingvoid Console::updateGuestPropertiesVRDPDisconnect(uint32_t u32ClientId)
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King rc = RTStrAPrintf(&pszPropertyName, "/VirtualBox/HostInfo/VRDP/Client/%u/Name", u32ClientId);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King mMachine->SetGuestProperty(Bstr(pszPropertyName), Bstr(""), Bstr("RDONLYGUEST"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King rc = RTStrAPrintf(&pszPropertyName, "/VirtualBox/HostInfo/VRDP/Client/%u/User", u32ClientId);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King mMachine->SetGuestProperty(Bstr(pszPropertyName), Bstr(""), Bstr("RDONLYGUEST"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King rc = RTStrAPrintf(&pszPropertyName, "/VirtualBox/HostInfo/VRDP/Client/%u/Domain", u32ClientId);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King mMachine->SetGuestProperty(Bstr(pszPropertyName), Bstr(""), Bstr("RDONLYGUEST"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King rc = RTStrAPrintf(&pszClientId, "%d", u32ClientId);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence mMachine->SetGuestProperty(Bstr("/VirtualBox/HostInfo/VRDP/LastDisconnectedClient"), Bstr(pszClientId), Bstr("RDONLYGUEST"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King#endif /* VBOX_WITH_GUEST_PROPS */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William Kingint Console::VRDPClientLogon(uint32_t u32ClientId, const char *pszUser, const char *pszPassword, const char *pszDomain)
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King LogFlowFunc(("%d, %s, %s, %s\n", u32ClientId, pszUser, pszPassword, pszDomain));
a9bc95f22ef2dd4a12e79be99412c9f18b814a5dBrian Wellington /* Console has been already uninitialized, deny request */
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington LogRel(("VRDPAUTH: Access denied (Console uninitialized).\n"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King HRESULT hrc = mMachine->COMGETTER(Id)(id.asOutParam());
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King hrc = mVRDPServer->COMGETTER(AuthType)(&authType);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King hrc = mVRDPServer->COMGETTER(AuthTimeout)(&authTimeout);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King VRDPAuthGuestJudgement guestJudgement = VRDPAuthGuestNotAsked;
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King LogRel(("VRDPAUTH: User: [%s]. Domain: [%s]. Authentication type: [%s]\n",
fa6c5e38f4b904aa85f3375f1ca830d4bf8f5877Andreas Gustafsson /* Call the external library. */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King result = mConsoleVRDPServer->Authenticate(uuid, guestJudgement, pszUser, pszPassword, pszDomain, u32ClientId);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence LogFlowFunc(("External auth asked for guest judgement\n"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King } /* pass through */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King /* Issue the request to guest. Assume that the call does not require EMT. It should not. */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King /* Ask the guest to judge these credentials. */
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington uint32_t u32GuestFlags = VMMDEV_SETCREDENTIALS_JUDGE;
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington int rc = mVMMDev->getVMMDevPort()->pfnSetCredentials(mVMMDev->getVMMDevPort(),
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington pszUser, pszPassword, pszDomain, u32GuestFlags);
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington /* Wait for guest. */
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington rc = mVMMDev->WaitCredentialsJudgement(authTimeout, &u32GuestFlags);
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington switch (u32GuestFlags & (VMMDEV_CREDENTIALS_JUDGE_OK | VMMDEV_CREDENTIALS_JUDGE_DENY | VMMDEV_CREDENTIALS_JUDGE_NOJUDGEMENT))
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington case VMMDEV_CREDENTIALS_JUDGE_DENY: guestJudgement = VRDPAuthGuestAccessDenied; break;
b3ef06344abad0105be99b622e615dcbd87911e1Brian Wellington case VMMDEV_CREDENTIALS_JUDGE_NOJUDGEMENT: guestJudgement = VRDPAuthGuestNoJudgement; break;
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington case VMMDEV_CREDENTIALS_JUDGE_OK: guestJudgement = VRDPAuthGuestAccessGranted; break;
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington LogFlowFunc(("Invalid guest flags %08X!!!\n", u32GuestFlags)); break;
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King LogFlowFunc(("Wait for credentials judgement rc = %Rrc!!!\n", rc));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King LogFlowFunc(("Guest judgement %d\n", guestJudgement));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King LogFlowFunc(("Could not set credentials rc = %Rrc!!!\n", rc));
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington LogRel(("VRDPAUTH: Guest judgement %d.\n", guestJudgement));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King LogFlowFunc(("External auth called again with guest judgement = %d\n", guestJudgement));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King result = mConsoleVRDPServer->Authenticate(uuid, guestJudgement, pszUser, pszPassword, pszDomain, u32ClientId);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King /* Reject. */
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington /* Multiconnection check must be made after authentication, so bad clients would not interfere with a good one. */
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington hrc = mVRDPServer->COMGETTER(AllowMultiConnection)(&allowMultiConnection);
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington AssertComRCReturn(hrc, VERR_ACCESS_DENIED);
b3ef06344abad0105be99b622e615dcbd87911e1Brian Wellington hrc = mVRDPServer->COMGETTER(ReuseSingleConnection)(&reuseSingleConnection);
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington AssertComRCReturn(hrc, VERR_ACCESS_DENIED);
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington LogFlowFunc(("allowMultiConnection %d, reuseSingleConnection = %d, mcVRDPClients = %d, mu32SingleRDPClientId = %d\n", allowMultiConnection, reuseSingleConnection, mcVRDPClients, mu32SingleRDPClientId));
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington /* Note: the 'mcVRDPClients' variable is incremented in ClientConnect callback, which is called when the client
fa6c5e38f4b904aa85f3375f1ca830d4bf8f5877Andreas Gustafsson * is successfully connected, that is after the ClientLogon callback. Therefore the mcVRDPClients
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King * value is 0 for first client.
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King /* There is a client already.
4fe8755480c108a1232b7189fd5434ab35a6b623Brian Wellington * If required drop the existing client connection and let the connecting one in.
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King LogRel(("VRDPAUTH: Multiple connections are not enabled. Disconnecting existing client.\n"));
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King mConsoleVRDPServer->DisconnectClient(mu32SingleRDPClientId, false);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King /* Reject. */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King LogRel(("VRDPAUTH: Multiple connections are not enabled. Access denied.\n"));
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /* Save the connected client id. From now on it will be necessary to disconnect this one. */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King updateGuestPropertiesVRDPLogon(u32ClientId, pszUser, pszDomain);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King#endif /* VBOX_WITH_GUEST_PROPS */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William Kingvoid Console::VRDPClientConnect(uint32_t u32ClientId)
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King uint32_t u32Clients = ASMAtomicIncU32(&mcVRDPClients);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King true, VRDP_EXPERIENCE_LEVEL_FULL); // @todo configurable
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King#endif /* VBOX_WITH_VRDP */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William Kingvoid Console::VRDPClientDisconnect(uint32_t u32ClientId,
79d91e915023ffa5fac1bb2f91f19210bb18407cBrian Wellington uint32_t u32Clients = ASMAtomicDecU32(&mcVRDPClients);
79d91e915023ffa5fac1bb2f91f19210bb18407cBrian Wellington pfnVRDPChange(getVMMDev()->getVMMDevPort(),
b869f35f43100c71c6d06bd23934b4a2c5ed4cb7Brian Wellington#endif /* VBOX_WITH_VRDP */
b869f35f43100c71c6d06bd23934b4a2c5ed4cb7Brian Wellington if (fu32Intercepted & VRDP_CLIENT_INTERCEPT_USB)
b869f35f43100c71c6d06bd23934b4a2c5ed4cb7Brian Wellington mConsoleVRDPServer->USBBackendDelete(u32ClientId);
79d91e915023ffa5fac1bb2f91f19210bb18407cBrian Wellington if (fu32Intercepted & VRDP_CLIENT_INTERCEPT_CLIPBOARD)
79d91e915023ffa5fac1bb2f91f19210bb18407cBrian Wellington mConsoleVRDPServer->ClipboardDelete(u32ClientId);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King if (fu32Intercepted & VRDP_CLIENT_INTERCEPT_AUDIO)
79d91e915023ffa5fac1bb2f91f19210bb18407cBrian Wellington PPDMIAUDIOSNIFFERPORT port = mAudioSniffer->getAudioSnifferPort();
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King#endif /* VBOX_WITH_VRDP */
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King HRESULT hrc = mMachine->COMGETTER(Id)(uuid.asOutParam());
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King hrc = mVRDPServer->COMGETTER(AuthType)(&authType);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King mConsoleVRDPServer->AuthDisconnect(uuid, u32ClientId);
615eff12e0e3565c52758292e10080a25d872941William King updateGuestPropertiesVRDPDisconnect(u32ClientId);
e5966f9b9a13fc83afaf9b74ac1f7eea6a647817William King#endif /* VBOX_WITH_GUEST_PROPS */
#ifdef VBOX_WITH_VRDP
++mcAudioRefs;
if (mAudioSniffer)
if (port)
#ifdef VBOX_WITH_VRDP
return S_OK;
return rc;
mSavedStateDataLoaded = true;
return rc;
DECLCALLBACK(void)
++ it)
DECLCALLBACK(int)
return VERR_VERSION_MISMATCH;
bool writable = true;
delete[] buf;
delete[] buf;
return VINF_SUCCESS;
#ifdef VBOX_WITH_GUEST_PROPS
DECLCALLBACK(int)
using namespace guestProp;
// LogFlowFunc(("pCBData->pcszName=%s, pCBData->pcszValue=%s, pCBData->pcszFlags=%s\n", pCBData->pcszName, pCBData->pcszValue, pCBData->pcszFlags));
flags);
return rc;
using namespace guestProp;
return E_OUTOFMEMORY;
&parm[0]);
const char *pszBuf
unsigned cEntries = 0;
++cEntries;
for (unsigned i = 0; i < cEntries; ++i)
return S_OK;
return E_FAIL;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
return S_OK;
if (!mDebugger)
return S_OK;
return S_OK;
STDMETHODIMP Console::COMGETTER(RemoteUSBDevices)(ComSafeArrayOut(IHostUSBDevice *, aRemoteUSBDevices))
return S_OK;
return S_OK;
return S_OK;
return E_POINTER;
switch (mMachineState)
case MachineState_Running:
case MachineState_Paused:
case MachineState_Stuck:
case MachineState_Teleporting:
case MachineState_Saved:
case MachineState_Stopping:
return S_OK;
vrc);
return rc;
switch (mMachineState)
case MachineState_Running:
case MachineState_Teleporting:
case MachineState_Paused:
return hrc;
int vrc;
vrc);
return rc;
vrc);
return rc;
bool handled = false;
vrc);
return rc;
bool entered = false;
return S_OK;
vrc);
return rc;
bool fBeganSavingState = false;
bool fTaskCreationFailed = false;
fTaskCreationFailed = true;
fBeganSavingState = true;
if (fBeganSavingState)
Resume();
return rc;
tr("Cannot adopt the saved machine state as the machine is not in Powered Off, Teleported or Aborted state (machine state: %s)"),
tr("Cannot discard the machine state as the machine is not in the saved state (machine state: %s)"),
return rc;
if (!pLed)
return u32;
switch (aDeviceType)
case DeviceType_Floppy:
case DeviceType_DVD:
case DeviceType_HardDisk:
case DeviceType_Network:
case DeviceType_USB:
case DeviceType_SharedFolder:
case PDMLED_READING:
case PDMLED_WRITING:
return S_OK;
#ifdef VBOX_WITH_USB
return rc;
#ifdef VBOX_WITH_USB
++ it;
if (!device)
return rc2;
return rc;
#ifdef VBOX_WITH_USB
aAddress);
return E_NOTIMPL;
#ifdef VBOX_WITH_USB
return E_NOTIMPL;
tr("Cannot create a transient shared folder on the machine while it is changing the state (machine state: %s)"),
aName);
return rc;
tr("Cannot remove a transient shared folder from the machine while it is changing the state (machine state: %s)"),
return rc;
for (size_t i = 0;
++cOperations;
// b) one extra sub-operations for online snapshots OR offline snapshots that have a saved state (needs to be copied)
bool fTakingSnapshotOnline = ((mMachineState == MachineState_Running) || (mMachineState == MachineState_Paused));
LogFlowFunc(("fTakingSnapshotOnline = %d, mMachineState = %d\n", fTakingSnapshotOnline, mMachineState));
++cOperations;
return VERR_NO_MEMORY;
(void*)pTask,
vrc);
delete pTask;
return rc;
return S_OK;
return S_OK;
#if 0 /** @todo r=bird,r=pritesh: must check that the interface id match correct or we might screw up with old code! */
void *dummy;
return hrc;
return S_OK;
return S_OK;
switch (enmCtrlType)
return NULL;
HRESULT Console::convertBusPortDeviceToLun(StorageBus_T enmBus, LONG port, LONG device, unsigned &uLun)
switch (enmBus)
case StorageBus_IDE:
case StorageBus_Floppy:
return S_OK;
case StorageBus_SATA:
case StorageBus_SCSI:
return S_OK;
uLun = 0;
unsigned uInstance = 0;
unsigned uLun = 0;
uInstance = 0;
this, pszDevice, uInstance, uLun, !!fHostDrive, location.raw(), format.raw(), !!fPassthrough, fForce);
return S_OK;
vrc);
* @todo the error handling in this method needs to be improved seriously - what if mounting fails...
DECLCALLBACK(int) Console::changeDrive(Console *pThis, const char *pszDevice, unsigned uInstance, unsigned uLun,
/// @todo change this to use the same code as in ConsoleImpl2.cpp
LogFlowFunc(("pThis=%p pszDevice=%p:{%s} uInstance=%u uLun=%u fHostDrive=%d pszPath=%p:{%s} pszFormat=%p:{%s} fPassthrough=%d fForce=%d\n",
pThis, pszDevice, pszDevice, uInstance, uLun, fHostDrive, pszPath, pszPath, pszFormat, pszFormat, fPassthrough, fForce));
bool fResume;
switch (enmVMState)
case VMSTATE_RESETTING:
case VMSTATE_RUNNING:
fResume = true;
case VMSTATE_SUSPENDED:
case VMSTATE_CREATED:
case VMSTATE_OFF:
fResume = false;
case VMSTATE_RUNNING_LS:
indirectly modify the meDVDState/meFloppyState members (pointed to by
if (fHostDrive)
rc = CFGMR3InsertString(pLunL0, "Driver", !strcmp(pszDevice, "i82078") ? "HostFloppy" : "HostDVD"); RC_CHECK();
rc = CFGMR3InsertString(pCfg, "Type", !strcmp(pszDevice, "i82078") ? "Floppy 1.44" : "DVD"); RC_CHECK();
rc = PDMR3DeviceAttach(pVM, pszDevice, uInstance, uLun, PDM_TACH_FLAGS_NOT_HOT_PLUG, &pBase); RC_CHECK();
if (!pIMount)
AssertFailed();
return rc;
if (fResume)
return rcRet;
if (!mpVM)
return S_OK;
switch (adapterType)
#ifdef VBOX_WITH_E1000
#ifdef VBOX_WITH_VIRTIO
AssertFailed();
if (pINetCfg)
#ifdef VBOX_DYNAMIC_NET_ATTACH
if ( enmVMState == VMSTATE_RUNNING /** @todo LiveMigration: Forbit or deal correctly with the _LS variants */
return rc;
#ifdef VBOX_DYNAMIC_NET_ATTACH
unsigned uInstance,
unsigned uLun,
return S_OK;
vrc);
const char *pszDevice,
unsigned uInstance,
unsigned uLun,
AssertMsg( (!strcmp(pszDevice, "pcnet") && uLun == 0 && uInstance < SchemaDefs::NetworkAdapterCount)
bool fResume;
switch (enmVMState)
case VMSTATE_RESETTING:
case VMSTATE_RUNNING:
fResume = true;
case VMSTATE_SUSPENDED:
case VMSTATE_CREATED:
case VMSTATE_OFF:
fResume = false;
rcRet = configNetwork(pThis, pszDevice, uInstance, uLun, aNetworkAdapter, pCfg, pLunL0, pInst, true);
if (fResume)
return rcRet;
if (!mpVM)
return S_OK;
return rc;
if (!mpVM)
return S_OK;
return rc;
if (!mpVM)
return S_OK;
return rc;
if (!mpVM)
return S_OK;
return rc;
if ( mVRDPServer
if (vrdpEnabled)
return rc;
if (!mpVM)
return S_OK;
return rc;
return rc;
HRESULT Console::onUSBDeviceAttach(IUSBDevice *aDevice, IVirtualBoxErrorInfo *aError, ULONG aMaskedIfs)
#ifdef VBOX_WITH_USB
return S_OK;
return E_FAIL;
return rc;
return E_FAIL;
#ifdef VBOX_WITH_USB
++ it;
return S_OK;
return rc;
return E_FAIL;
#ifndef VBOX_WITH_GUEST_PROPS
return E_INVALIDARG;
return E_POINTER;
return E_POINTER;
return E_POINTER;
using namespace guestProp;
vrc);
return rc;
#ifndef VBOX_WITH_GUEST_PROPS
return E_INVALIDARG;
return E_INVALIDARG;
return E_INVALIDARG;
using namespace guestProp;
vrc);
return rc;
#ifndef VBOX_WITH_GUEST_PROPS
return E_POINTER;
return E_POINTER;
return E_POINTER;
return E_POINTER;
return E_POINTER;
, E_FAIL);
void *pShape)
if (!wasValid)
*aWinId = 0;
if (aCheck)
return rc;
return rc;
if (*aWinId == 0)
return S_OK;
if (mVMDestroying)
++ mVMCallers;
return S_OK;
--mVMCallers;
if (uLogHistoryCount)
#ifdef VBOX_BLEEDING_EDGE
#ifdef VBOX_OSE
RTProcSelf(),
return hrc;
return E_POINTER;
if (!enabled)
switch (netattach)
#ifdef RT_OS_WINDOWS
if (!hostif)
tr("VM cannot start because the saved state file '%ls' is invalid (%Rrc). Discard the saved state prior to starting the VM"),
if (fTeleporterEnabled)
else if (fTeleporterEnabled)
if (autoReset)
if (aProgress)
E_FAIL);
else if (fTeleporterEnabled)
return S_OK;
LogRel(("Console::powerDown(): A request to power off the VM has been issued (mMachineState=%s, InUninit=%d)\n",
if ( !mVMPoweredOff
mVMPoweredOff = true;
if (mConsoleVRDPServer)
if (aProgress)
#ifdef VBOX_WITH_HGCM
# ifdef VBOX_WITH_GUEST_PROPS /** @todo r=bird: This may be premature, the VM may still be running at this point! */
if (pattern.isNull()) /** @todo r=bird: What is pattern actually used for? And, again, what's is the out-of-memory policy in main? */
if (aProgress)
if (mVMMDev)
if (aProgress)
if (mVMCallers > 0)
mVMDestroying = true;
mVMCallers));
if (aProgress)
if (!mVMPoweredOff)
mVMPoweredOff = false;
if (aProgress)
bool fHasUSBController = false;
fHasUSBController = true;
if (aProgress)
vrc);
if (fHasUSBController)
if (aProgress)
vrc);
mVMDestroying = false;
if (aProgress)
return rc;
if (aUpdateServer)
return rc;
return S_OK;
if (aSetError)
aName);
return VBOX_E_FILE_ERROR;
if (aGlobal)
if (online)
if (online)
if (online)
return rc;
return S_OK;
return S_OK;
void *aUser)
switch (aState)
case VMSTATE_OFF:
case VMSTATE_TERMINATED:
if (aVM)
AssertFailed();
case MachineState_Stopping:
case MachineState_Saving:
case MachineState_Starting:
case MachineState_Restoring:
case MachineState_Teleporting:
case VMSTATE_SUSPENDED:
case VMSTATE_SUSPENDED_LS:
case VMSTATE_SUSPENDED_EXT_LS:
AssertMsgFailed(("%s/%s -> %s\n", Global::stringifyMachineState(that->mMachineState), VMR3GetStateName(aOldState), VMR3GetStateName(aState) ));
case VMSTATE_RUNNING:
case VMSTATE_RUNNING_LS:
("%s/%s -> %s\n", Global::stringifyMachineState(that->mMachineState), VMR3GetStateName(aOldState), VMR3GetStateName(aState) ));
case VMSTATE_FATAL_ERROR:
case VMSTATE_GURU_MEDITATION:
#ifdef VBOX_WITH_USB
/** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
switch (vrc)
case VERR_VUSB_NO_PORTS:
vrc);
return hrc;
DECLCALLBACK(int)
Console::usbAttachCallback(Console *that, IUSBDevice *aHostDevice, PCRTUUID aUuid, bool aRemote, const char *aAddress, ULONG aMaskedIfs)
if (aRemote)
pvRemoteBackend = that->consoleVRDPServer()->USBBackendRequestPointer(pRemoteUSBDevice->clientId(), &guid);
if (!pvRemoteBackend)
return vrc;
/** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */
return S_OK;
DECLCALLBACK(int)
if (fRemote)
return vrc;
# ifdef VBOX_STRICT
# ifdef RT_OS_LINUX
memcpy(IfReq.ifr_name, str.raw(), sizeof(IfReq.ifr_name) - 1); /** @todo bitch about names which are too long... */
if (rcVBox != 0)
LogRel(("Configuration error: Failed to configure /dev/net/tun non blocking. Error: %s\n", strerror(iErr)));
switch (rcVBox)
case VERR_ACCESS_DENIED:
rcVBox);
memcpy(szTapdev + strlen(szTapdev), str.raw(), sizeof(szTapdev) - strlen(szTapdev) - 1); /** @todo bitch about names which are too long... */
switch (rcVBox)
case VERR_ACCESS_DENIED:
return rc;
# ifdef VBOX_STRICT
bool isStatic = true;
isStatic = false;
if (isStatic)
return rc;
if (!enabled)
return rc;
return VINF_SUCCESS;
const char *pszErrorId,
void Console::processRemoteUSBDevices(uint32_t u32ClientId, VRDPUSBDEVICEDESC *pDevList, uint32_t cbDevList)
LogFlowThisFunc(("u32ClientId = %d, pDevList=%p, cbDevList = %d\n", u32ClientId, pDevList, cbDevList));
++ it;
bool fNewDevice = true;
fNewDevice = false;
++ it;
if (fNewDevice)
if (fMatched)
++ it;
if (!device)
#if defined(RT_OS_WINDOWS)
#ifdef VBOX_WITH_VRDP
switch (vrc)
case VERR_FILE_NOT_FOUND:
vrc);
&pVM);
#ifdef VBOX_WITH_VRDP
if (machineDebugger)
++ it)
/* -> ConsoleImplTeleporter.cpp */
vrc);
* need to go back to the PoweredOff/Saved state. Reuse
console);
#if defined(RT_OS_WINDOWS)
return VINF_SUCCESS;
int rc;
#define RC_CHECK() do { if (RT_FAILURE(rc)) { AssertMsgFailed(("rc=%Rrc\n", rc)); return rc; } } while (0)
#define H() do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%Rhrc (%#x)\n", hrc, hrc)); *phrc = hrc; return VERR_GENERAL_FAILURE; } } while (0)
int iLUN;
bool fSCSI = false;
switch (enmController)
return VERR_GENERAL_FAILURE;
return VERR_GENERAL_FAILURE;
fSCSI = true;
fSCSI = true;
return VERR_GENERAL_FAILURE;
if (fSCSI)
pLunL1 = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/LUN#%d/AttachedDriver/AttachedDriver/", pcszDevice, lInstance, iLUN);
pLunL1 = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/LUN#%d/AttachedDriver/", pcszDevice, lInstance, iLUN);
if (!pLunL1)
if (fSCSI)
#ifdef VBOX_STRICT
char *pszDriver;
bool fHostIP = true;
if (values[i])
fHostIP = false;
if (values[i])
fHostIP = false;
if (!fHostIP)
rc = PDMR3DeviceAttach(pVM, pcszDevice, 0, iLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/); RC_CHECK();
return rc;
bool fBeganTakingSnapshot = false;
fBeganTakingSnapshot = true;
(void*)pTask);
for (size_t i = 0;
atts[i],
&rc);
if (fBeganTakingSnapshot)
delete pTask;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
typedef struct DRVMAINSTATUS
DECLCALLBACK(void *) Console::drvStatus_QueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
switch (enmInterface)
case PDMINTERFACE_BASE:
return NULL;
while (iLed-- > 0)
DECLCALLBACK(int) Console::drvStatus_Construct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
return rc;
return rc;
return rc;
AssertMsgFailed(("Configuration error: Invalid unit range %u-%u\n", pData->iFirstLUN, pData->iLastLUN));
return VERR_GENERAL_FAILURE;
pData->pLedPorts = (PPDMILEDPORTS)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_LED_PORTS);
return VERR_PDM_MISSING_INTERFACE_ABOVE;
return VINF_SUCCESS;
sizeof(DRVMAINSTATUS),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,