- Timestamp:
- Sep 28, 2009 2:00:18 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 52904
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleImpl.cpp
r23335 r23379 118 118 * (e.g. passing it as a thread function argument). If #rc() returns a 119 119 * failure, the Console object may not be used by the task (see 120 120 * Console::addCaller() for more details). 121 121 * 2. On successful initialization, the structure keeps the Console caller 122 122 * until destruction (to ensure Console remains in the Ready state and won't … … 133 133 VMTask(Console *aConsole, bool aUsesVMPtr) 134 134 : mConsole(aConsole), 135 mCallerAdded 135 mCallerAdded(false), 136 136 mVMCallerAdded(false) 137 137 { 138 AssertReturnVoid 138 AssertReturnVoid(aConsole); 139 139 mRC = aConsole->addCaller(); 140 140 if (SUCCEEDED(mRC)) … … 260 260 261 261 Console::Console() 262 : mSavedStateDataLoaded 263 , mConsoleVRDPServer 264 , mpVM 265 , mVMCallers 266 , mVMZeroCallersSem 267 , mVMDestroying 268 , mVMPoweredOff 269 , mVMMDev 270 , mAudioSniffer 271 , mVMStateChangeCallbackDisabled 272 , mMachineState 273 { 274 for (ULONG slot = 0; slot < SchemaDefs::NetworkAdapterCount; slot ++)262 : mSavedStateDataLoaded(false) 263 , mConsoleVRDPServer(NULL) 264 , mpVM(NULL) 265 , mVMCallers(0) 266 , mVMZeroCallersSem(NIL_RTSEMEVENT) 267 , mVMDestroying(false) 268 , mVMPoweredOff(false) 269 , mVMMDev(NULL) 270 , mAudioSniffer(NULL) 271 , mVMStateChangeCallbackDisabled(false) 272 , mMachineState(MachineState_PoweredOff) 273 { 274 for (ULONG slot = 0; slot < SchemaDefs::NetworkAdapterCount; ++slot) 275 275 meAttachmentType[slot] = NetworkAttachmentType_Null; 276 276 } … … 304 304 ///////////////////////////////////////////////////////////////////////////// 305 305 306 HRESULT Console::init 306 HRESULT Console::init(IMachine *aMachine, IInternalMachineControl *aControl) 307 307 { 308 308 AssertReturn(aMachine && aControl, E_INVALIDARG); … … 320 320 unconst(mControl) = aControl; 321 321 322 memset (&mCallbackData, 0, sizeof(mCallbackData));322 memset(&mCallbackData, 0, sizeof(mCallbackData)); 323 323 324 324 /* Cache essential properties and objects */ 325 325 326 rc = mMachine->COMGETTER(State) 326 rc = mMachine->COMGETTER(State)(&mMachineState); 327 327 AssertComRCReturnRC(rc); 328 328 329 329 #ifdef VBOX_WITH_VRDP 330 rc = mMachine->COMGETTER(VRDPServer) 330 rc = mMachine->COMGETTER(VRDPServer)(unconst(mVRDPServer).asOutParam()); 331 331 AssertComRCReturnRC(rc); 332 332 #endif … … 335 335 336 336 unconst(mGuest).createObject(); 337 rc = mGuest->init 337 rc = mGuest->init(this); 338 338 AssertComRCReturnRC(rc); 339 339 340 340 unconst(mKeyboard).createObject(); 341 rc = mKeyboard->init 341 rc = mKeyboard->init(this); 342 342 AssertComRCReturnRC(rc); 343 343 344 344 unconst(mMouse).createObject(); 345 rc = mMouse->init 345 rc = mMouse->init(this); 346 346 AssertComRCReturnRC(rc); 347 347 348 348 unconst(mDisplay).createObject(); 349 rc = mDisplay->init 349 rc = mDisplay->init(this); 350 350 AssertComRCReturnRC(rc); 351 351 352 352 unconst(mRemoteDisplayInfo).createObject(); 353 rc = mRemoteDisplayInfo->init 353 rc = mRemoteDisplayInfo->init(this); 354 354 AssertComRCReturnRC(rc); 355 355 356 356 /* Grab global and machine shared folder lists */ 357 357 358 rc = fetchSharedFolders 358 rc = fetchSharedFolders(true /* aGlobal */); 359 359 AssertComRCReturnRC(rc); 360 rc = fetchSharedFolders 360 rc = fetchSharedFolders(false /* aGlobal */); 361 361 AssertComRCReturnRC(rc); 362 362 363 363 /* Create other child objects */ 364 364 365 unconst(mConsoleVRDPServer) = new ConsoleVRDPServer 365 unconst(mConsoleVRDPServer) = new ConsoleVRDPServer(this); 366 366 AssertReturn(mConsoleVRDPServer, E_FAIL); 367 367 … … 385 385 386 386 /** 387 * 387 * Uninitializes the Console object. 388 388 */ 389 389 void Console::uninit() … … 412 412 { 413 413 powerDown(); 414 Assert 414 Assert(mpVM == NULL); 415 415 } 416 416 417 417 if (mVMZeroCallersSem != NIL_RTSEMEVENT) 418 418 { 419 RTSemEventDestroy 419 RTSemEventDestroy(mVMZeroCallersSem); 420 420 mVMZeroCallersSem = NIL_RTSEMEVENT; 421 421 } … … 497 497 /* dynamically allocated members of mCallbackData are uninitialized 498 498 * at the end of powerDown() */ 499 Assert 500 Assert 501 Assert 499 Assert(!mCallbackData.mpsc.valid && mCallbackData.mpsc.shape == NULL); 500 Assert(!mCallbackData.mcc.valid); 501 Assert(!mCallbackData.klc.valid); 502 502 503 503 LogFlowThisFuncLeave(); … … 505 505 506 506 #ifdef VBOX_WITH_GUEST_PROPS 507 bool Console::enabledGuestPropertiesVRDP 507 bool Console::enabledGuestPropertiesVRDP(void) 508 508 { 509 509 Bstr value; … … 519 519 } 520 520 521 void Console::updateGuestPropertiesVRDPLogon 521 void Console::updateGuestPropertiesVRDPLogon(uint32_t u32ClientId, const char *pszUser, const char *pszDomain) 522 522 { 523 523 if (!enabledGuestPropertiesVRDP()) … … 564 564 } 565 565 566 void Console::updateGuestPropertiesVRDPDisconnect 566 void Console::updateGuestPropertiesVRDPDisconnect(uint32_t u32ClientId) 567 567 { 568 568 if (!enabledGuestPropertiesVRDP()) … … 608 608 609 609 610 int Console::VRDPClientLogon 610 int Console::VRDPClientLogon(uint32_t u32ClientId, const char *pszUser, const char *pszPassword, const char *pszDomain) 611 611 { 612 612 LogFlowFuncEnter(); 613 LogFlowFunc 613 LogFlowFunc(("%d, %s, %s, %s\n", u32ClientId, pszUser, pszPassword, pszDomain)); 614 614 615 615 AutoCaller autoCaller(this); … … 623 623 624 624 Bstr id; 625 HRESULT hrc = mMachine->COMGETTER (Id)(id.asOutParam());625 HRESULT hrc = mMachine->COMGETTER(Id)(id.asOutParam()); 626 626 Guid uuid = Guid(id); 627 627 628 AssertComRCReturn 628 AssertComRCReturn(hrc, VERR_ACCESS_DENIED); 629 629 630 630 VRDPAuthType_T authType = VRDPAuthType_Null; 631 hrc = mVRDPServer->COMGETTER(AuthType) 632 AssertComRCReturn 631 hrc = mVRDPServer->COMGETTER(AuthType)(&authType); 632 AssertComRCReturn(hrc, VERR_ACCESS_DENIED); 633 633 634 634 ULONG authTimeout = 0; 635 hrc = mVRDPServer->COMGETTER(AuthTimeout) 636 AssertComRCReturn 635 hrc = mVRDPServer->COMGETTER(AuthTimeout)(&authTimeout); 636 AssertComRCReturn(hrc, VERR_ACCESS_DENIED); 637 637 638 638 VRDPAuthResult result = VRDPAuthAccessDenied; … … 641 641 LogFlowFunc(("Auth type %d\n", authType)); 642 642 643 LogRel 643 LogRel(("VRDPAUTH: User: [%s]. Domain: [%s]. Authentication type: [%s]\n", 644 644 pszUser, pszDomain, 645 645 authType == VRDPAuthType_Null? … … 665 665 { 666 666 /* Call the external library. */ 667 result = mConsoleVRDPServer->Authenticate 667 result = mConsoleVRDPServer->Authenticate(uuid, guestJudgement, pszUser, pszPassword, pszDomain, u32ClientId); 668 668 669 669 if (result != VRDPAuthDelegateToGuest) … … 674 674 LogRel(("VRDPAUTH: Delegated to guest.\n")); 675 675 676 LogFlowFunc 676 LogFlowFunc(("External auth asked for guest judgement\n")); 677 677 } /* pass through */ 678 678 … … 688 688 uint32_t u32GuestFlags = VMMDEV_SETCREDENTIALS_JUDGE; 689 689 690 int rc = mVMMDev->getVMMDevPort()->pfnSetCredentials 690 int rc = mVMMDev->getVMMDevPort()->pfnSetCredentials(mVMMDev->getVMMDevPort(), 691 691 pszUser, pszPassword, pszDomain, u32GuestFlags); 692 692 693 if ( VBOX_SUCCESS(rc))693 if (RT_SUCCESS(rc)) 694 694 { 695 695 /* Wait for guest. */ 696 rc = mVMMDev->WaitCredentialsJudgement 697 698 if ( VBOX_SUCCESS(rc))696 rc = mVMMDev->WaitCredentialsJudgement(authTimeout, &u32GuestFlags); 697 698 if (RT_SUCCESS(rc)) 699 699 { 700 700 switch (u32GuestFlags & (VMMDEV_CREDENTIALS_JUDGE_OK | VMMDEV_CREDENTIALS_JUDGE_DENY | VMMDEV_CREDENTIALS_JUDGE_NOJUDGEMENT)) … … 704 704 case VMMDEV_CREDENTIALS_JUDGE_OK: guestJudgement = VRDPAuthGuestAccessGranted; break; 705 705 default: 706 LogFlowFunc 706 LogFlowFunc(("Invalid guest flags %08X!!!\n", u32GuestFlags)); break; 707 707 } 708 708 } 709 709 else 710 710 { 711 LogFlowFunc 711 LogFlowFunc(("Wait for credentials judgement rc = %Rrc!!!\n", rc)); 712 712 } 713 713 714 LogFlowFunc 714 LogFlowFunc(("Guest judgement %d\n", guestJudgement)); 715 715 } 716 716 else 717 717 { 718 LogFlowFunc 718 LogFlowFunc(("Could not set credentials rc = %Rrc!!!\n", rc)); 719 719 } 720 720 } … … 723 723 { 724 724 LogRel(("VRDPAUTH: Guest judgement %d.\n", guestJudgement)); 725 LogFlowFunc 726 result = mConsoleVRDPServer->Authenticate 725 LogFlowFunc(("External auth called again with guest judgement = %d\n", guestJudgement)); 726 result = mConsoleVRDPServer->Authenticate(uuid, guestJudgement, pszUser, pszPassword, pszDomain, u32ClientId); 727 727 } 728 728 else … … 744 744 } 745 745 746 LogFlowFunc 746 LogFlowFunc(("Result = %d\n", result)); 747 747 LogFlowFuncLeave(); 748 748 … … 758 758 /* Multiconnection check must be made after authentication, so bad clients would not interfere with a good one. */ 759 759 BOOL allowMultiConnection = FALSE; 760 hrc = mVRDPServer->COMGETTER(AllowMultiConnection) 761 AssertComRCReturn 760 hrc = mVRDPServer->COMGETTER(AllowMultiConnection)(&allowMultiConnection); 761 AssertComRCReturn(hrc, VERR_ACCESS_DENIED); 762 762 763 763 BOOL reuseSingleConnection = FALSE; 764 hrc = mVRDPServer->COMGETTER(ReuseSingleConnection) 765 AssertComRCReturn 764 hrc = mVRDPServer->COMGETTER(ReuseSingleConnection)(&reuseSingleConnection); 765 AssertComRCReturn(hrc, VERR_ACCESS_DENIED); 766 766 767 767 LogFlowFunc(("allowMultiConnection %d, reuseSingleConnection = %d, mcVRDPClients = %d, mu32SingleRDPClientId = %d\n", allowMultiConnection, reuseSingleConnection, mcVRDPClients, mu32SingleRDPClientId)); … … 782 782 { 783 783 LogRel(("VRDPAUTH: Multiple connections are not enabled. Disconnecting existing client.\n")); 784 mConsoleVRDPServer->DisconnectClient 784 mConsoleVRDPServer->DisconnectClient(mu32SingleRDPClientId, false); 785 785 } 786 786 else … … 797 797 798 798 #ifdef VBOX_WITH_GUEST_PROPS 799 updateGuestPropertiesVRDPLogon 799 updateGuestPropertiesVRDPLogon(u32ClientId, pszUser, pszDomain); 800 800 #endif /* VBOX_WITH_GUEST_PROPS */ 801 801 … … 803 803 } 804 804 805 void Console::VRDPClientConnect 805 void Console::VRDPClientConnect(uint32_t u32ClientId) 806 806 { 807 807 LogFlowFuncEnter(); 808 808 809 809 AutoCaller autoCaller(this); 810 AssertComRCReturnVoid 810 AssertComRCReturnVoid(autoCaller.rc()); 811 811 812 812 #ifdef VBOX_WITH_VRDP … … 816 816 { 817 817 getVMMDev()->getVMMDevPort()-> 818 pfnVRDPChange 819 818 pfnVRDPChange(getVMMDev()->getVMMDevPort(), 819 true, VRDP_EXPERIENCE_LEVEL_FULL); // @todo configurable 820 820 } 821 821 822 822 NOREF(u32ClientId); 823 mDisplay->VideoAccelVRDP 823 mDisplay->VideoAccelVRDP(true); 824 824 #endif /* VBOX_WITH_VRDP */ 825 825 … … 828 828 } 829 829 830 void Console::VRDPClientDisconnect 831 830 void Console::VRDPClientDisconnect(uint32_t u32ClientId, 831 uint32_t fu32Intercepted) 832 832 { 833 833 LogFlowFuncEnter(); 834 834 835 835 AutoCaller autoCaller(this); 836 AssertComRCReturnVoid 837 838 AssertReturnVoid 836 AssertComRCReturnVoid(autoCaller.rc()); 837 838 AssertReturnVoid(mConsoleVRDPServer); 839 839 840 840 #ifdef VBOX_WITH_VRDP … … 844 844 { 845 845 getVMMDev()->getVMMDevPort()-> 846 pfnVRDPChange 847 848 } 849 850 mDisplay->VideoAccelVRDP 846 pfnVRDPChange(getVMMDev()->getVMMDevPort(), 847 false, 0); 848 } 849 850 mDisplay->VideoAccelVRDP(false); 851 851 #endif /* VBOX_WITH_VRDP */ 852 852 853 853 if (fu32Intercepted & VRDP_CLIENT_INTERCEPT_USB) 854 854 { 855 mConsoleVRDPServer->USBBackendDelete 855 mConsoleVRDPServer->USBBackendDelete(u32ClientId); 856 856 } 857 857 … … 859 859 if (fu32Intercepted & VRDP_CLIENT_INTERCEPT_CLIPBOARD) 860 860 { 861 mConsoleVRDPServer->ClipboardDelete 861 mConsoleVRDPServer->ClipboardDelete(u32ClientId); 862 862 } 863 863 … … 873 873 if (port) 874 874 { 875 port->pfnSetup 875 port->pfnSetup(port, false, false); 876 876 } 877 877 } … … 881 881 882 882 Bstr uuid; 883 HRESULT hrc = mMachine->COMGETTER (Id)(uuid.asOutParam());884 AssertComRC 883 HRESULT hrc = mMachine->COMGETTER(Id)(uuid.asOutParam()); 884 AssertComRC(hrc); 885 885 886 886 VRDPAuthType_T authType = VRDPAuthType_Null; 887 hrc = mVRDPServer->COMGETTER(AuthType) 888 AssertComRC 887 hrc = mVRDPServer->COMGETTER(AuthType)(&authType); 888 AssertComRC(hrc); 889 889 890 890 if (authType == VRDPAuthType_External) 891 mConsoleVRDPServer->AuthDisconnect 891 mConsoleVRDPServer->AuthDisconnect(uuid, u32ClientId); 892 892 893 893 #ifdef VBOX_WITH_GUEST_PROPS 894 updateGuestPropertiesVRDPDisconnect 894 updateGuestPropertiesVRDPDisconnect(u32ClientId); 895 895 #endif /* VBOX_WITH_GUEST_PROPS */ 896 896 … … 899 899 } 900 900 901 void Console::VRDPInterceptAudio 901 void Console::VRDPInterceptAudio(uint32_t u32ClientId) 902 902 { 903 903 LogFlowFuncEnter(); 904 904 905 905 AutoCaller autoCaller(this); 906 AssertComRCReturnVoid 907 908 LogFlowFunc 909 906 AssertComRCReturnVoid(autoCaller.rc()); 907 908 LogFlowFunc(("mAudioSniffer %p, u32ClientId %d.\n", 909 mAudioSniffer, u32ClientId)); 910 910 NOREF(u32ClientId); 911 911 912 912 #ifdef VBOX_WITH_VRDP 913 mcAudioRefs++;913 ++mcAudioRefs; 914 914 915 915 if (mcAudioRefs == 1) … … 920 920 if (port) 921 921 { 922 port->pfnSetup 922 port->pfnSetup(port, true, true); 923 923 } 924 924 } … … 930 930 } 931 931 932 void Console::VRDPInterceptUSB 932 void Console::VRDPInterceptUSB(uint32_t u32ClientId, void **ppvIntercept) 933 933 { 934 934 LogFlowFuncEnter(); 935 935 936 936 AutoCaller autoCaller(this); 937 AssertComRCReturnVoid 938 939 AssertReturnVoid 940 941 mConsoleVRDPServer->USBBackendCreate 937 AssertComRCReturnVoid(autoCaller.rc()); 938 939 AssertReturnVoid(mConsoleVRDPServer); 940 941 mConsoleVRDPServer->USBBackendCreate(u32ClientId, ppvIntercept); 942 942 943 943 LogFlowFuncLeave(); … … 945 945 } 946 946 947 void Console::VRDPInterceptClipboard 947 void Console::VRDPInterceptClipboard(uint32_t u32ClientId) 948 948 { 949 949 LogFlowFuncEnter(); 950 950 951 951 AutoCaller autoCaller(this); 952 AssertComRCReturnVoid 953 954 AssertReturnVoid 952 AssertComRCReturnVoid(autoCaller.rc()); 953 954 AssertReturnVoid(mConsoleVRDPServer); 955 955 956 956 #ifdef VBOX_WITH_VRDP 957 mConsoleVRDPServer->ClipboardCreate 957 mConsoleVRDPServer->ClipboardCreate(u32ClientId); 958 958 #endif /* VBOX_WITH_VRDP */ 959 959 … … 969 969 970 970 /** 971 * 972 * 973 * 974 * 975 * 976 * 977 * 978 * 971 * Loads various console data stored in the saved state file. 972 * This method does validation of the state file and returns an error info 973 * when appropriate. 974 * 975 * The method does nothing if the machine is not in the Saved file or if 976 * console data from it has already been loaded. 977 * 978 * @note The caller must lock this object for writing. 979 979 */ 980 980 HRESULT Console::loadDataFromSavedState() … … 984 984 985 985 Bstr savedStateFile; 986 HRESULT rc = mMachine->COMGETTER(StateFilePath) 987 if (FAILED 986 HRESULT rc = mMachine->COMGETTER(StateFilePath)(savedStateFile.asOutParam()); 987 if (FAILED(rc)) 988 988 return rc; 989 989 990 990 PSSMHANDLE ssm; 991 991 int vrc = SSMR3Open(Utf8Str(savedStateFile).c_str(), 0, &ssm); 992 if ( VBOX_SUCCESS(vrc))992 if (RT_SUCCESS(vrc)) 993 993 { 994 994 uint32_t version = 0; 995 vrc = SSMR3Seek 996 if (SSM_VERSION_MAJOR(version) 997 { 998 if ( VBOX_SUCCESS(vrc))999 vrc = loadStateFileExecInternal 995 vrc = SSMR3Seek(ssm, sSSMConsoleUnit, 0 /* iInstance */, &version); 996 if (SSM_VERSION_MAJOR(version) == SSM_VERSION_MAJOR(sSSMConsoleVer)) 997 { 998 if (RT_SUCCESS(vrc)) 999 vrc = loadStateFileExecInternal(ssm, version); 1000 1000 else if (vrc == VERR_SSM_UNIT_NOT_FOUND) 1001 1001 vrc = VINF_SUCCESS; … … 1004 1004 vrc = VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 1005 1005 1006 SSMR3Close (ssm); 1007 } 1008 1009 if (VBOX_FAILURE (vrc)) 1010 rc = setError (VBOX_E_FILE_ERROR, 1011 tr ("The saved state file '%ls' is invalid (%Rrc). " 1012 "Discard the saved state and try again"), 1013 savedStateFile.raw(), vrc); 1006 SSMR3Close(ssm); 1007 } 1008 1009 if (RT_FAILURE(vrc)) 1010 rc = setError(VBOX_E_FILE_ERROR, 1011 tr("The saved state file '%ls' is invalid (%Rrc). Discard the saved state and try again"), 1012 savedStateFile.raw(), vrc); 1014 1013 1015 1014 mSavedStateDataLoaded = true; … … 1019 1018 1020 1019 /** 1021 * 1022 * 1023 * 1024 * 1025 * 1026 * 1020 * Callback handler to save various console data to the state file, 1021 * called when the user saves the VM state. 1022 * 1023 * @param pvUser pointer to Console 1024 * 1025 * @note Locks the Console object for reading. 1027 1026 */ 1028 1027 //static 1029 1028 DECLCALLBACK(void) 1030 Console::saveStateFileExec 1031 { 1032 LogFlowFunc 1033 1034 Console *that = static_cast <Console *>(pvUser);1035 AssertReturnVoid 1029 Console::saveStateFileExec(PSSMHANDLE pSSM, void *pvUser) 1030 { 1031 LogFlowFunc(("\n")); 1032 1033 Console *that = static_cast<Console *>(pvUser); 1034 AssertReturnVoid(that); 1036 1035 1037 1036 AutoCaller autoCaller(that); 1038 AssertComRCReturnVoid 1037 AssertComRCReturnVoid(autoCaller.rc()); 1039 1038 1040 1039 AutoReadLock alock(that); 1041 1040 1042 int vrc = SSMR3PutU32 1043 AssertRC 1041 int vrc = SSMR3PutU32(pSSM, (uint32_t)that->mSharedFolders.size()); 1042 AssertRC(vrc); 1044 1043 1045 1044 for (SharedFolderMap::const_iterator it = that->mSharedFolders.begin(); … … 1051 1050 1052 1051 Utf8Str name = folder->name(); 1053 vrc = SSMR3PutU32 1054 AssertRC 1052 vrc = SSMR3PutU32(pSSM, (uint32_t)name.length() + 1 /* term. 0 */); 1053 AssertRC(vrc); 1055 1054 vrc = SSMR3PutStrZ(pSSM, name.c_str()); 1056 AssertRC 1055 AssertRC(vrc); 1057 1056 1058 1057 Utf8Str hostPath = folder->hostPath(); 1059 vrc = SSMR3PutU32 1060 AssertRC 1061 vrc = SSMR3PutStrZ 1062 AssertRC 1063 1064 vrc = SSMR3PutBool 1065 AssertRC 1058 vrc = SSMR3PutU32(pSSM, (uint32_t)hostPath.length() + 1 /* term. 0 */); 1059 AssertRC(vrc); 1060 vrc = SSMR3PutStrZ(pSSM, hostPath.c_str()); 1061 AssertRC(vrc); 1062 1063 vrc = SSMR3PutBool(pSSM, !!folder->writable()); 1064 AssertRC(vrc); 1066 1065 } 1067 1066 … … 1070 1069 1071 1070 /** 1072 * 1073 * 1074 * 1075 * 1076 * 1077 * 1078 * 1079 * 1080 * 1071 * Callback handler to load various console data from the state file. 1072 * Called when the VM is being restored from the saved state. 1073 * 1074 * @param pvUser pointer to Console 1075 * @param uVersion Console unit version. 1076 * Should match sSSMConsoleVer. 1077 * @param uPass The data pass. 1078 * 1079 * @note Should locks the Console object for writing, if necessary. 1081 1080 */ 1082 1081 //static … … 1084 1083 Console::loadStateFileExec(PSSMHANDLE pSSM, void *pvUser, uint32_t uVersion, uint32_t uPass) 1085 1084 { 1086 LogFlowFunc 1085 LogFlowFunc(("\n")); 1087 1086 1088 1087 if (SSM_VERSION_MAJOR_CHANGED(uVersion, sSSMConsoleVer)) … … 1098 1097 1099 1098 /** 1100 * 1101 * 1102 * 1103 * 1104 * 1105 * 1106 * 1107 * 1099 * Method to load various console data from the state file. 1100 * Called from #loadDataFromSavedState. 1101 * 1102 * @param pvUser pointer to Console 1103 * @param u32Version Console unit version. 1104 * Should match sSSMConsoleVer. 1105 * 1106 * @note Locks the Console object for writing. 1108 1107 */ 1109 1108 int 1110 Console::loadStateFileExecInternal 1109 Console::loadStateFileExecInternal(PSSMHANDLE pSSM, uint32_t u32Version) 1111 1110 { 1112 1111 AutoCaller autoCaller(this); 1113 AssertComRCReturn 1112 AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED); 1114 1113 1115 1114 AutoWriteLock alock(this); … … 1118 1117 1119 1118 uint32_t size = 0; 1120 int vrc = SSMR3GetU32 1121 AssertRCReturn 1119 int vrc = SSMR3GetU32(pSSM, &size); 1120 AssertRCReturn(vrc, vrc); 1122 1121 1123 1122 for (uint32_t i = 0; i < size; ++ i) … … 1130 1129 char *buf = NULL; 1131 1130 1132 vrc = SSMR3GetU32 1133 AssertRCReturn 1134 buf = new char 1135 vrc = SSMR3GetStrZ 1136 AssertRC 1131 vrc = SSMR3GetU32(pSSM, &szBuf); 1132 AssertRCReturn(vrc, vrc); 1133 buf = new char[szBuf]; 1134 vrc = SSMR3GetStrZ(pSSM, buf, szBuf); 1135 AssertRC(vrc); 1137 1136 name = buf; 1138 1137 delete[] buf; 1139 1138 1140 vrc = SSMR3GetU32 1141 AssertRCReturn 1142 buf = new char 1143 vrc = SSMR3GetStrZ 1144 AssertRC 1139 vrc = SSMR3GetU32(pSSM, &szBuf); 1140 AssertRCReturn(vrc, vrc); 1141 buf = new char[szBuf]; 1142 vrc = SSMR3GetStrZ(pSSM, buf, szBuf); 1143 AssertRC(vrc); 1145 1144 hostPath = buf; 1146 1145 delete[] buf; 1147 1146 1148 1147 if (u32Version > 0x00010000) 1149 SSMR3GetBool 1148 SSMR3GetBool(pSSM, &writable); 1150 1149 1151 1150 ComObjPtr<SharedFolder> sharedFolder; 1152 1151 sharedFolder.createObject(); 1153 HRESULT rc = sharedFolder->init 1154 AssertComRCReturn 1155 1156 mSharedFolders.insert (std::make_pair(name, sharedFolder));1152 HRESULT rc = sharedFolder->init(this, name, hostPath, writable); 1153 AssertComRCReturn(rc, VERR_INTERNAL_ERROR); 1154 1155 mSharedFolders.insert(std::make_pair(name, sharedFolder)); 1157 1156 } 1158 1157 … … 1163 1162 // static 1164 1163 DECLCALLBACK(int) 1165 Console::doGuestPropNotification 1166 1164 Console::doGuestPropNotification(void *pvExtension, uint32_t, 1165 void *pvParms, uint32_t cbParms) 1167 1166 { 1168 1167 using namespace guestProp; 1169 1168 1170 // LogFlowFunc 1169 // LogFlowFunc(("pvExtension=%p, pvParms=%p, cbParms=%u\n", pvExtension, pvParms, cbParms)); 1171 1170 int rc = VINF_SUCCESS; 1172 1171 /* No locking, as this is purely a notification which does not make any … … 1175 1174 AssertReturn(sizeof(HOSTCALLBACKDATA) == cbParms, VERR_INVALID_PARAMETER); 1176 1175 AssertReturn(HOSTCALLBACKMAGIC == pCBData->u32Magic, VERR_INVALID_PARAMETER); 1177 ComObjPtr<Console> pConsole = reinterpret_cast <Console *>(pvExtension);1178 // LogFlowFunc 1176 ComObjPtr<Console> pConsole = reinterpret_cast<Console *>(pvExtension); 1177 // LogFlowFunc(("pCBData->pcszName=%s, pCBData->pcszValue=%s, pCBData->pcszFlags=%s\n", pCBData->pcszName, pCBData->pcszValue, pCBData->pcszFlags)); 1179 1178 Bstr name(pCBData->pcszName); 1180 1179 Bstr value(pCBData->pcszValue); … … 1190 1189 pCBData->u64Timestamp, 1191 1190 flags); 1192 if (FAILED 1193 { 1194 // LogFunc 1195 // LogFunc 1196 // LogFunc 1197 // LogFunc 1191 if (FAILED(hrc)) 1192 { 1193 // LogFunc(("pConsole->mControl->PushGuestProperty failed, hrc=0x%x\n", hrc)); 1194 // LogFunc(("pCBData->pcszName=%s\n", pCBData->pcszName)); 1195 // LogFunc(("pCBData->pcszValue=%s\n", pCBData->pcszValue)); 1196 // LogFunc(("pCBData->pcszFlags=%s\n", pCBData->pcszFlags)); 1198 1197 rc = VERR_UNRESOLVED_ERROR; /** @todo translate error code */ 1199 1198 } 1200 1199 } 1201 // LogFlowFunc 1200 // LogFlowFunc(("rc=%Rrc\n", rc)); 1202 1201 return rc; 1203 1202 } 1204 1203 1205 HRESULT Console::doEnumerateGuestProperties 1206 1207 1208 1209 1204 HRESULT Console::doEnumerateGuestProperties(CBSTR aPatterns, 1205 ComSafeArrayOut(BSTR, aNames), 1206 ComSafeArrayOut(BSTR, aValues), 1207 ComSafeArrayOut(ULONG64, aTimestamps), 1208 ComSafeArrayOut(BSTR, aFlags)) 1210 1209 { 1211 1210 using namespace guestProp; … … 1219 1218 1220 1219 /* 1221 * Now things get slightly complicated. 1220 * Now things get slightly complicated. Due to a race with the guest adding 1222 1221 * properties, there is no good way to know how much to enlarge a buffer for 1223 * the service to enumerate into. 1222 * the service to enumerate into. We choose a decent starting size and loop a 1224 1223 * few times, each time retrying with the size suggested by the service plus 1225 1224 * one Kb. … … 1241 1240 parm[1].u.pointer.addr = Utf8Buf.mutableRaw(); 1242 1241 parm[1].u.pointer.size = (uint32_t)cchBuf + 1024; 1243 vrc = mVMMDev->hgcmHostCall 1244 1242 vrc = mVMMDev->hgcmHostCall("VBoxGuestPropSvc", ENUM_PROPS_HOST, 3, 1243 &parm[0]); 1245 1244 Utf8Buf.jolt(); 1246 1245 if (parm[2].type != VBOX_HGCM_SVC_PARM_32BIT) 1247 return setError (E_FAIL, tr("Internal application error"));1246 return setError(E_FAIL, tr("Internal application error")); 1248 1247 cchBuf = parm[2].u.uint32; 1249 1248 } 1250 1249 if (VERR_BUFFER_OVERFLOW == vrc) 1251 return setError (E_UNEXPECTED, tr ("Temporary failure due to guest activity, please retry")); 1250 return setError(E_UNEXPECTED, 1251 tr("Temporary failure due to guest activity, please retry")); 1252 1252 1253 1253 /* 1254 1254 * Finally we have to unpack the data returned by the service into the safe 1255 * arrays supplied by the caller. 1255 * arrays supplied by the caller. We start by counting the number of entries. 1256 1256 */ 1257 1257 const char *pszBuf … … 1304 1304 ///////////////////////////////////////////////////////////////////////////// 1305 1305 1306 STDMETHODIMP Console::COMGETTER(Machine) 1306 STDMETHODIMP Console::COMGETTER(Machine)(IMachine **aMachine) 1307 1307 { 1308 1308 CheckComArgOutPointerValid(aMachine); … … 1317 1317 } 1318 1318 1319 STDMETHODIMP Console::COMGETTER(State) 1319 STDMETHODIMP Console::COMGETTER(State)(MachineState_T *aMachineState) 1320 1320 { 1321 1321 CheckComArgOutPointerValid(aMachineState); … … 1332 1332 } 1333 1333 1334 STDMETHODIMP Console::COMGETTER(Guest) 1334 STDMETHODIMP Console::COMGETTER(Guest)(IGuest **aGuest) 1335 1335 { 1336 1336 CheckComArgOutPointerValid(aGuest); … … 1345 1345 } 1346 1346 1347 STDMETHODIMP Console::COMGETTER(Keyboard) 1347 STDMETHODIMP Console::COMGETTER(Keyboard)(IKeyboard **aKeyboard) 1348 1348 { 1349 1349 CheckComArgOutPointerValid(aKeyboard); … … 1358 1358 } 1359 1359 1360 STDMETHODIMP Console::COMGETTER(Mouse) 1360 STDMETHODIMP Console::COMGETTER(Mouse)(IMouse **aMouse) 1361 1361 { 1362 1362 CheckComArgOutPointerValid(aMouse); … … 1371 1371 } 1372 1372 1373 STDMETHODIMP Console::COMGETTER(Display) 1373 STDMETHODIMP Console::COMGETTER(Display)(IDisplay **aDisplay) 1374 1374 { 1375 1375 CheckComArgOutPointerValid(aDisplay); … … 1384 1384 } 1385 1385 1386 STDMETHODIMP Console::COMGETTER(Debugger) 1386 STDMETHODIMP Console::COMGETTER(Debugger)(IMachineDebugger **aDebugger) 1387 1387 { 1388 1388 CheckComArgOutPointerValid(aDebugger); … … 1398 1398 { 1399 1399 unconst(mDebugger).createObject(); 1400 mDebugger->init 1400 mDebugger->init(this); 1401 1401 } 1402 1402 … … 1406 1406 } 1407 1407 1408 STDMETHODIMP Console::COMGETTER(USBDevices) 1408 STDMETHODIMP Console::COMGETTER(USBDevices)(ComSafeArrayOut(IUSBDevice *, aUSBDevices)) 1409 1409 { 1410 1410 CheckComArgOutSafeArrayPointerValid(aUSBDevices); … … 1415 1415 AutoReadLock alock(this); 1416 1416 1417 SafeIfaceArray<IUSBDevice> collection 1417 SafeIfaceArray<IUSBDevice> collection(mUSBDevices); 1418 1418 collection.detachTo(ComSafeArrayOutArg(aUSBDevices)); 1419 1419 … … 1421 1421 } 1422 1422 1423 STDMETHODIMP Console::COMGETTER(RemoteUSBDevices) 1423 STDMETHODIMP Console::COMGETTER(RemoteUSBDevices)(ComSafeArrayOut(IHostUSBDevice *, aRemoteUSBDevices)) 1424 1424 { 1425 1425 CheckComArgOutSafeArrayPointerValid(aRemoteUSBDevices); … … 1430 1430 AutoReadLock alock(this); 1431 1431 1432 SafeIfaceArray<IHostUSBDevice> collection 1432 SafeIfaceArray<IHostUSBDevice> collection(mRemoteUSBDevices); 1433 1433 collection.detachTo(ComSafeArrayOutArg(aRemoteUSBDevices)); 1434 1434 … … 1436 1436 } 1437 1437 1438 STDMETHODIMP Console::COMGETTER(RemoteDisplayInfo) 1438 STDMETHODIMP Console::COMGETTER(RemoteDisplayInfo)(IRemoteDisplayInfo **aRemoteDisplayInfo) 1439 1439 { 1440 1440 CheckComArgOutPointerValid(aRemoteDisplayInfo); … … 1450 1450 1451 1451 STDMETHODIMP 1452 Console::COMGETTER(SharedFolders) 1452 Console::COMGETTER(SharedFolders)(ComSafeArrayOut(ISharedFolder *, aSharedFolders)) 1453 1453 { 1454 1454 CheckComArgOutSafeArrayPointerValid(aSharedFolders); … … 1464 1464 CheckComRCReturnRC(rc); 1465 1465 1466 SafeIfaceArray<ISharedFolder> sf 1466 SafeIfaceArray<ISharedFolder> sf(mSharedFolders); 1467 1467 sf.detachTo(ComSafeArrayOutArg(aSharedFolders)); 1468 1468 … … 1475 1475 1476 1476 1477 STDMETHODIMP Console::PowerUp 1478 { 1479 return powerUp 1480 } 1481 1482 STDMETHODIMP Console::PowerUpPaused 1483 { 1484 return powerUp 1485 } 1486 1487 STDMETHODIMP Console::PowerDown 1477 STDMETHODIMP Console::PowerUp(IProgress **aProgress) 1478 { 1479 return powerUp(aProgress, false /* aPaused */); 1480 } 1481 1482 STDMETHODIMP Console::PowerUpPaused(IProgress **aProgress) 1483 { 1484 return powerUp(aProgress, true /* aPaused */); 1485 } 1486 1487 STDMETHODIMP Console::PowerDown(IProgress **aProgress) 1488 1488 { 1489 1489 if (aProgress == NULL) … … 1498 1498 AutoWriteLock alock(this); 1499 1499 1500 if (!Global::IsActive 1500 if (!Global::IsActive(mMachineState)) 1501 1501 { 1502 1502 /* extra nice error message for a common case */ 1503 1503 if (mMachineState == MachineState_Saved) 1504 return setError 1505 tr 1504 return setError(VBOX_E_INVALID_VM_STATE, 1505 tr("Cannot power down a saved virtual machine")); 1506 1506 else if (mMachineState == MachineState_Stopping) 1507 return setError 1508 tr 1507 return setError(VBOX_E_INVALID_VM_STATE, 1508 tr("Virtual machine is being powered down.")); 1509 1509 else 1510 1510 return setError(VBOX_E_INVALID_VM_STATE, 1511 tr ("Invalid machine state: %d (must be Running, Paused " 1512 "or Stuck)"), 1511 tr("Invalid machine state: %d (must be Running, Paused or Stuck)"), 1513 1512 mMachineState); 1514 1513 } … … 1519 1518 ComObjPtr<Progress> progress; 1520 1519 progress.createObject(); 1521 progress->init (static_cast <IConsole *>(this),1522 Bstr (tr("Stopping virtual machine")),1523 1520 progress->init(static_cast<IConsole *>(this), 1521 Bstr(tr("Stopping virtual machine")), 1522 FALSE /* aCancelable */); 1524 1523 1525 1524 /* setup task object and thread to carry out the operation asynchronously */ 1526 std::auto_ptr <VMProgressTask> task 1527 new VMProgressTask 1525 std::auto_ptr <VMProgressTask> task( 1526 new VMProgressTask(this, progress, true /* aUsesVMPtr */)); 1528 1527 AssertReturn(task->isOk(), E_FAIL); 1529 1528 1530 int vrc = RTThreadCreate 1531 1532 1533 1534 ComAssertMsgRCRet 1529 int vrc = RTThreadCreate(NULL, Console::powerDownThread, 1530 (void *) task.get(), 0, 1531 RTTHREADTYPE_MAIN_WORKER, 0, 1532 "VMPowerDown"); 1533 ComAssertMsgRCRet(vrc, 1535 1534 ("Could not create VMPowerDown thread (%Rrc)", vrc), E_FAIL); 1536 1535 … … 1539 1538 1540 1539 /* go to Stopping state to forbid state-dependant operations */ 1541 setMachineState 1540 setMachineState(MachineState_Stopping); 1542 1541 1543 1542 /* pass the progress to the caller */ … … 1560 1559 1561 1560 if (mMachineState != MachineState_Running) 1562 return setError (VBOX_E_INVALID_VM_STATE, 1563 tr ("Invalid machine state: %d)"), mMachineState); 1561 return setError(VBOX_E_INVALID_VM_STATE, 1562 tr("Invalid machine state: %d"), 1563 mMachineState); 1564 1564 1565 1565 /* protect mpVM */ 1566 AutoVMCaller autoVMCaller 1566 AutoVMCaller autoVMCaller(this); 1567 1567 CheckComRCReturnRC(autoVMCaller.rc()); 1568 1568 … … 1570 1570 alock.leave(); 1571 1571 1572 int vrc = VMR3Reset (mpVM); 1573 1574 HRESULT rc = VBOX_SUCCESS (vrc) ? S_OK : 1575 setError (VBOX_E_VM_ERROR, tr ("Could not reset the machine (%Rrc)"), vrc); 1572 int vrc = VMR3Reset(mpVM); 1573 1574 HRESULT rc = RT_SUCCESS(vrc) ? S_OK : 1575 setError(VBOX_E_VM_ERROR, 1576 tr("Could not reset the machine (%Rrc)"), 1577 vrc); 1576 1578 1577 1579 LogFlowThisFunc(("mMachineState=%d, rc=%08X\n", mMachineState, rc)); … … 1590 1592 1591 1593 if (mMachineState != MachineState_Running) 1592 return setError (VBOX_E_INVALID_VM_STATE, 1593 tr ("Invalid machine state: %d)"), mMachineState); 1594 return setError(VBOX_E_INVALID_VM_STATE, 1595 tr("Invalid machine state: %d)"), 1596 mMachineState); 1594 1597 1595 1598 /* protect mpVM */ 1596 AutoVMCaller autoVMCaller 1599 AutoVMCaller autoVMCaller(this); 1597 1600 CheckComRCReturnRC(autoVMCaller.rc()); 1598 1601 … … 1602 1605 alock.leave(); 1603 1606 1604 int vrc = VMR3Suspend (mpVM); 1605 1606 HRESULT rc = VBOX_SUCCESS (vrc) ? S_OK : 1607 setError (VBOX_E_VM_ERROR, 1608 tr ("Could not suspend the machine execution (%Rrc)"), vrc); 1607 int vrc = VMR3Suspend(mpVM); 1608 1609 HRESULT rc = RT_SUCCESS(vrc) ? S_OK : 1610 setError(VBOX_E_VM_ERROR, 1611 tr("Could not suspend the machine execution (%Rrc)"), 1612 vrc); 1609 1613 1610 1614 LogFlowThisFunc(("rc=%08X\n", rc)); … … 1623 1627 1624 1628 if (mMachineState != MachineState_Paused) 1625 return setError 1626 tr ("Cannot resume the machine as it is not paused "1627 "(machine state: %d)"),mMachineState);1629 return setError(VBOX_E_INVALID_VM_STATE, 1630 tr("Cannot resume the machine as it is not paused (machine state: %d)"), 1631 mMachineState); 1628 1632 1629 1633 /* protect mpVM */ 1630 AutoVMCaller autoVMCaller 1634 AutoVMCaller autoVMCaller(this); 1631 1635 CheckComRCReturnRC(autoVMCaller.rc()); 1632 1636 … … 1638 1642 int vrc; 1639 1643 if (VMR3GetState(mpVM) == VMSTATE_CREATED) 1640 vrc = VMR3PowerOn 1644 vrc = VMR3PowerOn(mpVM); /* (PowerUpPaused) */ 1641 1645 else 1642 vrc = VMR3Resume (mpVM); 1643 1644 HRESULT rc = VBOX_SUCCESS (vrc) ? S_OK : 1645 setError (VBOX_E_VM_ERROR, 1646 tr ("Could not resume the machine execution (%Rrc)"), vrc); 1646 vrc = VMR3Resume(mpVM); 1647 1648 HRESULT rc = RT_SUCCESS(vrc) ? S_OK : 1649 setError(VBOX_E_VM_ERROR, 1650 tr("Could not resume the machine execution (%Rrc)"), 1651 vrc); 1647 1652 1648 1653 LogFlowThisFunc(("rc=%08X\n", rc)); … … 1661 1666 1662 1667 if (mMachineState != MachineState_Running) 1663 return setError (VBOX_E_INVALID_VM_STATE, 1664 tr ("Invalid machine state: %d)"), mMachineState); 1668 return setError(VBOX_E_INVALID_VM_STATE, 1669 tr("Invalid machine state: %d)"), 1670 mMachineState); 1665 1671 1666 1672 /* protect mpVM */ 1667 AutoVMCaller autoVMCaller 1673 AutoVMCaller autoVMCaller(this); 1668 1674 CheckComRCReturnRC(autoVMCaller.rc()); 1669 1675 1670 1676 PPDMIBASE pBase; 1671 int vrc = PDMR3QueryDeviceLun 1672 if ( VBOX_SUCCESS(vrc))1673 { 1674 Assert 1677 int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase); 1678 if (RT_SUCCESS(vrc)) 1679 { 1680 Assert(pBase); 1675 1681 PPDMIACPIPORT pPort = 1676 1682 (PPDMIACPIPORT) pBase->pfnQueryInterface(pBase, PDMINTERFACE_ACPI_PORT); … … 1678 1684 } 1679 1685 1680 HRESULT rc = VBOX_SUCCESS (vrc) ? S_OK : 1681 setError (VBOX_E_PDM_ERROR, 1682 tr ("Controlled power off failed (%Rrc)"), vrc); 1686 HRESULT rc = RT_SUCCESS(vrc) ? S_OK : 1687 setError(VBOX_E_PDM_ERROR, 1688 tr("Controlled power off failed (%Rrc)"), 1689 vrc); 1683 1690 1684 1691 LogFlowThisFunc(("rc=%08X\n", rc)); … … 1700 1707 1701 1708 if (mMachineState != MachineState_Running) 1702 return setError (VBOX_E_INVALID_VM_STATE, 1703 tr ("Invalid machine state: %d)"), mMachineState); 1709 return setError(VBOX_E_INVALID_VM_STATE, 1710 tr("Invalid machine state: %d)"), 1711 mMachineState); 1704 1712 1705 1713 /* protect mpVM */ 1706 AutoVMCaller autoVMCaller 1714 AutoVMCaller autoVMCaller(this); 1707 1715 CheckComRCReturnRC(autoVMCaller.rc()); 1708 1716 1709 1717 PPDMIBASE pBase; 1710 int vrc = PDMR3QueryDeviceLun 1718 int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase); 1711 1719 bool handled = false; 1712 if ( VBOX_SUCCESS(vrc))1713 { 1714 Assert 1720 if (RT_SUCCESS(vrc)) 1721 { 1722 Assert(pBase); 1715 1723 PPDMIACPIPORT pPort = 1716 1724 (PPDMIACPIPORT) pBase->pfnQueryInterface(pBase, PDMINTERFACE_ACPI_PORT); … … 1718 1726 } 1719 1727 1720 HRESULT rc = VBOX_SUCCESS(vrc) ? S_OK :1721 setError 1722 tr ("Checking if the ACPI Power Button event was handled by the "1723 "guest OS failed (%Rrc)"),vrc);1728 HRESULT rc = RT_SUCCESS(vrc) ? S_OK : 1729 setError(VBOX_E_PDM_ERROR, 1730 tr("Checking if the ACPI Power Button event was handled by the guest OS failed (%Rrc)"), 1731 vrc); 1724 1732 1725 1733 *aHandled = handled; … … 1743 1751 1744 1752 if (mMachineState != MachineState_Running) 1745 return setError 1746 tr ("Invalid machine state %d when checking if the guest entered "1747 "the ACPI mode)"),mMachineState);1753 return setError(VBOX_E_INVALID_VM_STATE, 1754 tr("Invalid machine state %d when checking if the guest entered the ACPI mode)"), 1755 mMachineState); 1748 1756 1749 1757 /* protect mpVM */ 1750 AutoVMCaller autoVMCaller 1758 AutoVMCaller autoVMCaller(this); 1751 1759 CheckComRCReturnRC(autoVMCaller.rc()); 1752 1760 1753 1761 PPDMIBASE pBase; 1754 int vrc = PDMR3QueryDeviceLun 1762 int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase); 1755 1763 bool entered = false; 1756 1764 if (RT_SUCCESS(vrc)) 1757 1765 { 1758 Assert 1766 Assert(pBase); 1759 1767 PPDMIACPIPORT pPort = 1760 1768 (PPDMIACPIPORT) pBase->pfnQueryInterface(pBase, PDMINTERFACE_ACPI_PORT); … … 1778 1786 1779 1787 if (mMachineState != MachineState_Running) 1780 return setError (VBOX_E_INVALID_VM_STATE, 1781 tr ("Invalid machine state: %d)"), mMachineState); 1788 return setError(VBOX_E_INVALID_VM_STATE, 1789 tr("Invalid machine state: %d)"), 1790 mMachineState); 1782 1791 1783 1792 /* protect mpVM */ 1784 AutoVMCaller autoVMCaller 1793 AutoVMCaller autoVMCaller(this); 1785 1794 CheckComRCReturnRC(autoVMCaller.rc()); 1786 1795 1787 1796 PPDMIBASE pBase; 1788 int vrc = PDMR3QueryDeviceLun 1789 if ( VBOX_SUCCESS(vrc))1790 { 1791 Assert 1797 int vrc = PDMR3QueryDeviceLun(mpVM, "acpi", 0, 0, &pBase); 1798 if (RT_SUCCESS(vrc)) 1799 { 1800 Assert(pBase); 1792 1801 PPDMIACPIPORT pPort = 1793 1802 (PPDMIACPIPORT) pBase->pfnQueryInterface(pBase, PDMINTERFACE_ACPI_PORT); … … 1795 1804 } 1796 1805 1797 HRESULT rc = VBOX_SUCCESS (vrc) ? S_OK : 1798 setError (VBOX_E_PDM_ERROR, 1799 tr ("Sending sleep button event failed (%Rrc)"), vrc); 1806 HRESULT rc = RT_SUCCESS(vrc) ? S_OK : 1807 setError(VBOX_E_PDM_ERROR, 1808 tr("Sending sleep button event failed (%Rrc)"), 1809 vrc); 1800 1810 1801 1811 LogFlowThisFunc(("rc=%08X\n", rc)); … … 1804 1814 } 1805 1815 1806 STDMETHODIMP Console::SaveState 1816 STDMETHODIMP Console::SaveState(IProgress **aProgress) 1807 1817 { 1808 1818 LogFlowThisFuncEnter(); … … 1819 1829 mMachineState != MachineState_Paused) 1820 1830 { 1821 return setError 1822 tr ("Cannot save the execution state as the machine "1823 "is not running or paused (machine state: %d)"),mMachineState);1831 return setError(VBOX_E_INVALID_VM_STATE, 1832 tr("Cannot save the execution state as the machine is not running or paused (machine state: %d)"), 1833 mMachineState); 1824 1834 } 1825 1835 … … 1838 1848 ComObjPtr<Progress> progress; 1839 1849 progress.createObject(); 1840 progress->init (static_cast <IConsole *>(this),1841 Bstr (tr("Saving the execution state of the virtual machine")),1842 1850 progress->init(static_cast<IConsole *>(this), 1851 Bstr(tr("Saving the execution state of the virtual machine")), 1852 FALSE /* aCancelable */); 1843 1853 1844 1854 bool fBeganSavingState = false; … … 1848 1858 { 1849 1859 /* create a task object early to ensure mpVM protection is successful */ 1850 std::auto_ptr <VMSaveTask> task (new VMSaveTask(this, progress));1860 std::auto_ptr <VMSaveTask> task(new VMSaveTask(this, progress)); 1851 1861 rc = task->rc(); 1852 1862 /* 1853 * 1854 * 1855 * 1856 * 1863 * If we fail here it means a PowerDown() call happened on another 1864 * thread while we were doing Pause() (which leaves the Console lock). 1865 * We assign PowerDown() a higher precedence than SaveState(), 1866 * therefore just return the error to the caller. 1857 1867 */ 1858 if (FAILED 1868 if (FAILED(rc)) 1859 1869 { 1860 1870 fTaskCreationFailed = true; … … 1865 1875 1866 1876 /* 1867 * 1868 * 1869 * 1877 * request a saved state file path from the server 1878 * (this will set the machine state to Saving on the server to block 1879 * others from accessing this machine) 1870 1880 */ 1871 rc = mControl->BeginSavingState 1872 CheckComRCBreakRC 1881 rc = mControl->BeginSavingState(progress, stateFilePath.asOutParam()); 1882 CheckComRCBreakRC(rc); 1873 1883 1874 1884 fBeganSavingState = true; 1875 1885 1876 1886 /* sync the state with the server */ 1877 setMachineStateLocally 1887 setMachineStateLocally(MachineState_Saving); 1878 1888 1879 1889 /* ensure the directory for the saved state file exists */ … … 1884 1894 { 1885 1895 int vrc = RTDirCreateFullPath(dir.c_str(), 0777); 1886 if ( VBOX_FAILURE(vrc))1896 if (RT_FAILURE(vrc)) 1887 1897 { 1888 rc = setError 1889 tr 1898 rc = setError(VBOX_E_FILE_ERROR, 1899 tr("Could not create a directory '%s' to save the state to (%Rrc)"), 1890 1900 dir.raw(), vrc); 1891 1901 break; … … 1900 1910 1901 1911 /* create a thread to wait until the VM state is saved */ 1902 int vrc = RTThreadCreate 1903 1904 1905 ComAssertMsgRCBreak 1906 1912 int vrc = RTThreadCreate(NULL, Console::saveStateThread, (void *) task.get(), 1913 0, RTTHREADTYPE_MAIN_WORKER, 0, "VMSave"); 1914 1915 ComAssertMsgRCBreak(vrc, ("Could not create VMSave thread (%Rrc)", vrc), 1916 rc = E_FAIL); 1907 1917 1908 1918 /* task is now owned by saveStateThread(), so release it */ … … 1914 1924 while (0); 1915 1925 1916 if (FAILED 1926 if (FAILED(rc) && !fTaskCreationFailed) 1917 1927 { 1918 1928 /* preserve existing error info */ … … 1922 1932 { 1923 1933 /* 1924 * 1925 * 1926 * 1934 * cancel the requested save state procedure. 1935 * This will reset the machine state to the state it had right 1936 * before calling mControl->BeginSavingState(). 1927 1937 */ 1928 mControl->EndSavingState 1938 mControl->EndSavingState(FALSE); 1929 1939 } 1930 1940 … … 1932 1942 { 1933 1943 /* restore the paused state if appropriate */ 1934 setMachineStateLocally 1944 setMachineStateLocally(MachineState_Paused); 1935 1945 /* restore the running state if appropriate */ 1936 1946 Resume(); 1937 1947 } 1938 1948 else 1939 setMachineStateLocally 1949 setMachineStateLocally(lastMachineState); 1940 1950 } 1941 1951 … … 1945 1955 } 1946 1956 1947 STDMETHODIMP Console::AdoptSavedState 1957 STDMETHODIMP Console::AdoptSavedState(IN_BSTR aSavedStateFile) 1948 1958 { 1949 1959 CheckComArgNotNull(aSavedStateFile); … … 1956 1966 if (mMachineState != MachineState_PoweredOff && 1957 1967 mMachineState != MachineState_Aborted) 1958 return setError (VBOX_E_INVALID_VM_STATE, 1959 tr ("Cannot adopt the saved machine state as the machine is " 1960 "not in Powered Off or Aborted state (machine state: %d)"), 1968 return setError(VBOX_E_INVALID_VM_STATE, 1969 tr("Cannot adopt the saved machine state as the machine is not in Powered Off or Aborted state (machine state: %d)"), 1961 1970 mMachineState); 1962 1971 1963 return mControl->AdoptSavedState 1972 return mControl->AdoptSavedState(aSavedStateFile); 1964 1973 } 1965 1974 … … 1972 1981 1973 1982 if (mMachineState != MachineState_Saved) 1974 return setError (VBOX_E_INVALID_VM_STATE, 1975 tr ("Cannot discard the machine state as the machine is " 1976 "not in the saved state (machine state: %d)"), 1983 return setError(VBOX_E_INVALID_VM_STATE, 1984 tr("Cannot discard the machine state as the machine is not in the saved state (machine state: %d)"), 1977 1985 mMachineState); 1978 1986 … … 1983 1991 1984 1992 /* 1985 * 1986 * 1993 * Saved -> PoweredOff transition will be detected in the SessionMachine 1994 * and properly handled. 1987 1995 */ 1988 rc = setMachineState 1996 rc = setMachineState(MachineState_PoweredOff); 1989 1997 1990 1998 return rc; … … 2001 2009 } 2002 2010 2003 STDMETHODIMP Console::GetDeviceActivity 2004 2011 STDMETHODIMP Console::GetDeviceActivity(DeviceType_T aDeviceType, 2012 DeviceActivity_T *aDeviceActivity) 2005 2013 { 2006 2014 CheckComArgNotNull(aDeviceActivity); … … 2010 2018 2011 2019 /* 2012 * 2013 * 2020 * Note: we don't lock the console object here because 2021 * readAndClearLed() should be thread safe. 2014 2022 */ 2015 2023 2016 2024 /* Get LED array to read */ 2017 PDMLEDCORE 2025 PDMLEDCORE SumLed = {0}; 2018 2026 switch (aDeviceType) 2019 2027 { 2020 2028 case DeviceType_Floppy: 2021 2029 { 2022 for (unsigned i = 0; i < RT_ELEMENTS(mapFDLeds); i++)2030 for (unsigned i = 0; i < RT_ELEMENTS(mapFDLeds); ++i) 2023 2031 SumLed.u32 |= readAndClearLed(mapFDLeds[i]); 2024 2032 break; … … 2036 2044 SumLed.u32 |= readAndClearLed(mapIDELeds[1]); 2037 2045 SumLed.u32 |= readAndClearLed(mapIDELeds[3]); 2038 for (unsigned i = 0; i < RT_ELEMENTS(mapSATALeds); i++)2046 for (unsigned i = 0; i < RT_ELEMENTS(mapSATALeds); ++i) 2039 2047 SumLed.u32 |= readAndClearLed(mapSATALeds[i]); 2040 for (unsigned i = 0; i < RT_ELEMENTS(mapSCSILeds); i++)2048 for (unsigned i = 0; i < RT_ELEMENTS(mapSCSILeds); ++i) 2041 2049 SumLed.u32 |= readAndClearLed(mapSCSILeds[i]); 2042 2050 break; … … 2045 2053 case DeviceType_Network: 2046 2054 { 2047 for (unsigned i = 0; i < RT_ELEMENTS(mapNetworkLeds); i++)2055 for (unsigned i = 0; i < RT_ELEMENTS(mapNetworkLeds); ++i) 2048 2056 SumLed.u32 |= readAndClearLed(mapNetworkLeds[i]); 2049 2057 break; … … 2052 2060 case DeviceType_USB: 2053 2061 { 2054 for (unsigned i = 0; i < RT_ELEMENTS(mapUSBLed); i++)2062 for (unsigned i = 0; i < RT_ELEMENTS(mapUSBLed); ++i) 2055 2063 SumLed.u32 |= readAndClearLed(mapUSBLed[i]); 2056 2064 break; … … 2064 2072 2065 2073 default: 2066 return setError (E_INVALIDARG, 2067 tr ("Invalid device type: %d"), aDeviceType); 2074 return setError(E_INVALIDARG, 2075 tr("Invalid device type: %d"), 2076 aDeviceType); 2068 2077 } 2069 2078 … … 2086 2095 } 2087 2096 2088 STDMETHODIMP Console::AttachUSBDevice 2097 STDMETHODIMP Console::AttachUSBDevice(IN_BSTR aId) 2089 2098 { 2090 2099 #ifdef VBOX_WITH_USB … … 2096 2105 if (mMachineState != MachineState_Running && 2097 2106 mMachineState != MachineState_Paused) 2098 return setError 2099 tr ("Cannot attach a USB device to the machine which is not "2100 "running or paused (machine state: %d)"),mMachineState);2107 return setError(VBOX_E_INVALID_VM_STATE, 2108 tr("Cannot attach a USB device to the machine which is not running or paused (machine state: %d)"), 2109 mMachineState); 2101 2110 2102 2111 /* protect mpVM */ 2103 AutoVMCaller autoVMCaller 2112 AutoVMCaller autoVMCaller(this); 2104 2113 CheckComRCReturnRC(autoVMCaller.rc()); 2105 2114 2106 2115 /* Don't proceed unless we've found the usb controller. */ 2107 2116 PPDMIBASE pBase = NULL; 2108 int vrc = PDMR3QueryLun 2109 if ( VBOX_FAILURE(vrc))2110 return setError 2111 tr 2117 int vrc = PDMR3QueryLun(mpVM, "usb-ohci", 0, 0, &pBase); 2118 if (RT_FAILURE(vrc)) 2119 return setError(VBOX_E_PDM_ERROR, 2120 tr("The virtual machine does not have a USB controller")); 2112 2121 2113 2122 /* leave the lock because the USB Proxy service may call us back … … 2116 2125 2117 2126 /* Request the device capture */ 2118 HRESULT rc = mControl->CaptureUSBDevice 2127 HRESULT rc = mControl->CaptureUSBDevice(aId); 2119 2128 CheckComRCReturnRC(rc); 2120 2129 … … 2122 2131 2123 2132 #else /* !VBOX_WITH_USB */ 2124 return setError 2125 tr 2133 return setError(VBOX_E_PDM_ERROR, 2134 tr("The virtual machine does not have a USB controller")); 2126 2135 #endif /* !VBOX_WITH_USB */ 2127 2136 } 2128 2137 2129 STDMETHODIMP Console::DetachUSBDevice 2138 STDMETHODIMP Console::DetachUSBDevice(IN_BSTR aId, IUSBDevice **aDevice) 2130 2139 { 2131 2140 #ifdef VBOX_WITH_USB … … 2152 2161 2153 2162 if (!device) 2154 return setError 2155 tr 2156 Guid 2163 return setError(E_INVALIDARG, 2164 tr("USB device with UUID {%RTuuid} is not attached to this machine"), 2165 Guid(aId).raw()); 2157 2166 2158 2167 /* … … 2160 2169 */ 2161 2170 alock.leave(); 2162 HRESULT rc2 = mControl->DetachUSBDevice 2163 if (FAILED 2171 HRESULT rc2 = mControl->DetachUSBDevice(aId, false /* aDone */); 2172 if (FAILED(rc2)) 2164 2173 return rc2; 2165 2174 alock.enter(); 2166 2175 2167 2176 /* Request the PDM to detach the USB device. */ 2168 HRESULT rc = detachUSBDevice 2177 HRESULT rc = detachUSBDevice(it); 2169 2178 2170 2179 if (SUCCEEDED(rc)) … … 2176 2185 /* Request the device release. Even if it fails, the device will 2177 2186 * remain as held by proxy, which is OK for us (the VM process). */ 2178 rc = mControl->DetachUSBDevice 2187 rc = mControl->DetachUSBDevice(aId, true /* aDone */); 2179 2188 } 2180 2189 … … 2183 2192 2184 2193 #else /* !VBOX_WITH_USB */ 2185 return setError 2186 tr 2194 return setError(VBOX_E_PDM_ERROR, 2195 tr("The virtual machine does not have a USB controller")); 2187 2196 #endif /* !VBOX_WITH_USB */ 2188 2197 } … … 2197 2206 2198 2207 SafeIfaceArray<IUSBDevice> devsvec; 2199 HRESULT rc = COMGETTER(USBDevices) 2208 HRESULT rc = COMGETTER(USBDevices)(ComSafeArrayAsOutParam(devsvec)); 2200 2209 CheckComRCReturnRC(rc); 2201 2210 … … 2203 2212 { 2204 2213 Bstr address; 2205 rc = devsvec[i]->COMGETTER(Address) 2214 rc = devsvec[i]->COMGETTER(Address)(address.asOutParam()); 2206 2215 CheckComRCReturnRC(rc); 2207 2216 if (address == aAddress) 2208 {2209 ComObjPtr<OUSBDevice> found;2210 found.createObject();2211 found->init (devsvec[i]);2212 return found.queryInterfaceTo(aDevice);2213 }2214 }2215 2216 return setErrorNoLog (VBOX_E_OBJECT_NOT_FOUND, tr (2217 "Could not find a USB device with address '%ls'"),2218 aAddress);2219 2220 #else /* !VBOX_WITH_USB */2221 return E_NOTIMPL;2222 #endif /* !VBOX_WITH_USB */2223 }2224 2225 STDMETHODIMP Console::FindUSBDeviceById(IN_BSTR aId, IUSBDevice **aDevice)2226 {2227 #ifdef VBOX_WITH_USB2228 CheckComArgExpr(aId, Guid (aId).isEmpty() == false);2229 CheckComArgOutPointerValid(aDevice);2230 2231 *aDevice = NULL;2232 2233 SafeIfaceArray<IUSBDevice> devsvec;2234 HRESULT rc = COMGETTER(USBDevices) (ComSafeArrayAsOutParam(devsvec));2235 CheckComRCReturnRC(rc);2236 2237 for (size_t i = 0; i < devsvec.size(); ++i)2238 {2239 Bstr id;2240 rc = devsvec[i]->COMGETTER(Id) (id.asOutParam());2241 CheckComRCReturnRC(rc);2242 if (id == aId)2243 2217 { 2244 2218 ComObjPtr<OUSBDevice> found; … … 2249 2223 } 2250 2224 2251 return setErrorNoLog (VBOX_E_OBJECT_NOT_FOUND, tr (2252 "Could not find a USB device with uuid {%RTuuid}"),2253 Guid (aId).raw());2225 return setErrorNoLog(VBOX_E_OBJECT_NOT_FOUND, 2226 tr("Could not find a USB device with address '%ls'"), 2227 aAddress); 2254 2228 2255 2229 #else /* !VBOX_WITH_USB */ … … 2258 2232 } 2259 2233 2234 STDMETHODIMP Console::FindUSBDeviceById(IN_BSTR aId, IUSBDevice **aDevice) 2235 { 2236 #ifdef VBOX_WITH_USB 2237 CheckComArgExpr(aId, Guid(aId).isEmpty() == false); 2238 CheckComArgOutPointerValid(aDevice); 2239 2240 *aDevice = NULL; 2241 2242 SafeIfaceArray<IUSBDevice> devsvec; 2243 HRESULT rc = COMGETTER(USBDevices)(ComSafeArrayAsOutParam(devsvec)); 2244 CheckComRCReturnRC(rc); 2245 2246 for (size_t i = 0; i < devsvec.size(); ++i) 2247 { 2248 Bstr id; 2249 rc = devsvec[i]->COMGETTER(Id)(id.asOutParam()); 2250 CheckComRCReturnRC(rc); 2251 if (id == aId) 2252 { 2253 ComObjPtr<OUSBDevice> found; 2254 found.createObject(); 2255 found->init(devsvec[i]); 2256 return found.queryInterfaceTo(aDevice); 2257 } 2258 } 2259 2260 return setErrorNoLog(VBOX_E_OBJECT_NOT_FOUND, 2261 tr("Could not find a USB device with uuid {%RTuuid}"), 2262 Guid(aId).raw()); 2263 2264 #else /* !VBOX_WITH_USB */ 2265 return E_NOTIMPL; 2266 #endif /* !VBOX_WITH_USB */ 2267 } 2268 2260 2269 STDMETHODIMP 2261 Console::CreateSharedFolder 2270 Console::CreateSharedFolder(IN_BSTR aName, IN_BSTR aHostPath, BOOL aWritable) 2262 2271 { 2263 2272 CheckComArgNotNull(aName); … … 2271 2280 /// @todo see @todo in AttachUSBDevice() about the Paused state 2272 2281 if (mMachineState == MachineState_Saved) 2273 return setError (VBOX_E_INVALID_VM_STATE, 2274 tr ("Cannot create a transient shared folder on the " 2275 "machine in the saved state")); 2282 return setError(VBOX_E_INVALID_VM_STATE, 2283 tr("Cannot create a transient shared folder on the machine in the saved state")); 2276 2284 if (mMachineState > MachineState_Paused) 2277 return setError (VBOX_E_INVALID_VM_STATE, 2278 tr ("Cannot create a transient shared folder on the " 2279 "machine while it is changing the state (machine state: %d)"), 2285 return setError(VBOX_E_INVALID_VM_STATE, 2286 tr("Cannot create a transient shared folder on the machine while it is changing the state (machine state: %d)"), 2280 2287 mMachineState); 2281 2288 2282 2289 ComObjPtr<SharedFolder> sharedFolder; 2283 HRESULT rc = findSharedFolder 2290 HRESULT rc = findSharedFolder(aName, sharedFolder, false /* aSetError */); 2284 2291 if (SUCCEEDED(rc)) 2285 return setError (VBOX_E_FILE_ERROR, 2286 tr ("Shared folder named '%ls' already exists"), aName); 2292 return setError(VBOX_E_FILE_ERROR, 2293 tr("Shared folder named '%ls' already exists"), 2294 aName); 2287 2295 2288 2296 sharedFolder.createObject(); 2289 rc = sharedFolder->init 2297 rc = sharedFolder->init(this, aName, aHostPath, aWritable); 2290 2298 CheckComRCReturnRC(rc); 2291 2299 2292 2300 /* protect mpVM (if not NULL) */ 2293 AutoVMCallerQuietWeak autoVMCaller 2301 AutoVMCallerQuietWeak autoVMCaller(this); 2294 2302 2295 2303 if (mpVM && autoVMCaller.isOk() && mVMMDev->isShFlActive()) … … 2300 2308 /* first, remove the machine or the global folder if there is any */ 2301 2309 SharedFolderDataMap::const_iterator it; 2302 if (findOtherSharedFolder 2303 { 2304 rc = removeSharedFolder 2310 if (findOtherSharedFolder(aName, it)) 2311 { 2312 rc = removeSharedFolder(aName); 2305 2313 CheckComRCReturnRC(rc); 2306 2314 } 2307 2315 2308 2316 /* second, create the given folder */ 2309 rc = createSharedFolder (aName, SharedFolderData(aHostPath, aWritable));2317 rc = createSharedFolder(aName, SharedFolderData(aHostPath, aWritable)); 2310 2318 CheckComRCReturnRC(rc); 2311 2319 } 2312 2320 2313 mSharedFolders.insert (std::make_pair(aName, sharedFolder));2321 mSharedFolders.insert(std::make_pair(aName, sharedFolder)); 2314 2322 2315 2323 /* notify console callbacks after the folder is added to the list */ … … 2317 2325 CallbackList::iterator it = mCallbacks.begin(); 2318 2326 while (it != mCallbacks.end()) 2319 (*it++)->OnSharedFolderChange 2327 (*it++)->OnSharedFolderChange(Scope_Session); 2320 2328 } 2321 2329 … … 2323 2331 } 2324 2332 2325 STDMETHODIMP Console::RemoveSharedFolder 2333 STDMETHODIMP Console::RemoveSharedFolder(IN_BSTR aName) 2326 2334 { 2327 2335 CheckComArgNotNull(aName); … … 2334 2342 /// @todo see @todo in AttachUSBDevice() about the Paused state 2335 2343 if (mMachineState == MachineState_Saved) 2336 return setError (VBOX_E_INVALID_VM_STATE, 2337 tr ("Cannot remove a transient shared folder from the " 2338 "machine in the saved state")); 2344 return setError(VBOX_E_INVALID_VM_STATE, 2345 tr("Cannot remove a transient shared folder from the machine in the saved state")); 2339 2346 if (mMachineState > MachineState_Paused) 2340 return setError (VBOX_E_INVALID_VM_STATE, 2341 tr ("Cannot remove a transient shared folder from the " 2342 "machine while it is changing the state (machine state: %d)"), 2347 return setError(VBOX_E_INVALID_VM_STATE, 2348 tr("Cannot remove a transient shared folder from the machine while it is changing the state (machine state: %d)"), 2343 2349 mMachineState); 2344 2350 2345 2351 ComObjPtr<SharedFolder> sharedFolder; 2346 HRESULT rc = findSharedFolder 2352 HRESULT rc = findSharedFolder(aName, sharedFolder, true /* aSetError */); 2347 2353 CheckComRCReturnRC(rc); 2348 2354 2349 2355 /* protect mpVM (if not NULL) */ 2350 AutoVMCallerQuietWeak autoVMCaller 2356 AutoVMCallerQuietWeak autoVMCaller(this); 2351 2357 2352 2358 if (mpVM && autoVMCaller.isOk() && mVMMDev->isShFlActive()) … … 2356 2362 2357 2363 /* first, remove the given folder */ 2358 rc = removeSharedFolder 2364 rc = removeSharedFolder(aName); 2359 2365 CheckComRCReturnRC(rc); 2360 2366 2361 2367 /* first, remove the machine or the global folder if there is any */ 2362 2368 SharedFolderDataMap::const_iterator it; 2363 if (findOtherSharedFolder 2364 { 2365 rc = createSharedFolder 2369 if (findOtherSharedFolder(aName, it)) 2370 { 2371 rc = createSharedFolder(aName, it->second); 2366 2372 /* don't check rc here because we need to remove the console 2367 2373 * folder from the collection even on failure */ … … 2369 2375 } 2370 2376 2371 mSharedFolders.erase 2377 mSharedFolders.erase(aName); 2372 2378 2373 2379 /* notify console callbacks after the folder is removed to the list */ … … 2375 2381 CallbackList::iterator it = mCallbacks.begin(); 2376 2382 while (it != mCallbacks.end()) 2377 (*it++)->OnSharedFolderChange 2383 (*it++)->OnSharedFolderChange(Scope_Session); 2378 2384 } 2379 2385 … … 2472 2478 { 2473 2479 /* 2474 * 2475 * 2476 * 2477 * 2480 * If we fail here it means a PowerDown() call happened on another 2481 * thread while we were doing Pause() (which leaves the Console lock). 2482 * We assign PowerDown() a higher precedence than TakeSnapshot(), 2483 * therefore just return the error to the caller. 2478 2484 */ 2479 2485 rc = pTask->rc(); … … 2520 2526 STDMETHODIMP Console::DiscardSnapshot(IN_BSTR aId, IProgress **aProgress) 2521 2527 { 2522 CheckComArgExpr(aId, Guid 2528 CheckComArgExpr(aId, Guid(aId).isEmpty() == false); 2523 2529 CheckComArgOutPointerValid(aProgress); 2524 2530 … … 2528 2534 AutoWriteLock alock(this); 2529 2535 2530 if (Global::IsOnlineOrTransient (mMachineState)) 2531 return setError (VBOX_E_INVALID_VM_STATE, 2532 tr ("Cannot discard a snapshot of the running machine " 2533 "(machine state: %d)"), 2536 if (Global::IsOnlineOrTransient(mMachineState)) 2537 return setError(VBOX_E_INVALID_VM_STATE, 2538 tr("Cannot discard a snapshot of the running machine (machine state: %d)"), 2534 2539 mMachineState); 2535 2540 2536 2541 MachineState_T machineState = MachineState_Null; 2537 HRESULT rc = mControl->DiscardSnapshot 2542 HRESULT rc = mControl->DiscardSnapshot(this, aId, &machineState, aProgress); 2538 2543 CheckComRCReturnRC(rc); 2539 2544 2540 setMachineStateLocally 2545 setMachineStateLocally(machineState); 2541 2546 return S_OK; 2542 2547 } 2543 2548 2544 STDMETHODIMP Console::DiscardCurrentState 2549 STDMETHODIMP Console::DiscardCurrentState(IProgress **aProgress) 2545 2550 { 2546 2551 AutoCaller autoCaller(this); … … 2549 2554 AutoWriteLock alock(this); 2550 2555 2551 if (Global::IsOnlineOrTransient (mMachineState)) 2552 return setError (VBOX_E_INVALID_VM_STATE, 2553 tr ("Cannot discard the current state of the running machine " 2554 "(nachine state: %d)"), 2556 if (Global::IsOnlineOrTransient(mMachineState)) 2557 return setError(VBOX_E_INVALID_VM_STATE, 2558 tr("Cannot discard the current state of the running machine (machine state: %d)"), 2555 2559 mMachineState); 2556 2560 2557 2561 MachineState_T machineState = MachineState_Null; 2558 HRESULT rc = mControl->DiscardCurrentState 2562 HRESULT rc = mControl->DiscardCurrentState(this, &machineState, aProgress); 2559 2563 CheckComRCReturnRC(rc); 2560 2564 2561 setMachineStateLocally 2565 setMachineStateLocally(machineState); 2562 2566 return S_OK; 2563 2567 } 2564 2568 2565 STDMETHODIMP Console::DiscardCurrentSnapshotAndState 2569 STDMETHODIMP Console::DiscardCurrentSnapshotAndState(IProgress **aProgress) 2566 2570 { 2567 2571 AutoCaller autoCaller(this); … … 2570 2574 AutoWriteLock alock(this); 2571 2575 2572 if (Global::IsOnlineOrTransient (mMachineState)) 2573 return setError (VBOX_E_INVALID_VM_STATE, 2574 tr ("Cannot discard the current snapshot and state of the " 2575 "running machine (machine state: %d)"), 2576 if (Global::IsOnlineOrTransient(mMachineState)) 2577 return setError(VBOX_E_INVALID_VM_STATE, 2578 tr("Cannot discard the current snapshot and state of the running machine (machine state: %d)"), 2576 2579 mMachineState); 2577 2580 2578 2581 MachineState_T machineState = MachineState_Null; 2579 2582 HRESULT rc = 2580 mControl->DiscardCurrentSnapshotAndState 2583 mControl->DiscardCurrentSnapshotAndState(this, &machineState, aProgress); 2581 2584 CheckComRCReturnRC(rc); 2582 2585 2583 setMachineStateLocally 2586 setMachineStateLocally(machineState); 2584 2587 return S_OK; 2585 2588 } 2586 2589 2587 STDMETHODIMP Console::RegisterCallback 2590 STDMETHODIMP Console::RegisterCallback(IConsoleCallback *aCallback) 2588 2591 { 2589 2592 CheckComArgNotNull(aCallback); … … 2602 2605 AutoWriteLock alock(this); 2603 2606 2604 mCallbacks.push_back (CallbackList::value_type(aCallback));2607 mCallbacks.push_back(CallbackList::value_type(aCallback)); 2605 2608 2606 2609 /* Inform the callback about the current status (for example, the new … … 2609 2612 2610 2613 if (mCallbackData.mpsc.valid) 2611 aCallback->OnMousePointerShapeChange 2612 2613 2614 2615 2616 2617 2614 aCallback->OnMousePointerShapeChange(mCallbackData.mpsc.visible, 2615 mCallbackData.mpsc.alpha, 2616 mCallbackData.mpsc.xHot, 2617 mCallbackData.mpsc.yHot, 2618 mCallbackData.mpsc.width, 2619 mCallbackData.mpsc.height, 2620 mCallbackData.mpsc.shape); 2618 2621 if (mCallbackData.mcc.valid) 2619 aCallback->OnMouseCapabilityChange 2620 2622 aCallback->OnMouseCapabilityChange(mCallbackData.mcc.supportsAbsolute, 2623 mCallbackData.mcc.needsHostCursor); 2621 2624 2622 2625 aCallback->OnAdditionsStateChange(); 2623 2626 2624 2627 if (mCallbackData.klc.valid) 2625 aCallback->OnKeyboardLedsChange 2626 2627 2628 aCallback->OnKeyboardLedsChange(mCallbackData.klc.numLock, 2629 mCallbackData.klc.capsLock, 2630 mCallbackData.klc.scrollLock); 2628 2631 2629 2632 /* Note: we don't call OnStateChange for new callbacks because the … … 2634 2637 } 2635 2638 2636 STDMETHODIMP Console::UnregisterCallback 2639 STDMETHODIMP Console::UnregisterCallback(IConsoleCallback *aCallback) 2637 2640 { 2638 2641 CheckComArgNotNull(aCallback); … … 2644 2647 2645 2648 CallbackList::iterator it; 2646 it = std::find 2647 2648 CallbackList::value_type(aCallback));2649 it = std::find(mCallbacks.begin(), 2650 mCallbacks.end(), 2651 CallbackList::value_type(aCallback)); 2649 2652 if (it == mCallbacks.end()) 2650 return setError 2651 tr 2652 2653 mCallbacks.erase 2653 return setError(E_INVALIDARG, 2654 tr("The given callback handler is not registered")); 2655 2656 mCallbacks.erase(it); 2654 2657 return S_OK; 2655 2658 } … … 2688 2691 { 2689 2692 AssertMsgReturn(port < 2 && port >= 0, ("%d\n", port), E_INVALIDARG); 2690 AssertMsgReturn(device < 2 && device >= 0, ("%d\n", device), 2693 AssertMsgReturn(device < 2 && device >= 0, ("%d\n", device), E_INVALIDARG); 2691 2694 uLun = 2 * port + device; 2692 2695 return S_OK; … … 2733 2736 AssertComRC(rc); 2734 2737 ComPtr<IStorageController> ctrl; 2735 for (size_t i = 0; i < ctrls.size(); i++)2738 for (size_t i = 0; i < ctrls.size(); ++i) 2736 2739 { 2737 2740 Bstr ctrlName; … … 2815 2818 if (!location.isEmpty()) 2816 2819 return setError(E_FAIL, 2817 tr("Could not mount the media/drive '%s' (%Rrc)"), location.raw(), vrc); 2820 tr("Could not mount the media/drive '%s' (%Rrc)"), 2821 location.raw(), vrc); 2818 2822 2819 2823 return setError(E_FAIL, 2820 tr("Could not unmount the currently mounted media/drive (%Rrc)"), vrc); 2824 tr("Could not unmount the currently mounted media/drive (%Rrc)"), 2825 vrc); 2821 2826 } 2822 2827 … … 2843 2848 * @todo the error handling in this method needs to be improved seriously - what if mounting fails... 2844 2849 */ 2845 DECLCALLBACK(int) Console::changeDrive 2846 2847 { 2848 /// @todo FIXME - this isn't called right now2849 LogFlowFunc 2850 2850 DECLCALLBACK(int) Console::changeDrive(Console *pThis, const char *pszDevice, unsigned uInstance, unsigned uLun, 2851 const char *pszPath, bool fPassthrough) 2852 { 2853 /// @todo change this to use the same code as in ConsoleImpl2.cpp 2854 LogFlowFunc(("pThis=%p pszDevice=%p:{%s} uInstance=%u uLun=%u pszPath=%p:{%s} fPassthrough=%d\n", 2855 pThis, pszDevice, pszDevice, uInstance, uLun, pszPath, pszPath, fPassthrough)); 2851 2856 2852 2857 AssertReturn(pThis, VERR_INVALID_PARAMETER); 2853 2858 2854 2859 AutoCaller autoCaller(pThis); 2855 AssertComRCReturn 2860 AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED); 2856 2861 2857 2862 /* protect mpVM */ 2858 AutoVMCaller autoVMCaller 2863 AutoVMCaller autoVMCaller(pThis); 2859 2864 CheckComRCReturnRC(autoVMCaller.rc()); 2860 2865 … … 2868 2873 */ 2869 2874 bool fResume; 2870 VMSTATE enmVMState = VMR3GetState 2875 VMSTATE enmVMState = VMR3GetState(pVM); 2871 2876 switch (enmVMState) 2872 2877 { … … 2874 2879 case VMSTATE_RUNNING: 2875 2880 { 2876 LogFlowFunc 2881 LogFlowFunc(("Suspending the VM...\n")); 2877 2882 /* disable the callback to prevent Console-level state change */ 2878 2883 pThis->mVMStateChangeCallbackDisabled = true; 2879 int rc = VMR3Suspend 2884 int rc = VMR3Suspend(pVM); 2880 2885 pThis->mVMStateChangeCallbackDisabled = false; 2881 AssertRCReturn 2886 AssertRCReturn(rc, rc); 2882 2887 fResume = true; 2883 2888 break; … … 2891 2896 2892 2897 default: 2893 AssertMsgFailedReturn 2898 AssertMsgFailedReturn(("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED); 2894 2899 } 2895 2900 … … 2913 2918 * Unmount existing media / detach host drive. 2914 2919 */ 2915 PPDMIMOUNT 2916 PPDMIBASE 2917 rc = PDMR3QueryLun 2918 if ( VBOX_FAILURE(rc))2920 PPDMIMOUNT pIMount = NULL; 2921 PPDMIBASE pBase; 2922 rc = PDMR3QueryLun(pVM, pszDevice, uInstance, uLun, &pBase); 2923 if (RT_FAILURE(rc)) 2919 2924 { 2920 2925 if (rc == VERR_PDM_LUN_NOT_FOUND) 2921 2926 rc = VINF_SUCCESS; 2922 AssertRC 2927 AssertRC(rc); 2923 2928 } 2924 2929 else 2925 2930 { 2926 pIMount = (PPDMIMOUNT) pBase->pfnQueryInterface 2927 AssertBreakStmt 2931 pIMount = (PPDMIMOUNT) pBase->pfnQueryInterface(pBase, PDMINTERFACE_MOUNT); 2932 AssertBreakStmt(pIMount, rc = VERR_INVALID_POINTER); 2928 2933 2929 2934 /* 2930 2935 * Unmount the media. 2931 2936 */ 2932 rc = pIMount->pfnUnmount 2937 rc = pIMount->pfnUnmount(pIMount, false); 2933 2938 if (rc == VERR_PDM_MEDIA_NOT_MOUNTED) 2934 2939 rc = VINF_SUCCESS; 2935 2940 } 2936 2941 2937 if ( VBOX_FAILURE(rc))2942 if (RT_FAILURE(rc)) 2938 2943 { 2939 2944 rcRet = rc; … … 2944 2949 * Construct a new driver configuration. 2945 2950 */ 2946 PCFGMNODE pInst = CFGMR3GetChildF (CFGMR3GetRoot(pVM), "Devices/%s/%d/", pszDevice, uInstance);2947 AssertRelease 2951 PCFGMNODE pInst = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%d/", pszDevice, uInstance); 2952 AssertRelease(pInst); 2948 2953 /* nuke anything which might have been left behind. */ 2949 CFGMR3RemoveNode (CFGMR3GetChildF(pInst, "LUN#%d", uLun));2950 2951 #define RC_CHECK() do { if (VBOX_FAILURE (rc)) { AssertReleaseRC(rc); break; } } while (0)2954 CFGMR3RemoveNode(CFGMR3GetChildF(pInst, "LUN#%d", uLun)); 2955 2956 #define RC_CHECK() do { if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; } } while (0) 2952 2957 2953 2958 /* create a new block driver config */ 2954 2959 PCFGMNODE pLunL0; 2955 rc = CFGMR3InsertNodeF (pInst, &pLunL0, "LUN#%d", uLun);RC_CHECK();2956 rc = CFGMR3InsertString (pLunL0, "Driver","Block"); RC_CHECK();2960 rc = CFGMR3InsertNodeF(pInst, &pLunL0, "LUN#%d", uLun); RC_CHECK(); 2961 rc = CFGMR3InsertString(pLunL0, "Driver", "Block"); RC_CHECK(); 2957 2962 PCFGMNODE pCfg; 2958 rc = CFGMR3InsertNode (pLunL0, "Config",&pCfg); RC_CHECK();2959 rc = CFGMR3InsertString (pCfg, "Type", !strcmp(pszDevice, "i82078") ? "Floppy 1.44" : "DVD"); RC_CHECK();2960 rc = CFGMR3InsertInteger (pCfg, "Mountable",1); RC_CHECK();2963 rc = CFGMR3InsertNode(pLunL0, "Config", &pCfg); RC_CHECK(); 2964 rc = CFGMR3InsertString(pCfg, "Type", !strcmp(pszDevice, "i82078") ? "Floppy 1.44" : "DVD"); RC_CHECK(); 2965 rc = CFGMR3InsertInteger(pCfg, "Mountable", 1); RC_CHECK(); 2961 2966 2962 2967 /* 2963 2968 * Attach the driver. 2964 2969 */ 2965 rc = PDMR3DeviceAttach 2966 pIMount = (PPDMIMOUNT) pBase->pfnQueryInterface 2970 rc = PDMR3DeviceAttach(pVM, pszDevice, uInstance, uLun, PDM_TACH_FLAGS_NOT_HOT_PLUG, &pBase); RC_CHECK(); 2971 pIMount = (PPDMIMOUNT) pBase->pfnQueryInterface(pBase, PDMINTERFACE_MOUNT); 2967 2972 if (!pIMount) 2968 2973 { … … 2976 2981 if (pszPath && *pszPath) 2977 2982 { 2978 rc = pIMount->pfnMount (pIMount, pszPath, strcmp(pszDevice, "i82078") ? "MediaISO" : "RawImage");2983 rc = pIMount->pfnMount(pIMount, pszPath, strcmp(pszDevice, "i82078") ? "MediaISO" : "RawImage"); 2979 2984 } 2980 2985 2981 2986 #undef RC_CHECK 2982 2987 2983 if ( VBOX_FAILURE (rc) && VBOX_SUCCESS(rcRet))2988 if (RT_FAILURE(rc) && RT_SUCCESS(rcRet)) 2984 2989 rcRet = rc; 2985 2990 … … 2998 3003 if (fResume) 2999 3004 { 3000 LogFlowFunc 3005 LogFlowFunc(("Resuming the VM...\n")); 3001 3006 /* disable the callback to prevent Console-level state change */ 3002 3007 pThis->mVMStateChangeCallbackDisabled = true; 3003 rc = VMR3Resume 3008 rc = VMR3Resume(pVM); 3004 3009 pThis->mVMStateChangeCallbackDisabled = false; 3005 AssertRC 3006 if ( VBOX_FAILURE(rc))3010 AssertRC(rc); 3011 if (RT_FAILURE(rc)) 3007 3012 { 3008 3013 /* too bad, we failed. try to sync the console state with the VMM state */ 3009 vmstateChangeCallback 3014 vmstateChangeCallback(pVM, VMSTATE_SUSPENDED, enmVMState, pThis); 3010 3015 } 3011 3016 /// @todo (r=dmik) if we failed with drive mount, then the VMR3Resume 3012 // 3013 // 3014 // 3015 // 3016 if ( VBOX_SUCCESS(rcRet))3017 // error (if any) will be hidden from the caller. For proper reporting 3018 // of such multiple errors to the caller we need to enhance the 3019 // IVirtualBoxError interface. For now, give the first error the higher 3020 // priority. 3021 if (RT_SUCCESS(rcRet)) 3017 3022 rcRet = rc; 3018 3023 } 3019 3024 3020 LogFlowFunc 3025 LogFlowFunc(("Returning %Rrc\n", rcRet)); 3021 3026 return rcRet; 3022 3027 } … … 3024 3029 3025 3030 /** 3026 * 3027 * 3028 * 3031 * Called by IInternalSessionControl::OnNetworkAdapterChange(). 3032 * 3033 * @note Locks this object for writing. 3029 3034 */ 3030 HRESULT Console::onNetworkAdapterChange 3035 HRESULT Console::onNetworkAdapterChange(INetworkAdapter *aNetworkAdapter, BOOL changeAdapter) 3031 3036 { 3032 3037 LogFlowThisFunc(("\n")); … … 3042 3047 3043 3048 /* protect mpVM */ 3044 AutoVMCaller autoVMCaller 3049 AutoVMCaller autoVMCaller(this); 3045 3050 CheckComRCReturnRC(autoVMCaller.rc()); 3046 3051 3047 3052 /* Get the properties we need from the adapter */ 3048 3053 BOOL fCableConnected, fTraceEnabled; 3049 HRESULT rc = aNetworkAdapter->COMGETTER(CableConnected) 3054 HRESULT rc = aNetworkAdapter->COMGETTER(CableConnected)(&fCableConnected); 3050 3055 AssertComRC(rc); 3051 3056 if (SUCCEEDED(rc)) 3052 3057 { 3053 rc = aNetworkAdapter->COMGETTER(TraceEnabled) 3058 rc = aNetworkAdapter->COMGETTER(TraceEnabled)(&fTraceEnabled); 3054 3059 AssertComRC(rc); 3055 3060 } … … 3057 3062 { 3058 3063 ULONG ulInstance; 3059 rc = aNetworkAdapter->COMGETTER(Slot) 3060 AssertComRC 3064 rc = aNetworkAdapter->COMGETTER(Slot)(&ulInstance); 3065 AssertComRC(rc); 3061 3066 if (SUCCEEDED(rc)) 3062 3067 { … … 3084 3089 #endif /* VBOX_WITH_VIRTIO */ 3085 3090 #endif 3086 int vrc = PDMR3QueryDeviceLun 3087 3088 ComAssertRC 3089 if ( VBOX_SUCCESS(vrc))3091 int vrc = PDMR3QueryDeviceLun(mpVM, pszAdapterName, 3092 (unsigned) ulInstance, 0, &pBase); 3093 ComAssertRC(vrc); 3094 if (RT_SUCCESS(vrc)) 3090 3095 { 3091 3096 Assert(pBase); … … 3094 3099 if (pINetCfg) 3095 3100 { 3096 Log 3101 Log(("Console::onNetworkAdapterChange: setting link state to %d\n", 3097 3102 fCableConnected)); 3098 vrc = pINetCfg->pfnSetLinkState 3099 3100 3103 vrc = pINetCfg->pfnSetLinkState(pINetCfg, 3104 fCableConnected ? PDMNETWORKLINKSTATE_UP 3105 : PDMNETWORKLINKSTATE_DOWN); 3101 3106 ComAssertRC(vrc); 3102 3107 } … … 3111 3116 if (fTraceEnabled && fCableConnected && pINetCfg) 3112 3117 { 3113 vrc = pINetCfg->pfnSetLinkState 3118 vrc = pINetCfg->pfnSetLinkState(pINetCfg, PDMNETWORKLINKSTATE_DOWN); 3114 3119 ComAssertRC(vrc); 3115 3120 } … … 3119 3124 if (fTraceEnabled && fCableConnected && pINetCfg) 3120 3125 { 3121 vrc = pINetCfg->pfnSetLinkState 3126 vrc = pINetCfg->pfnSetLinkState(pINetCfg, PDMNETWORKLINKSTATE_UP); 3122 3127 ComAssertRC(vrc); 3123 3128 } … … 3127 3132 } 3128 3133 3129 if ( VBOX_FAILURE(vrc))3134 if (RT_FAILURE(vrc)) 3130 3135 rc = E_FAIL; 3131 3136 } … … 3137 3142 CallbackList::iterator it = mCallbacks.begin(); 3138 3143 while (it != mCallbacks.end()) 3139 (*it++)->OnNetworkAdapterChange 3144 (*it++)->OnNetworkAdapterChange(aNetworkAdapter); 3140 3145 } 3141 3146 … … 3158 3163 * @note Locks this object for writing. 3159 3164 */ 3160 HRESULT Console::doNetworkAdapterChange 3161 3162 3163 3165 HRESULT Console::doNetworkAdapterChange(const char *pszDevice, 3166 unsigned uInstance, 3167 unsigned uLun, 3168 INetworkAdapter *aNetworkAdapter) 3164 3169 { 3165 3170 LogFlowThisFunc(("pszDevice=%p:{%s} uInstance=%u uLun=%u aNetworkAdapter=%p\n", … … 3173 3178 3174 3179 /* protect mpVM */ 3175 AutoVMCaller autoVMCaller 3180 AutoVMCaller autoVMCaller(this); 3176 3181 CheckComRCReturnRC(autoVMCaller.rc()); 3177 3182 … … 3182 3187 */ 3183 3188 PVMREQ pReq; 3184 int vrc = VMR3ReqCall 3185 3186 3189 int vrc = VMR3ReqCall(mpVM, 0 /*idDstCpu*/, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS, 3190 (PFNRT) Console::changeNetworkAttachment, 5, 3191 this, pszDevice, uInstance, uLun, aNetworkAdapter); 3187 3192 3188 3193 /* leave the lock before waiting for a result (EMT will call us back!) */ 3189 3194 alock.leave(); 3190 3195 3191 if (vrc == VERR_TIMEOUT || VBOX_SUCCESS(vrc))3192 { 3193 vrc = VMR3ReqWait 3194 AssertRC 3195 if ( VBOX_SUCCESS(vrc))3196 if (vrc == VERR_TIMEOUT || RT_SUCCESS(vrc)) 3197 { 3198 vrc = VMR3ReqWait(pReq, RT_INDEFINITE_WAIT); 3199 AssertRC(vrc); 3200 if (RT_SUCCESS(vrc)) 3196 3201 vrc = pReq->iStatus; 3197 3202 } 3198 VMR3ReqFree 3199 3200 if ( VBOX_SUCCESS(vrc))3203 VMR3ReqFree(pReq); 3204 3205 if (RT_SUCCESS(vrc)) 3201 3206 { 3202 3207 LogFlowThisFunc(("Returns S_OK\n")); … … 3204 3209 } 3205 3210 3206 return setError (E_FAIL, 3207 tr ("Could not change the network adaptor attachement type (%Rrc)"), vrc); 3211 return setError(E_FAIL, 3212 tr("Could not change the network adaptor attachement type (%Rrc)"), 3213 vrc); 3208 3214 } 3209 3215 … … 3223 3229 * @note Locks the Console object for writing. 3224 3230 */ 3225 DECLCALLBACK(int) Console::changeNetworkAttachment 3226 3227 3228 3229 3230 { 3231 LogFlowFunc 3232 3231 DECLCALLBACK(int) Console::changeNetworkAttachment(Console *pThis, 3232 const char *pszDevice, 3233 unsigned uInstance, 3234 unsigned uLun, 3235 INetworkAdapter *aNetworkAdapter) 3236 { 3237 LogFlowFunc(("pThis=%p pszDevice=%p:{%s} uInstance=%u uLun=%u aNetworkAdapter=%p\n", 3238 pThis, pszDevice, pszDevice, uInstance, uLun, aNetworkAdapter)); 3233 3239 3234 3240 AssertReturn(pThis, VERR_INVALID_PARAMETER); 3235 3241 3236 AssertMsg ( (!strcmp(pszDevice, "pcnet") && uLun == 0 && uInstance < SchemaDefs::NetworkAdapterCount)3237 || (!strcmp 3242 AssertMsg( (!strcmp(pszDevice, "pcnet") && uLun == 0 && uInstance < SchemaDefs::NetworkAdapterCount) 3243 || (!strcmp(pszDevice, "e1000") && uLun == 0 && uInstance < SchemaDefs::NetworkAdapterCount), 3238 3244 ("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance)); 3239 3245 Log(("pszDevice=%s uLun=%d uInstance=%d\n", pszDevice, uLun, uInstance)); 3240 3246 3241 3247 AutoCaller autoCaller(pThis); 3242 AssertComRCReturn 3248 AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED); 3243 3249 3244 3250 /* protect mpVM */ 3245 AutoVMCaller autoVMCaller 3251 AutoVMCaller autoVMCaller(pThis); 3246 3252 CheckComRCReturnRC(autoVMCaller.rc()); 3247 3253 … … 3255 3261 */ 3256 3262 bool fResume; 3257 VMSTATE enmVMState = VMR3GetState 3263 VMSTATE enmVMState = VMR3GetState(pVM); 3258 3264 switch (enmVMState) 3259 3265 { … … 3261 3267 case VMSTATE_RUNNING: 3262 3268 { 3263 LogFlowFunc 3269 LogFlowFunc(("Suspending the VM...\n")); 3264 3270 /* disable the callback to prevent Console-level state change */ 3265 3271 pThis->mVMStateChangeCallbackDisabled = true; 3266 int rc = VMR3Suspend 3272 int rc = VMR3Suspend(pVM); 3267 3273 pThis->mVMStateChangeCallbackDisabled = false; 3268 AssertRCReturn 3274 AssertRCReturn(rc, rc); 3269 3275 fResume = true; 3270 3276 break; … … 3278 3284 3279 3285 default: 3280 AssertMsgFailedReturn 3286 AssertMsgFailedReturn(("enmVMState=%d\n", enmVMState), VERR_ACCESS_DENIED); 3281 3287 } 3282 3288 … … 3286 3292 PCFGMNODE pCfg = NULL; /* /Devices/Dev/.../Config/ */ 3287 3293 PCFGMNODE pLunL0 = NULL; /* /Devices/Dev/0/LUN#0/ */ 3288 PCFGMNODE pInst = CFGMR3GetChildF (CFGMR3GetRoot(pVM), "Devices/%s/%d/", pszDevice, uInstance);3289 AssertRelease 3294 PCFGMNODE pInst = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%d/", pszDevice, uInstance); 3295 AssertRelease(pInst); 3290 3296 3291 3297 rcRet = configNetwork(pThis, pszDevice, uInstance, uLun, aNetworkAdapter, pCfg, pLunL0, pInst, true); … … 3296 3302 if (fResume) 3297 3303 { 3298 LogFlowFunc 3304 LogFlowFunc(("Resuming the VM...\n")); 3299 3305 /* disable the callback to prevent Console-level state change */ 3300 3306 pThis->mVMStateChangeCallbackDisabled = true; 3301 rc = VMR3Resume 3307 rc = VMR3Resume(pVM); 3302 3308 pThis->mVMStateChangeCallbackDisabled = false; 3303 AssertRC 3304 if ( VBOX_FAILURE(rc))3309 AssertRC(rc); 3310 if (RT_FAILURE(rc)) 3305 3311 { 3306 3312 /* too bad, we failed. try to sync the console state with the VMM state */ 3307 vmstateChangeCallback 3313 vmstateChangeCallback(pVM, VMSTATE_SUSPENDED, enmVMState, pThis); 3308 3314 } 3309 3315 /// @todo (r=dmik) if we failed with drive mount, then the VMR3Resume 3310 // 3311 // 3312 // 3313 // 3314 if ( VBOX_SUCCESS(rcRet))3316 // error (if any) will be hidden from the caller. For proper reporting 3317 // of such multiple errors to the caller we need to enhance the 3318 // IVirtualBoxError interface. For now, give the first error the higher 3319 // priority. 3320 if (RT_SUCCESS(rcRet)) 3315 3321 rcRet = rc; 3316 3322 } 3317 3323 3318 LogFlowFunc 3324 LogFlowFunc(("Returning %Rrc\n", rcRet)); 3319 3325 return rcRet; 3320 3326 } … … 3323 3329 3324 3330 /** 3325 * 3326 * 3327 * 3331 * Called by IInternalSessionControl::OnSerialPortChange(). 3332 * 3333 * @note Locks this object for writing. 3328 3334 */ 3329 HRESULT Console::onSerialPortChange 3335 HRESULT Console::onSerialPortChange(ISerialPort *aSerialPort) 3330 3336 { 3331 3337 LogFlowThisFunc(("\n")); … … 3343 3349 3344 3350 /* protect mpVM */ 3345 AutoVMCaller autoVMCaller 3351 AutoVMCaller autoVMCaller(this); 3346 3352 CheckComRCReturnRC(autoVMCaller.rc()); 3347 3353 … … 3353 3359 CallbackList::iterator it = mCallbacks.begin(); 3354 3360 while (it != mCallbacks.end()) 3355 (*it++)->OnSerialPortChange 3361 (*it++)->OnSerialPortChange(aSerialPort); 3356 3362 } 3357 3363 … … 3361 3367 3362 3368 /** 3363 * 3364 * 3365 * 3369 * Called by IInternalSessionControl::OnParallelPortChange(). 3370 * 3371 * @note Locks this object for writing. 3366 3372 */ 3367 HRESULT Console::onParallelPortChange 3373 HRESULT Console::onParallelPortChange(IParallelPort *aParallelPort) 3368 3374 { 3369 3375 LogFlowThisFunc(("\n")); … … 3381 3387 3382 3388 /* protect mpVM */ 3383 AutoVMCaller autoVMCaller 3389 AutoVMCaller autoVMCaller(this); 3384 3390 CheckComRCReturnRC(autoVMCaller.rc()); 3385 3391 … … 3391 3397 CallbackList::iterator it = mCallbacks.begin(); 3392 3398 while (it != mCallbacks.end()) 3393 (*it++)->OnParallelPortChange 3399 (*it++)->OnParallelPortChange(aParallelPort); 3394 3400 } 3395 3401 … … 3399 3405 3400 3406 /** 3401 * 3402 * 3403 * 3407 * Called by IInternalSessionControl::OnStorageControllerChange(). 3408 * 3409 * @note Locks this object for writing. 3404 3410 */ 3405 HRESULT Console::onStorageControllerChange 3411 HRESULT Console::onStorageControllerChange() 3406 3412 { 3407 3413 LogFlowThisFunc(("\n")); … … 3419 3425 3420 3426 /* protect mpVM */ 3421 AutoVMCaller autoVMCaller 3427 AutoVMCaller autoVMCaller(this); 3422 3428 CheckComRCReturnRC(autoVMCaller.rc()); 3423 3429 … … 3429 3435 CallbackList::iterator it = mCallbacks.begin(); 3430 3436 while (it != mCallbacks.end()) 3431 (*it++)->OnStorageControllerChange 3437 (*it++)->OnStorageControllerChange(); 3432 3438 } 3433 3439 … … 3437 3443 3438 3444 /** 3439 * 3440 * 3441 * 3445 * Called by IInternalSessionControl::OnMediumChange(). 3446 * 3447 * @note Locks this object for writing. 3442 3448 */ 3443 HRESULT Console::onMediumChange 3449 HRESULT Console::onMediumChange(IMediumAttachment *aMediumAttachment) 3444 3450 { 3445 3451 LogFlowThisFunc(("\n")); … … 3457 3463 3458 3464 /* protect mpVM */ 3459 AutoVMCaller autoVMCaller 3465 AutoVMCaller autoVMCaller(this); 3460 3466 CheckComRCReturnRC(autoVMCaller.rc()); 3461 3467 … … 3467 3473 CallbackList::iterator it = mCallbacks.begin(); 3468 3474 while (it != mCallbacks.end()) 3469 (*it++)->OnMediumChange 3475 (*it++)->OnMediumChange(aMediumAttachment); 3470 3476 } 3471 3477 … … 3475 3481 3476 3482 /** 3477 * 3478 * 3479 * 3483 * Called by IInternalSessionControl::OnVRDPServerChange(). 3484 * 3485 * @note Locks this object for writing. 3480 3486 */ 3481 3487 HRESULT Console::onVRDPServerChange() … … 3492 3498 BOOL vrdpEnabled = FALSE; 3493 3499 3494 rc = mVRDPServer->COMGETTER(Enabled) 3495 ComAssertComRCRetRC 3500 rc = mVRDPServer->COMGETTER(Enabled)(&vrdpEnabled); 3501 ComAssertComRCRetRC(rc); 3496 3502 3497 3503 /* VRDP server may call this Console object back from other threads (VRDP INPUT or OUTPUT). */ … … 3503 3509 // However if a server was started and this notification was called, 3504 3510 // we have to restart the server. 3505 mConsoleVRDPServer->Stop 3506 3507 if (RT_FAILURE(mConsoleVRDPServer->Launch 3511 mConsoleVRDPServer->Stop(); 3512 3513 if (RT_FAILURE(mConsoleVRDPServer->Launch())) 3508 3514 { 3509 3515 rc = E_FAIL; … … 3511 3517 else 3512 3518 { 3513 mConsoleVRDPServer->EnableConnections 3519 mConsoleVRDPServer->EnableConnections(); 3514 3520 } 3515 3521 } 3516 3522 else 3517 3523 { 3518 mConsoleVRDPServer->Stop 3524 mConsoleVRDPServer->Stop(); 3519 3525 } 3520 3526 … … 3534 3540 3535 3541 /** 3536 * 3537 * 3538 * 3542 * Called by IInternalSessionControl::OnUSBControllerChange(). 3543 * 3544 * @note Locks this object for writing. 3539 3545 */ 3540 3546 HRESULT Console::onUSBControllerChange() … … 3554 3560 3555 3561 /// @todo (dmik) 3556 // 3557 // 3558 // 3562 // check for the Enabled state and disable virtual USB controller?? 3563 // Anyway, if we want to query the machine's USB Controller we need to cache 3564 // it to mUSBController in #init() (as it is done with mDVDDrive). 3559 3565 // 3560 // 3566 // bird: While the VM supports hot-plugging, I doubt any guest can handle it at this time... :-) 3561 3567 // 3562 3568 // /* protect mpVM */ 3563 // AutoVMCaller autoVMCaller 3569 // AutoVMCaller autoVMCaller(this); 3564 3570 // CheckComRCReturnRC(autoVMCaller.rc()); 3565 3571 … … 3576 3582 3577 3583 /** 3578 * 3579 * 3580 * 3584 * Called by IInternalSessionControl::OnSharedFolderChange(). 3585 * 3586 * @note Locks this object for writing. 3581 3587 */ 3582 HRESULT Console::onSharedFolderChange 3588 HRESULT Console::onSharedFolderChange(BOOL aGlobal) 3583 3589 { 3584 3590 LogFlowThisFunc(("aGlobal=%RTbool\n", aGlobal)); … … 3589 3595 AutoWriteLock alock(this); 3590 3596 3591 HRESULT rc = fetchSharedFolders 3597 HRESULT rc = fetchSharedFolders(aGlobal); 3592 3598 3593 3599 /* notify console callbacks on success */ … … 3596 3602 CallbackList::iterator it = mCallbacks.begin(); 3597 3603 while (it != mCallbacks.end()) 3598 (*it++)->OnSharedFolderChange (aGlobal ? (Scope_T)Scope_Global3599 : (Scope_T)Scope_Machine);3604 (*it++)->OnSharedFolderChange(aGlobal ? (Scope_T)Scope_Global 3605 : (Scope_T)Scope_Machine); 3600 3606 } 3601 3607 … … 3604 3610 3605 3611 /** 3606 * 3607 * 3608 * 3609 * 3610 * 3611 * 3612 * 3613 * 3614 * 3615 * 3616 * 3617 * 3618 * 3612 * Called by IInternalSessionControl::OnUSBDeviceAttach() or locally by 3613 * processRemoteUSBDevices() after IInternalMachineControl::RunUSBDeviceFilters() 3614 * returns TRUE for a given remote USB device. 3615 * 3616 * @return S_OK if the device was attached to the VM. 3617 * @return failure if not attached. 3618 * 3619 * @param aDevice 3620 * The device in question. 3621 * @param aMaskedIfs 3622 * The interfaces to hide from the guest. 3623 * 3624 * @note Locks this object for writing. 3619 3625 */ 3620 HRESULT Console::onUSBDeviceAttach 3626 HRESULT Console::onUSBDeviceAttach(IUSBDevice *aDevice, IVirtualBoxErrorInfo *aError, ULONG aMaskedIfs) 3621 3627 { 3622 3628 #ifdef VBOX_WITH_USB … … 3624 3630 3625 3631 AutoCaller autoCaller(this); 3626 ComAssertComRCRetRC 3632 ComAssertComRCRetRC(autoCaller.rc()); 3627 3633 3628 3634 AutoWriteLock alock(this); 3629 3635 3630 3636 /* protect mpVM (we don't need error info, since it's a callback) */ 3631 AutoVMCallerQuiet autoVMCaller 3632 if (FAILED 3637 AutoVMCallerQuiet autoVMCaller(this); 3638 if (FAILED(autoVMCaller.rc())) 3633 3639 { 3634 3640 /* The VM may be no more operational when this message arrives … … 3643 3649 { 3644 3650 /* notify callbacks about the error */ 3645 onUSBDeviceStateChange 3651 onUSBDeviceStateChange(aDevice, true /* aAttached */, aError); 3646 3652 return S_OK; 3647 3653 } 3648 3654 3649 3655 /* Don't proceed unless there's at least one USB hub. */ 3650 if (!PDMR3USBHasHub 3656 if (!PDMR3USBHasHub(mpVM)) 3651 3657 { 3652 3658 LogFlowThisFunc(("Attach request ignored (no USB controller).\n")); … … 3654 3660 } 3655 3661 3656 HRESULT rc = attachUSBDevice 3657 if (FAILED 3662 HRESULT rc = attachUSBDevice(aDevice, aMaskedIfs); 3663 if (FAILED(rc)) 3658 3664 { 3659 3665 /* take the current error info */ … … 3661 3667 /* the error must be a VirtualBoxErrorInfo instance */ 3662 3668 ComPtr<IVirtualBoxErrorInfo> error = eik.takeError(); 3663 Assert 3669 Assert(!error.isNull()); 3664 3670 if (!error.isNull()) 3665 3671 { 3666 3672 /* notify callbacks about the error */ 3667 onUSBDeviceStateChange 3673 onUSBDeviceStateChange(aDevice, true /* aAttached */, error); 3668 3674 } 3669 3675 } … … 3677 3683 3678 3684 /** 3679 * 3680 * 3681 * 3682 * 3685 * Called by IInternalSessionControl::OnUSBDeviceDetach() and locally by 3686 * processRemoteUSBDevices(). 3687 * 3688 * @note Locks this object for writing. 3683 3689 */ 3684 HRESULT Console::onUSBDeviceDetach 3685 3690 HRESULT Console::onUSBDeviceDetach(IN_BSTR aId, 3691 IVirtualBoxErrorInfo *aError) 3686 3692 { 3687 3693 #ifdef VBOX_WITH_USB 3688 Guid Uuid 3694 Guid Uuid(aId); 3689 3695 LogFlowThisFunc(("aId={%RTuuid} aError=%p\n", Uuid.raw(), aError)); 3690 3696 … … 3718 3724 * failure in this case. */ 3719 3725 3720 AutoVMCallerQuiet autoVMCaller 3721 if (FAILED 3726 AutoVMCallerQuiet autoVMCaller(this); 3727 if (FAILED(autoVMCaller.rc())) 3722 3728 { 3723 3729 LogFlowThisFunc(("Detach request ignored (mMachineState=%d).\n", … … 3727 3733 3728 3734 /* the device must be in the list otherwise */ 3729 AssertFailedReturn 3735 AssertFailedReturn(E_FAIL); 3730 3736 } 3731 3737 … … 3733 3739 { 3734 3740 /* notify callback about an error */ 3735 onUSBDeviceStateChange 3741 onUSBDeviceStateChange(device, false /* aAttached */, aError); 3736 3742 return S_OK; 3737 3743 } 3738 3744 3739 HRESULT rc = detachUSBDevice 3740 3741 if (FAILED 3745 HRESULT rc = detachUSBDevice(it); 3746 3747 if (FAILED(rc)) 3742 3748 { 3743 3749 /* take the current error info */ … … 3745 3751 /* the error must be a VirtualBoxErrorInfo instance */ 3746 3752 ComPtr<IVirtualBoxErrorInfo> error = eik.takeError(); 3747 Assert 3753 Assert(!error.isNull()); 3748 3754 if (!error.isNull()) 3749 3755 { 3750 3756 /* notify callbacks about the error */ 3751 onUSBDeviceStateChange 3757 onUSBDeviceStateChange(device, false /* aAttached */, error); 3752 3758 } 3753 3759 } … … 3763 3769 * @note Temporarily locks this object for writing. 3764 3770 */ 3765 HRESULT Console::getGuestProperty 3766 3767 { 3768 #if !defined (VBOX_WITH_GUEST_PROPS)3771 HRESULT Console::getGuestProperty(IN_BSTR aName, BSTR *aValue, 3772 ULONG64 *aTimestamp, BSTR *aFlags) 3773 { 3774 #ifndef VBOX_WITH_GUEST_PROPS 3769 3775 ReturnComNotImplemented(); 3770 3776 #else 3771 if (!VALID_PTR 3777 if (!VALID_PTR(aName)) 3772 3778 return E_INVALIDARG; 3773 if (!VALID_PTR 3779 if (!VALID_PTR(aValue)) 3774 3780 return E_POINTER; 3775 if ((aTimestamp != NULL) && !VALID_PTR 3781 if ((aTimestamp != NULL) && !VALID_PTR(aTimestamp)) 3776 3782 return E_POINTER; 3777 if ((aFlags != NULL) && !VALID_PTR 3783 if ((aFlags != NULL) && !VALID_PTR(aFlags)) 3778 3784 return E_POINTER; 3779 3785 … … 3782 3788 3783 3789 /* protect mpVM (if not NULL) */ 3784 AutoVMCallerWeak autoVMCaller 3790 AutoVMCallerWeak autoVMCaller(this); 3785 3791 CheckComRCReturnRC(autoVMCaller.rc()); 3786 3792 … … 3804 3810 parm[1].u.pointer.addr = pszBuffer; 3805 3811 parm[1].u.pointer.size = sizeof(pszBuffer); 3806 int vrc = mVMMDev->hgcmHostCall 3812 int vrc = mVMMDev->hgcmHostCall("VBoxGuestPropSvc", GET_PROP_HOST, 3807 3813 4, &parm[0]); 3808 3814 /* The returned string should never be able to be greater than our buffer */ 3809 AssertLogRel 3810 AssertLogRel 3815 AssertLogRel(vrc != VERR_BUFFER_OVERFLOW); 3816 AssertLogRel(RT_FAILURE(vrc) || VBOX_HGCM_SVC_PARM_64BIT == parm[2].type); 3811 3817 if (RT_SUCCESS(vrc) || (VERR_NOT_FOUND == vrc)) 3812 3818 { … … 3826 3832 } 3827 3833 else 3828 rc = setError (E_UNEXPECTED, 3829 tr ("The service call failed with the error %Rrc"), vrc); 3834 rc = setError(E_UNEXPECTED, 3835 tr("The service call failed with the error %Rrc"), 3836 vrc); 3830 3837 } 3831 3838 catch(std::bad_alloc & /*e*/) … … 3834 3841 } 3835 3842 return rc; 3836 #endif /* else !defined (VBOX_WITH_GUEST_PROPS)*/3843 #endif /* VBOX_WITH_GUEST_PROPS */ 3837 3844 } 3838 3845 … … 3840 3847 * @note Temporarily locks this object for writing. 3841 3848 */ 3842 HRESULT Console::setGuestProperty 3843 { 3844 #if !defined (VBOX_WITH_GUEST_PROPS)3849 HRESULT Console::setGuestProperty(IN_BSTR aName, IN_BSTR aValue, IN_BSTR aFlags) 3850 { 3851 #ifndef VBOX_WITH_GUEST_PROPS 3845 3852 ReturnComNotImplemented(); 3846 3853 #else 3847 if (!VALID_PTR 3854 if (!VALID_PTR(aName)) 3848 3855 return E_INVALIDARG; 3849 if ((aValue != NULL) && !VALID_PTR 3856 if ((aValue != NULL) && !VALID_PTR(aValue)) 3850 3857 return E_INVALIDARG; 3851 if ((aFlags != NULL) && !VALID_PTR 3858 if ((aFlags != NULL) && !VALID_PTR(aFlags)) 3852 3859 return E_INVALIDARG; 3853 3860 … … 3856 3863 3857 3864 /* protect mpVM (if not NULL) */ 3858 AutoVMCallerWeak autoVMCaller 3865 AutoVMCallerWeak autoVMCaller(this); 3859 3866 CheckComRCReturnRC(autoVMCaller.rc()); 3860 3867 … … 3890 3897 } 3891 3898 if ((aValue != NULL) && (aFlags != NULL)) 3892 vrc = mVMMDev->hgcmHostCall 3893 3899 vrc = mVMMDev->hgcmHostCall("VBoxGuestPropSvc", SET_PROP_HOST, 3900 3, &parm[0]); 3894 3901 else if (aValue != NULL) 3895 vrc = mVMMDev->hgcmHostCall 3896 3902 vrc = mVMMDev->hgcmHostCall("VBoxGuestPropSvc", SET_PROP_VALUE_HOST, 3903 2, &parm[0]); 3897 3904 else 3898 vrc = mVMMDev->hgcmHostCall 3899 3905 vrc = mVMMDev->hgcmHostCall("VBoxGuestPropSvc", DEL_PROP_HOST, 3906 1, &parm[0]); 3900 3907 if (RT_SUCCESS(vrc)) 3901 3908 rc = S_OK; 3902 3909 else 3903 rc = setError (E_UNEXPECTED, 3904 tr ("The service call failed with the error %Rrc"), vrc); 3910 rc = setError(E_UNEXPECTED, 3911 tr("The service call failed with the error %Rrc"), 3912 vrc); 3905 3913 return rc; 3906 #endif /* else !defined (VBOX_WITH_GUEST_PROPS)*/3914 #endif /* VBOX_WITH_GUEST_PROPS */ 3907 3915 } 3908 3916 … … 3911 3919 * @note Temporarily locks this object for writing. 3912 3920 */ 3913 HRESULT Console::enumerateGuestProperties 3914 3915 3916 3917 3918 { 3919 #if !defined (VBOX_WITH_GUEST_PROPS)3921 HRESULT Console::enumerateGuestProperties(IN_BSTR aPatterns, 3922 ComSafeArrayOut(BSTR, aNames), 3923 ComSafeArrayOut(BSTR, aValues), 3924 ComSafeArrayOut(ULONG64, aTimestamps), 3925 ComSafeArrayOut(BSTR, aFlags)) 3926 { 3927 #ifndef VBOX_WITH_GUEST_PROPS 3920 3928 ReturnComNotImplemented(); 3921 3929 #else 3922 if (!VALID_PTR 3930 if (!VALID_PTR(aPatterns) && (aPatterns != NULL)) 3923 3931 return E_POINTER; 3924 3932 if (ComSafeArrayOutIsNull(aNames)) … … 3935 3943 3936 3944 /* protect mpVM (if not NULL) */ 3937 AutoVMCallerWeak autoVMCaller 3945 AutoVMCallerWeak autoVMCaller(this); 3938 3946 CheckComRCReturnRC(autoVMCaller.rc()); 3939 3947 … … 3941 3949 * autoVMCaller, so there is no need to hold a lock of this */ 3942 3950 3943 return doEnumerateGuestProperties 3944 3945 3946 3947 #endif /* else !defined (VBOX_WITH_GUEST_PROPS)*/3951 return doEnumerateGuestProperties(aPatterns, ComSafeArrayOutArg(aNames), 3952 ComSafeArrayOutArg(aValues), 3953 ComSafeArrayOutArg(aTimestamps), 3954 ComSafeArrayOutArg(aFlags)); 3955 #endif /* VBOX_WITH_GUEST_PROPS */ 3948 3956 } 3949 3957 3950 3958 /** 3951 * 3952 * 3953 * 3954 * 3955 * 3956 * 3959 * Gets called by Session::UpdateMachineState() 3960 * (IInternalSessionControl::updateMachineState()). 3961 * 3962 * Must be called only in certain cases (see the implementation). 3963 * 3964 * @note Locks this object for writing. 3957 3965 */ 3958 HRESULT Console::updateMachineState 3966 HRESULT Console::updateMachineState(MachineState_T aMachineState) 3959 3967 { 3960 3968 AutoCaller autoCaller(this); … … 3967 3975 E_FAIL); 3968 3976 3969 return setMachineStateLocally 3977 return setMachineStateLocally(aMachineState); 3970 3978 } 3971 3979 3972 3980 /** 3973 * 3981 * @note Locks this object for writing. 3974 3982 */ 3975 3983 void Console::onMousePointerShapeChange(bool fVisible, bool fAlpha, … … 3980 3988 #if 0 3981 3989 LogFlowThisFuncEnter(); 3982 LogFlowThisFunc(("fVisible=%d, fAlpha=%d, xHot = %d, yHot = %d, width=%d, " 3983 "height=%d, shape=%p\n", 3990 LogFlowThisFunc(("fVisible=%d, fAlpha=%d, xHot = %d, yHot = %d, width=%d, height=%d, shape=%p\n", 3984 3991 fVisible, fAlpha, xHot, yHot, width, height, pShape)); 3985 3992 #endif 3986 3993 3987 3994 AutoCaller autoCaller(this); 3988 AssertComRCReturnVoid 3995 AssertComRCReturnVoid(autoCaller.rc()); 3989 3996 3990 3997 /* We need a write lock because we alter the cached callback data */ … … 4013 4020 if (mCallbackData.mpsc.shape != NULL && mCallbackData.mpsc.shapeSize != cb) 4014 4021 { 4015 RTMemFree 4022 RTMemFree(mCallbackData.mpsc.shape); 4016 4023 mCallbackData.mpsc.shape = NULL; 4017 4024 } 4018 4025 if (mCallbackData.mpsc.shape == NULL) 4019 4026 { 4020 mCallbackData.mpsc.shape = (BYTE *) RTMemAllocZ 4021 AssertReturnVoid 4027 mCallbackData.mpsc.shape = (BYTE *) RTMemAllocZ(cb); 4028 AssertReturnVoid(mCallbackData.mpsc.shape); 4022 4029 } 4023 4030 mCallbackData.mpsc.shapeSize = cb; 4024 memcpy 4031 memcpy(mCallbackData.mpsc.shape, pShape, cb); 4025 4032 } 4026 4033 else 4027 4034 { 4028 4035 if (wasValid && mCallbackData.mpsc.shape != NULL) 4029 RTMemFree 4036 RTMemFree(mCallbackData.mpsc.shape); 4030 4037 mCallbackData.mpsc.shape = NULL; 4031 4038 mCallbackData.mpsc.shapeSize = 0; … … 4036 4043 CallbackList::iterator it = mCallbacks.begin(); 4037 4044 while (it != mCallbacks.end()) 4038 (*it++)->OnMousePointerShapeChange 4039 4045 (*it++)->OnMousePointerShapeChange(fVisible, fAlpha, xHot, yHot, 4046 width, height, (BYTE *) pShape); 4040 4047 4041 4048 #if 0 … … 4045 4052 4046 4053 /** 4047 * 4054 * @note Locks this object for writing. 4048 4055 */ 4049 void Console::onMouseCapabilityChange 4056 void Console::onMouseCapabilityChange(BOOL supportsAbsolute, BOOL needsHostCursor) 4050 4057 { 4051 4058 LogFlowThisFunc(("supportsAbsolute=%d needsHostCursor=%d\n", … … 4053 4060 4054 4061 AutoCaller autoCaller(this); 4055 AssertComRCReturnVoid 4062 AssertComRCReturnVoid(autoCaller.rc()); 4056 4063 4057 4064 /* We need a write lock because we alter the cached callback data */ … … 4067 4074 { 4068 4075 Log2(("Console::onMouseCapabilityChange: calling %p\n", (void*)*it)); 4069 (*it++)->OnMouseCapabilityChange 4076 (*it++)->OnMouseCapabilityChange(supportsAbsolute, needsHostCursor); 4070 4077 } 4071 4078 } 4072 4079 4073 4080 /** 4074 * 4081 * @note Locks this object for reading. 4075 4082 */ 4076 void Console::onStateChange 4083 void Console::onStateChange(MachineState_T machineState) 4077 4084 { 4078 4085 AutoCaller autoCaller(this); 4079 AssertComRCReturnVoid 4086 AssertComRCReturnVoid(autoCaller.rc()); 4080 4087 4081 4088 AutoReadLock alock(this); … … 4083 4090 CallbackList::iterator it = mCallbacks.begin(); 4084 4091 while (it != mCallbacks.end()) 4085 (*it++)->OnStateChange 4092 (*it++)->OnStateChange(machineState); 4086 4093 } 4087 4094 4088 4095 /** 4089 * 4096 * @note Locks this object for reading. 4090 4097 */ 4091 4098 void Console::onAdditionsStateChange() 4092 4099 { 4093 4100 AutoCaller autoCaller(this); 4094 AssertComRCReturnVoid 4101 AssertComRCReturnVoid(autoCaller.rc()); 4095 4102 4096 4103 AutoReadLock alock(this); … … 4102 4109 4103 4110 /** 4104 * 4111 * @note Locks this object for reading. 4105 4112 */ 4106 4113 void Console::onAdditionsOutdated() 4107 4114 { 4108 4115 AutoCaller autoCaller(this); 4109 AssertComRCReturnVoid 4116 AssertComRCReturnVoid(autoCaller.rc()); 4110 4117 4111 4118 AutoReadLock alock(this); 4112 4119 4113 4120 /** @todo Use the On-Screen Display feature to report the fact. 4114 * 4115 * 4116 * 4121 * The user should be told to install additions that are 4122 * provided with the current VBox build: 4123 * VBOX_VERSION_MAJOR.VBOX_VERSION_MINOR.VBOX_VERSION_BUILD 4117 4124 */ 4118 4125 } 4119 4126 4120 4127 /** 4121 * 4128 * @note Locks this object for writing. 4122 4129 */ 4123 4130 void Console::onKeyboardLedsChange(bool fNumLock, bool fCapsLock, bool fScrollLock) 4124 4131 { 4125 4132 AutoCaller autoCaller(this); 4126 AssertComRCReturnVoid 4133 AssertComRCReturnVoid(autoCaller.rc()); 4127 4134 4128 4135 /* We need a write lock because we alter the cached callback data */ … … 4141 4148 4142 4149 /** 4143 * 4150 * @note Locks this object for reading. 4144 4151 */ 4145 void Console::onUSBDeviceStateChange 4146 4152 void Console::onUSBDeviceStateChange(IUSBDevice *aDevice, bool aAttached, 4153 IVirtualBoxErrorInfo *aError) 4147 4154 { 4148 4155 AutoCaller autoCaller(this); 4149 AssertComRCReturnVoid 4156 AssertComRCReturnVoid(autoCaller.rc()); 4150 4157 4151 4158 AutoReadLock alock(this); … … 4153 4160 CallbackList::iterator it = mCallbacks.begin(); 4154 4161 while (it != mCallbacks.end()) 4155 (*it++)->OnUSBDeviceStateChange 4162 (*it++)->OnUSBDeviceStateChange(aDevice, aAttached, aError); 4156 4163 } 4157 4164 4158 4165 /** 4159 * 4166 * @note Locks this object for reading. 4160 4167 */ 4161 void Console::onRuntimeError 4168 void Console::onRuntimeError(BOOL aFatal, IN_BSTR aErrorID, IN_BSTR aMessage) 4162 4169 { 4163 4170 AutoCaller autoCaller(this); 4164 AssertComRCReturnVoid 4171 AssertComRCReturnVoid(autoCaller.rc()); 4165 4172 4166 4173 AutoReadLock alock(this); … … 4168 4175 CallbackList::iterator it = mCallbacks.begin(); 4169 4176 while (it != mCallbacks.end()) 4170 (*it++)->OnRuntimeError 4177 (*it++)->OnRuntimeError(aFatal, aErrorID, aMessage); 4171 4178 } 4172 4179 4173 4180 /** 4174 * 4181 * @note Locks this object for reading. 4175 4182 */ 4176 HRESULT Console::onShowWindow 4183 HRESULT Console::onShowWindow(BOOL aCheck, BOOL *aCanShow, ULONG64 *aWinId) 4177 4184 { 4178 4185 AssertReturn(aCanShow, E_POINTER); … … 4195 4202 { 4196 4203 BOOL canShow = FALSE; 4197 rc = (*it++)->OnCanShowWindow 4198 AssertComRC 4199 if (FAILED 4204 rc = (*it++)->OnCanShowWindow(&canShow); 4205 AssertComRC(rc); 4206 if (FAILED(rc) || !canShow) 4200 4207 return rc; 4201 4208 } … … 4207 4214 { 4208 4215 ULONG64 winId = 0; 4209 rc = (*it++)->OnShowWindow 4210 AssertComRC 4211 if (FAILED 4216 rc = (*it++)->OnShowWindow(&winId); 4217 AssertComRC(rc); 4218 if (FAILED(rc)) 4212 4219 return rc; 4213 4220 /* only one callback may return non-null winId */ 4214 Assert 4221 Assert(*aWinId == 0 || winId == 0); 4215 4222 if (*aWinId == 0) 4216 4223 *aWinId = winId; … … 4225 4232 4226 4233 /** 4227 * 4228 * 4229 * 4230 * 4231 * 4232 * 4233 * 4234 * 4235 * 4236 * 4237 * 4238 * 4239 * 4240 * 4241 * 4242 * 4243 * 4244 * 4245 * 4246 * 4247 * 4234 * Increases the usage counter of the mpVM pointer. Guarantees that 4235 * VMR3Destroy() will not be called on it at least until releaseVMCaller() 4236 * is called. 4237 * 4238 * If this method returns a failure, the caller is not allowed to use mpVM 4239 * and may return the failed result code to the upper level. This method sets 4240 * the extended error info on failure if \a aQuiet is false. 4241 * 4242 * Setting \a aQuiet to true is useful for methods that don't want to return 4243 * the failed result code to the caller when this method fails (e.g. need to 4244 * silently check for the mpVM availability). 4245 * 4246 * When mpVM is NULL but \a aAllowNullVM is true, a corresponding error will be 4247 * returned instead of asserting. Having it false is intended as a sanity check 4248 * for methods that have checked mMachineState and expect mpVM *NOT* to be NULL. 4249 * 4250 * @param aQuiet true to suppress setting error info 4251 * @param aAllowNullVM true to accept mpVM being NULL and return a failure 4252 * (otherwise this method will assert if mpVM is NULL) 4253 * 4254 * @note Locks this object for writing. 4248 4255 */ 4249 HRESULT Console::addVMCaller 4250 4251 { 4252 AutoCaller autoCaller(this);4256 HRESULT Console::addVMCaller(bool aQuiet /* = false */, 4257 bool aAllowNullVM /* = false */) 4258 { 4259 AutoCaller autoCaller(this); 4253 4260 AssertComRCReturnRC(autoCaller.rc()); 4254 4261 … … 4258 4265 { 4259 4266 /* powerDown() is waiting for all callers to finish */ 4260 return aQuiet ? E_ACCESSDENIED : setError 4261 tr 4267 return aQuiet ? E_ACCESSDENIED : setError(E_ACCESSDENIED, 4268 tr("Virtual machine is being powered down")); 4262 4269 } 4263 4270 4264 4271 if (mpVM == NULL) 4265 4272 { 4266 Assert 4273 Assert(aAllowNullVM == true); 4267 4274 4268 4275 /* The machine is not powered up */ 4269 return aQuiet ? E_ACCESSDENIED : setError 4270 tr 4276 return aQuiet ? E_ACCESSDENIED : setError(E_ACCESSDENIED, 4277 tr("Virtual machine is not powered up")); 4271 4278 } 4272 4279 … … 4277 4284 4278 4285 /** 4279 * 4280 * 4281 * 4282 * 4286 * Decreases the usage counter of the mpVM pointer. Must always complete 4287 * the addVMCaller() call after the mpVM pointer is no more necessary. 4288 * 4289 * @note Locks this object for writing. 4283 4290 */ 4284 4291 void Console::releaseVMCaller() 4285 4292 { 4286 AutoCaller autoCaller(this);4287 AssertComRCReturnVoid 4293 AutoCaller autoCaller(this); 4294 AssertComRCReturnVoid(autoCaller.rc()); 4288 4295 4289 4296 AutoWriteLock alock(this); 4290 4297 4291 AssertReturnVoid 4292 4293 Assert 4294 -- 4298 AssertReturnVoid(mpVM != NULL); 4299 4300 Assert(mVMCallers > 0); 4301 --mVMCallers; 4295 4302 4296 4303 if (mVMCallers == 0 && mVMDestroying) 4297 4304 { 4298 4305 /* inform powerDown() there are no more callers */ 4299 RTSemEventSignal 4306 RTSemEventSignal(mVMZeroCallersSem); 4300 4307 } 4301 4308 } … … 4307 4314 * Note that the logic must be in sync with Machine::DeleteSettings(). 4308 4315 */ 4309 HRESULT Console::consoleInitReleaseLog 4316 HRESULT Console::consoleInitReleaseLog(const ComPtr<IMachine> aMachine) 4310 4317 { 4311 4318 HRESULT hrc = S_OK; 4312 4319 4313 4320 Bstr logFolder; 4314 hrc = aMachine->COMGETTER(LogFolder) 4321 hrc = aMachine->COMGETTER(LogFolder)(logFolder.asOutParam()); 4315 4322 CheckComRCReturnRC(hrc); 4316 4323 … … 4350 4357 Utf8Str oldName, newName; 4351 4358 4352 for (unsigned int j = 0; j < RT_ELEMENTS 4359 for (unsigned int j = 0; j < RT_ELEMENTS(files); ++ j) 4353 4360 { 4354 4361 if (i > 0) 4355 oldName = Utf8StrFmt ("%s.%d", files[j]->raw(), i);4362 oldName = Utf8StrFmt("%s.%d", files[j]->raw(), i); 4356 4363 else 4357 oldName = *files 4358 newName = Utf8StrFmt ("%s.%d", files[j]->raw(), i + 1);4364 oldName = *files[j]; 4365 newName = Utf8StrFmt("%s.%d", files[j]->raw(), i + 1); 4359 4366 /* If the old file doesn't exist, delete the new file (if it 4360 4367 * exists) to provide correct rotation even if the sequence is … … 4370 4377 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; 4371 4378 RTUINT fFlags = RTLOGFLAGS_PREFIX_TIME_PROG; 4372 #if defined (RT_OS_WINDOWS) || defined(RT_OS_OS2)4379 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 4373 4380 fFlags |= RTLOGFLAGS_USECRLF; 4374 4381 #endif … … 4426 4433 } 4427 4434 else 4428 hrc = setError (E_FAIL, 4429 tr ("Failed to open release log (%s, %Rrc)"), szError, vrc); 4435 hrc = setError(E_FAIL, 4436 tr("Failed to open release log (%s, %Rrc)"), 4437 szError, vrc); 4430 4438 4431 4439 return hrc; … … 4442 4450 * @todo move down to powerDown(); 4443 4451 */ 4444 HRESULT Console::powerUp 4452 HRESULT Console::powerUp(IProgress **aProgress, bool aPaused) 4445 4453 { 4446 4454 if (aProgress == NULL) … … 4455 4463 AutoWriteLock alock(this); 4456 4464 4457 if (Global::IsOnlineOrTransient 4465 if (Global::IsOnlineOrTransient(mMachineState)) 4458 4466 return setError(VBOX_E_INVALID_VM_STATE, 4459 tr ("Virtual machine is already running or busy "4460 "(machine state: %d)"),mMachineState);4467 tr("Virtual machine is already running or busy (machine state: %d)"), 4468 mMachineState); 4461 4469 4462 4470 HRESULT rc = S_OK; … … 4466 4474 { 4467 4475 ComPtr<INetworkAdapter> adapter; 4468 mMachine->GetNetworkAdapter 4476 mMachine->GetNetworkAdapter(slot, adapter.asOutParam()); 4469 4477 BOOL enabled = FALSE; 4470 adapter->COMGETTER(Enabled) 4478 adapter->COMGETTER(Enabled)(&enabled); 4471 4479 if (!enabled) 4472 4480 continue; … … 4484 4492 if (!hostif) 4485 4493 { 4486 return setError (VBOX_E_HOST_ERROR, 4487 tr ("VM cannot start because host interface networking " 4488 "requires a host interface name to be set")); 4494 return setError(VBOX_E_HOST_ERROR, 4495 tr("VM cannot start because host interface networking requires a host interface name to be set")); 4489 4496 } 4490 4497 ComPtr<IVirtualBox> virtualBox; … … 4495 4502 if (!SUCCEEDED(host->FindHostNetworkInterfaceByName(hostif, hostInterface.asOutParam()))) 4496 4503 { 4497 return setError (VBOX_E_HOST_ERROR, 4498 tr ("VM cannot start because the host interface '%ls' " 4499 "does not exist"), 4504 return setError(VBOX_E_HOST_ERROR, 4505 tr("VM cannot start because the host interface '%ls' does not exist"), 4500 4506 hostif.raw()); 4501 4507 } … … 4518 4524 for (SharedFolderDataMap::const_iterator it = mGlobalSharedFolders.begin(); 4519 4525 it != mGlobalSharedFolders.end(); ++ it) 4520 sharedFolders 4526 sharedFolders[it->first] = it->second; 4521 4527 4522 4528 /* second, insert machine folders */ 4523 4529 for (SharedFolderDataMap::const_iterator it = mMachineSharedFolders.begin(); 4524 4530 it != mMachineSharedFolders.end(); ++ it) 4525 sharedFolders 4531 sharedFolders[it->first] = it->second; 4526 4532 4527 4533 /* third, insert console folders */ 4528 4534 for (SharedFolderMap::const_iterator it = mSharedFolders.begin(); 4529 4535 it != mSharedFolders.end(); ++ it) 4530 sharedFolders 4536 sharedFolders[it->first] = SharedFolderData(it->second->hostPath(), it->second->writable()); 4531 4537 } 4532 4538 … … 4538 4544 if (mMachineState == MachineState_Saved) 4539 4545 { 4540 rc = mMachine->COMGETTER(StateFilePath) 4546 rc = mMachine->COMGETTER(StateFilePath)(savedStateFile.asOutParam()); 4541 4547 CheckComRCReturnRC(rc); 4542 ComAssertRet 4548 ComAssertRet(!!savedStateFile, E_FAIL); 4543 4549 int vrc = SSMR3ValidateFile(Utf8Str(savedStateFile).c_str(), false /* fChecksumIt */); 4544 if ( VBOX_FAILURE(vrc))4550 if (RT_FAILURE(vrc)) 4545 4551 return setError(VBOX_E_FILE_ERROR, 4546 tr("VM cannot start because the saved state file '%ls' is invalid (%Rrc). " 4547 "Discard the saved state prior to starting the VM"), 4552 tr("VM cannot start because the saved state file '%ls' is invalid (%Rrc). Discard the saved state prior to starting the VM"), 4548 4553 savedStateFile.raw(), vrc); 4549 4554 } … … 4554 4559 Bstr progressDesc; 4555 4560 if (mMachineState == MachineState_Saved) 4556 progressDesc = tr 4561 progressDesc = tr("Restoring virtual machine"); 4557 4562 else 4558 progressDesc = tr 4559 rc = powerupProgress->init (static_cast <IConsole *>(this),4560 4563 progressDesc = tr("Starting virtual machine"); 4564 rc = powerupProgress->init(static_cast<IConsole *>(this), 4565 progressDesc, FALSE /* aCancelable */); 4561 4566 CheckComRCReturnRC(rc); 4562 4567 … … 4564 4569 * asynchronously */ 4565 4570 4566 std::auto_ptr <VMPowerUpTask> task (new VMPowerUpTask(this, powerupProgress));4567 ComAssertComRCRetRC 4571 std::auto_ptr<VMPowerUpTask> task(new VMPowerUpTask(this, powerupProgress)); 4572 ComAssertComRCRetRC(task->rc()); 4568 4573 4569 4574 task->mSetVMErrorCallback = setVMErrorCallback; … … 4577 4582 { 4578 4583 com::SafeIfaceArray<IMediumAttachment> atts; 4579 rc = mMachine->COMGETTER(MediumAttachments) 4584 rc = mMachine->COMGETTER(MediumAttachments)(ComSafeArrayAsOutParam(atts)); 4580 4585 CheckComRCReturnRC(rc); 4581 4586 … … 4629 4634 ComObjPtr<CombinedProgress> progress; 4630 4635 progress.createObject(); 4631 VMPowerUpTask::ProgressList progresses 4632 progresses.push_back 4633 rc = progress->init (static_cast <IConsole *>(this),4634 4635 4636 VMPowerUpTask::ProgressList progresses(task->hardDiskProgresses); 4637 progresses.push_back(ComPtr<IProgress> (powerupProgress)); 4638 rc = progress->init(static_cast<IConsole *>(this), 4639 progressDesc, progresses.begin(), 4640 progresses.end()); 4636 4641 AssertComRCReturnRC(rc); 4637 4642 progress.queryInterfaceTo(aProgress); … … 4639 4644 } 4640 4645 4641 int vrc = RTThreadCreate 4642 4643 4644 ComAssertMsgRCRet 4645 4646 int vrc = RTThreadCreate(NULL, Console::powerUpThread, (void *) task.get(), 4647 0, RTTHREADTYPE_MAIN_WORKER, 0, "VMPowerUp"); 4648 4649 ComAssertMsgRCRet(vrc, ("Could not create VMPowerUp thread (%Rrc)", vrc), 4650 E_FAIL); 4646 4651 4647 4652 /* task is now owned by powerUpThread(), so release it */ … … 4653 4658 4654 4659 if (mMachineState == MachineState_Saved) 4655 setMachineState 4660 setMachineState(MachineState_Restoring); 4656 4661 else 4657 setMachineState 4662 setMachineState(MachineState_Starting); 4658 4663 4659 4664 LogFlowThisFunc(("mMachineState=%d\n", mMachineState)); … … 4690 4695 * release(). Otherwise it will deadlock. 4691 4696 */ 4692 HRESULT Console::powerDown 4697 HRESULT Console::powerDown(Progress *aProgress /*= NULL*/) 4693 4698 { 4694 4699 LogFlowThisFuncEnter(); … … 4709 4714 4710 4715 /* sanity */ 4711 Assert (mVMDestroying == false); 4712 4713 Assert (mpVM != NULL); 4714 4715 AssertMsg (mMachineState == MachineState_Running || 4716 mMachineState == MachineState_Paused || 4717 mMachineState == MachineState_Stuck || 4718 mMachineState == MachineState_Saving || 4719 mMachineState == MachineState_Starting || 4720 mMachineState == MachineState_Restoring || 4721 mMachineState == MachineState_Stopping, 4722 ("Invalid machine state: %d\n", mMachineState)); 4723 4724 LogRel (("Console::powerDown(): A request to power off the VM has been " 4725 "issued (mMachineState=%d, InUninit=%d)\n", 4716 Assert(mVMDestroying == false); 4717 4718 Assert(mpVM != NULL); 4719 4720 AssertMsg(mMachineState == MachineState_Running || 4721 mMachineState == MachineState_Paused || 4722 mMachineState == MachineState_Stuck || 4723 mMachineState == MachineState_Saving || 4724 mMachineState == MachineState_Starting || 4725 mMachineState == MachineState_Restoring || 4726 mMachineState == MachineState_Stopping, 4727 ("Invalid machine state: %d\n", mMachineState)); 4728 4729 LogRel(("Console::powerDown(): A request to power off the VM has been issued (mMachineState=%d, InUninit=%d)\n", 4726 4730 mMachineState, autoCaller.state() == InUninit)); 4727 4731 … … 4744 4748 mMachineState != MachineState_Restoring && 4745 4749 mMachineState != MachineState_Stopping) 4746 setMachineState 4750 setMachineState(MachineState_Stopping); 4747 4751 4748 4752 /* ---------------------------------------------------------------------- … … 4783 4787 rc = E_OUTOFMEMORY; 4784 4788 else 4785 rc = doEnumerateGuestProperties (Bstr (""), ComSafeArrayAsOutParam(namesOut),4786 ComSafeArrayAsOutParam 4787 ComSafeArrayAsOutParam 4788 ComSafeArrayAsOutParam 4789 rc = doEnumerateGuestProperties(Bstr(""), ComSafeArrayAsOutParam(namesOut), 4790 ComSafeArrayAsOutParam(valuesOut), 4791 ComSafeArrayAsOutParam(timestampsOut), 4792 ComSafeArrayAsOutParam(flagsOut)); 4789 4793 if (SUCCEEDED(rc)) 4790 4794 { … … 4798 4802 { 4799 4803 uint32_t fFlags; 4800 guestProp::validateFlags 4804 guestProp::validateFlags(Utf8Str(flagsOut[i]).raw(), &fFlags); 4801 4805 if ( !( fFlags & guestProp::TRANSIENT) 4802 4806 || (mMachineState == MachineState_Saving) … … 4809 4813 } 4810 4814 } 4811 com::SafeArray<BSTR> namesIn 4812 com::SafeArray<BSTR> valuesIn 4813 com::SafeArray<ULONG64> timestampsIn 4814 com::SafeArray<BSTR> flagsIn 4815 com::SafeArray<BSTR> namesIn(names); 4816 com::SafeArray<BSTR> valuesIn(values); 4817 com::SafeArray<ULONG64> timestampsIn(timestamps); 4818 com::SafeArray<BSTR> flagsIn(flags); 4815 4819 if ( namesIn.isNull() 4816 4820 || valuesIn.isNull() … … 4821 4825 /* PushGuestProperties() calls DiscardSettings(), which calls us back */ 4822 4826 alock.leave(); 4823 mControl->PushGuestProperties (ComSafeArrayAsInParam(namesIn),4824 ComSafeArrayAsInParam 4825 ComSafeArrayAsInParam 4826 ComSafeArrayAsInParam 4827 mControl->PushGuestProperties(ComSafeArrayAsInParam(namesIn), 4828 ComSafeArrayAsInParam(valuesIn), 4829 ComSafeArrayAsInParam(timestampsIn), 4830 ComSafeArrayAsInParam(flagsIn)); 4827 4831 alock.enter(); 4828 4832 } … … 4848 4852 alock.leave(); 4849 4853 4850 mVMMDev->hgcmShutdown 4854 mVMMDev->hgcmShutdown(); 4851 4855 4852 4856 alock.enter(); … … 4872 4876 /* lazy creation */ 4873 4877 if (mVMZeroCallersSem == NIL_RTSEMEVENT) 4874 RTSemEventCreate 4878 RTSemEventCreate(&mVMZeroCallersSem); 4875 4879 4876 4880 LogFlowThisFunc(("Waiting for mpVM callers (%d) to drop to zero...\n", … … 4879 4883 alock.leave(); 4880 4884 4881 RTSemEventWait 4885 RTSemEventWait(mVMZeroCallersSem, RT_INDEFINITE_WAIT); 4882 4886 4883 4887 alock.enter(); … … 4898 4902 alock.leave(); 4899 4903 4900 vrc = VMR3PowerOff 4904 vrc = VMR3PowerOff(mpVM); 4901 4905 4902 4906 /* Note that VMR3PowerOff() may fail here (invalid VMSTATE) if the … … 4921 4925 /* If we are called from Console::uninit(), then try to destroy the VM even 4922 4926 * on failure (this will most likely fail too, but what to do?..) */ 4923 if ( VBOX_SUCCESS(vrc) || autoCaller.state() == InUninit)4927 if (RT_SUCCESS(vrc) || autoCaller.state() == InUninit) 4924 4928 { 4925 4929 /* If the machine has an USB comtroller, release all USB devices … … 4928 4932 { 4929 4933 PPDMIBASE pBase; 4930 int vrc = PDMR3QueryLun 4931 if ( VBOX_SUCCESS(vrc))4934 int vrc = PDMR3QueryLun(mpVM, "usb-ohci", 0, 0, &pBase); 4935 if (RT_SUCCESS(vrc)) 4932 4936 { 4933 4937 fHasUSBController = true; 4934 detachAllUSBDevices 4938 detachAllUSBDevices(false /* aDone */); 4935 4939 } 4936 4940 } … … 4952 4956 alock.leave(); 4953 4957 4954 vrc = VMR3Destroy 4958 vrc = VMR3Destroy(pVM); 4955 4959 4956 4960 /* take the lock again */ … … 4961 4965 aProgress->SetCurrentOperationProgress(99 * (++ step) / StepCount ); 4962 4966 4963 if ( VBOX_SUCCESS(vrc))4967 if (RT_SUCCESS(vrc)) 4964 4968 { 4965 4969 LogFlowThisFunc(("Machine has been destroyed (mMachineState=%d)\n", … … 4977 4981 /* bad bad bad, but what to do? */ 4978 4982 mpVM = pVM; 4979 rc = setError (VBOX_E_VM_ERROR, 4980 tr ("Could not destroy the machine. (Error: %Rrc)"), vrc); 4983 rc = setError(VBOX_E_VM_ERROR, 4984 tr("Could not destroy the machine. (Error: %Rrc)"), 4985 vrc); 4981 4986 } 4982 4987 4983 4988 /* Complete the detaching of the USB devices. */ 4984 4989 if (fHasUSBController) 4985 detachAllUSBDevices 4990 detachAllUSBDevices(true /* aDone */); 4986 4991 4987 4992 /* advance percent count */ … … 4991 4996 else 4992 4997 { 4993 rc = setError (VBOX_E_VM_ERROR, 4994 tr ("Could not power off the machine. (Error: %Rrc)"), vrc); 4998 rc = setError(VBOX_E_VM_ERROR, 4999 tr("Could not power off the machine. (Error: %Rrc)"), 5000 vrc); 4995 5001 } 4996 5002 … … 5008 5014 { 5009 5015 if (mCallbackData.mpsc.shape != NULL) 5010 RTMemFree 5011 } 5012 memset (&mCallbackData, 0, sizeof(mCallbackData));5016 RTMemFree(mCallbackData.mpsc.shape); 5017 } 5018 memset(&mCallbackData, 0, sizeof(mCallbackData)); 5013 5019 } 5014 5020 5015 5021 /* complete the progress */ 5016 5022 if (aProgress) 5017 aProgress->notifyComplete 5023 aProgress->notifyComplete(rc); 5018 5024 5019 5025 LogFlowThisFuncLeave(); … … 5022 5028 5023 5029 /** 5024 * 5030 * @note Locks this object for writing. 5025 5031 */ 5026 HRESULT Console::setMachineState 5032 HRESULT Console::setMachineState(MachineState_T aMachineState, 5027 5033 bool aUpdateServer /* = true */) 5028 5034 { … … 5047 5053 // necessary??) 5048 5054 LogFlowThisFunc(("Doing onStateChange()...\n")); 5049 onStateChange 5055 onStateChange(aMachineState); 5050 5056 LogFlowThisFunc(("Done onStateChange()\n")); 5051 5057 … … 5054 5060 /* Server notification MUST be done from under the lock; otherwise 5055 5061 * the machine state here and on the server might go out of sync 5056 * whi hccan lead to various unexpected results (like the machine5062 * which can lead to various unexpected results (like the machine 5057 5063 * state being >= MachineState_Running on the server, while the 5058 5064 * session state is already SessionState_Closed at the same time … … 5066 5072 */ 5067 5073 LogFlowThisFunc(("Doing mControl->UpdateState()...\n")); 5068 rc = mControl->UpdateState 5074 rc = mControl->UpdateState(aMachineState); 5069 5075 LogFlowThisFunc(("mControl->UpdateState()=%08X\n", rc)); 5070 5076 } … … 5075 5081 5076 5082 /** 5077 * 5078 * 5079 * 5080 * 5081 * 5082 * 5083 * 5084 * 5085 * 5086 * 5087 * 5083 * Searches for a shared folder with the given logical name 5084 * in the collection of shared folders. 5085 * 5086 * @param aName logical name of the shared folder 5087 * @param aSharedFolder where to return the found object 5088 * @param aSetError whether to set the error info if the folder is 5089 * not found 5090 * @return 5091 * S_OK when found or E_INVALIDARG when not found 5092 * 5093 * @note The caller must lock this object for writing. 5088 5094 */ 5089 HRESULT Console::findSharedFolder 5090 5091 5095 HRESULT Console::findSharedFolder(CBSTR aName, 5096 ComObjPtr<SharedFolder> &aSharedFolder, 5097 bool aSetError /* = false */) 5092 5098 { 5093 5099 /* sanity check */ 5094 5100 AssertReturn(isWriteLockOnCurrentThread(), E_FAIL); 5095 5101 5096 SharedFolderMap::const_iterator it = mSharedFolders.find 5102 SharedFolderMap::const_iterator it = mSharedFolders.find(aName); 5097 5103 if (it != mSharedFolders.end()) 5098 5104 { … … 5102 5108 5103 5109 if (aSetError) 5104 setError (VBOX_E_FILE_ERROR, 5105 tr ("Could not find a shared folder named '%ls'."), aName); 5110 setError(VBOX_E_FILE_ERROR, 5111 tr("Could not find a shared folder named '%ls'."), 5112 aName); 5106 5113 5107 5114 return VBOX_E_FILE_ERROR; … … 5109 5116 5110 5117 /** 5111 * 5112 * 5113 * 5114 * 5115 * 5118 * Fetches the list of global or machine shared folders from the server. 5119 * 5120 * @param aGlobal true to fetch global folders. 5121 * 5122 * @note The caller must lock this object for writing. 5116 5123 */ 5117 HRESULT Console::fetchSharedFolders 5124 HRESULT Console::fetchSharedFolders(BOOL aGlobal) 5118 5125 { 5119 5126 /* sanity check */ 5120 AssertReturn(AutoCaller 5121 5127 AssertReturn(AutoCaller(this).state() == InInit || 5128 isWriteLockOnCurrentThread(), E_FAIL); 5122 5129 5123 5130 /* protect mpVM (if not NULL) */ 5124 AutoVMCallerQuietWeak autoVMCaller 5131 AutoVMCallerQuietWeak autoVMCaller(this); 5125 5132 5126 5133 HRESULT rc = S_OK; … … 5141 5148 5142 5149 SafeIfaceArray<ISharedFolder> folders; 5143 rc = mMachine->COMGETTER(SharedFolders) 5150 rc = mMachine->COMGETTER(SharedFolders)(ComSafeArrayAsOutParam(folders)); 5144 5151 AssertComRCReturnRC(rc); 5145 5152 … … 5152 5159 BOOL writable; 5153 5160 5154 rc = folder->COMGETTER(Name) 5155 CheckComRCBreakRC 5156 rc = folder->COMGETTER(HostPath) 5157 CheckComRCBreakRC 5158 rc = folder->COMGETTER(Writable) 5159 5160 mMachineSharedFolders.insert (std::make_pair (name, SharedFolderData(hostPath, writable)));5161 rc = folder->COMGETTER(Name)(name.asOutParam()); 5162 CheckComRCBreakRC(rc); 5163 rc = folder->COMGETTER(HostPath)(hostPath.asOutParam()); 5164 CheckComRCBreakRC(rc); 5165 rc = folder->COMGETTER(Writable)(&writable); 5166 5167 mMachineSharedFolders.insert(std::make_pair(name, SharedFolderData(hostPath, writable))); 5161 5168 5162 5169 /* send changes to HGCM if the VM is running */ … … 5164 5171 if (online) 5165 5172 { 5166 SharedFolderDataMap::iterator it = oldFolders.find 5173 SharedFolderDataMap::iterator it = oldFolders.find(name); 5167 5174 if (it == oldFolders.end() || it->second.mHostPath != hostPath) 5168 5175 { 5169 5176 /* a new machine folder is added or 5170 5177 * the existing machine folder is changed */ 5171 if (mSharedFolders.find 5178 if (mSharedFolders.find(name) != mSharedFolders.end()) 5172 5179 ; /* the console folder exists, nothing to do */ 5173 5180 else … … 5176 5183 * or the global folder if any (when new) */ 5177 5184 if (it != oldFolders.end() || 5178 mGlobalSharedFolders.find 5185 mGlobalSharedFolders.find(name) != 5179 5186 mGlobalSharedFolders.end()) 5180 rc = removeSharedFolder 5187 rc = removeSharedFolder(name); 5181 5188 /* create the new machine folder */ 5182 rc = createSharedFolder (name, SharedFolderData(hostPath, writable));5189 rc = createSharedFolder(name, SharedFolderData(hostPath, writable)); 5183 5190 } 5184 5191 } 5185 5192 /* forget the processed (or identical) folder */ 5186 5193 if (it != oldFolders.end()) 5187 oldFolders.erase 5194 oldFolders.erase(it); 5188 5195 5189 5196 rc = S_OK; … … 5200 5207 it != oldFolders.end(); ++ it) 5201 5208 { 5202 if (mSharedFolders.find 5209 if (mSharedFolders.find(it->first) != mSharedFolders.end()) 5203 5210 ; /* the console folder exists, nothing to do */ 5204 5211 else 5205 5212 { 5206 5213 /* remove the outdated machine folder */ 5207 rc = removeSharedFolder 5214 rc = removeSharedFolder(it->first); 5208 5215 /* create the global folder if there is any */ 5209 5216 SharedFolderDataMap::const_iterator git = 5210 mGlobalSharedFolders.find 5217 mGlobalSharedFolders.find(it->first); 5211 5218 if (git != mGlobalSharedFolders.end()) 5212 rc = createSharedFolder 5219 rc = createSharedFolder(git->first, git->second); 5213 5220 } 5214 5221 } … … 5222 5229 5223 5230 /** 5224 * 5225 * 5226 * 5227 * 5228 * 5229 * 5230 * 5231 * 5231 * Searches for a shared folder with the given name in the list of machine 5232 * shared folders and then in the list of the global shared folders. 5233 * 5234 * @param aName Name of the folder to search for. 5235 * @param aIt Where to store the pointer to the found folder. 5236 * @return @c true if the folder was found and @c false otherwise. 5237 * 5238 * @note The caller must lock this object for reading. 5232 5239 */ 5233 bool Console::findOtherSharedFolder 5234 5240 bool Console::findOtherSharedFolder(IN_BSTR aName, 5241 SharedFolderDataMap::const_iterator &aIt) 5235 5242 { 5236 5243 /* sanity check */ … … 5238 5245 5239 5246 /* first, search machine folders */ 5240 aIt = mMachineSharedFolders.find 5247 aIt = mMachineSharedFolders.find(aName); 5241 5248 if (aIt != mMachineSharedFolders.end()) 5242 5249 return true; 5243 5250 5244 5251 /* second, search machine folders */ 5245 aIt = mGlobalSharedFolders.find 5252 aIt = mGlobalSharedFolders.find(aName); 5246 5253 if (aIt != mGlobalSharedFolders.end()) 5247 5254 return true; … … 5251 5258 5252 5259 /** 5253 * 5254 * 5255 * 5256 * 5257 * 5258 * 5259 * 5260 * Calls the HGCM service to add a shared folder definition. 5261 * 5262 * @param aName Shared folder name. 5263 * @param aHostPath Shared folder path. 5264 * 5265 * @note Must be called from under AutoVMCaller and when mpVM != NULL! 5266 * @note Doesn't lock anything. 5260 5267 */ 5261 HRESULT Console::createSharedFolder 5262 { 5263 ComAssertRet 5264 ComAssertRet 5268 HRESULT Console::createSharedFolder(CBSTR aName, SharedFolderData aData) 5269 { 5270 ComAssertRet(aName && *aName, E_FAIL); 5271 ComAssertRet(aData.mHostPath, E_FAIL); 5265 5272 5266 5273 /* sanity checks */ … … 5268 5275 AssertReturn(mVMMDev->isShFlActive(), E_FAIL); 5269 5276 5270 VBOXHGCMSVCPARM 5271 SHFLSTRING 5272 size_t 5273 5274 Log 5275 5276 cbString = (RTUtf16Len (aData.mHostPath) + 1) * sizeof(RTUTF16);5277 VBOXHGCMSVCPARM parms[SHFL_CPARMS_ADD_MAPPING]; 5278 SHFLSTRING *pFolderName, *pMapName; 5279 size_t cbString; 5280 5281 Log(("Adding shared folder '%ls' -> '%ls'\n", aName, aData.mHostPath.raw())); 5282 5283 cbString = (RTUtf16Len(aData.mHostPath) + 1) * sizeof(RTUTF16); 5277 5284 if (cbString >= UINT16_MAX) 5278 return setError (E_INVALIDARG, tr("The name is too long"));5279 pFolderName = (SHFLSTRING *) RTMemAllocZ (sizeof(SHFLSTRING) + cbString);5280 Assert 5281 memcpy 5285 return setError(E_INVALIDARG, tr("The name is too long")); 5286 pFolderName = (SHFLSTRING *) RTMemAllocZ(sizeof(SHFLSTRING) + cbString); 5287 Assert(pFolderName); 5288 memcpy(pFolderName->String.ucs2, aData.mHostPath, cbString); 5282 5289 5283 5290 pFolderName->u16Size = (uint16_t)cbString; … … 5286 5293 parms[0].type = VBOX_HGCM_SVC_PARM_PTR; 5287 5294 parms[0].u.pointer.addr = pFolderName; 5288 parms[0].u.pointer.size = sizeof 5289 5290 cbString = (RTUtf16Len (aName) + 1) * sizeof(RTUTF16);5295 parms[0].u.pointer.size = sizeof(SHFLSTRING) + (uint16_t)cbString; 5296 5297 cbString = (RTUtf16Len(aName) + 1) * sizeof(RTUTF16); 5291 5298 if (cbString >= UINT16_MAX) 5292 5299 { 5293 RTMemFree 5294 return setError (E_INVALIDARG, tr("The host path is too long"));5295 } 5296 pMapName = (SHFLSTRING *) RTMemAllocZ 5297 Assert 5298 memcpy 5300 RTMemFree(pFolderName); 5301 return setError(E_INVALIDARG, tr("The host path is too long")); 5302 } 5303 pMapName = (SHFLSTRING *) RTMemAllocZ(sizeof(SHFLSTRING) + cbString); 5304 Assert(pMapName); 5305 memcpy(pMapName->String.ucs2, aName, cbString); 5299 5306 5300 5307 pMapName->u16Size = (uint16_t)cbString; 5301 pMapName->u16Length = (uint16_t)cbString - sizeof 5308 pMapName->u16Length = (uint16_t)cbString - sizeof(RTUTF16); 5302 5309 5303 5310 parms[1].type = VBOX_HGCM_SVC_PARM_PTR; 5304 5311 parms[1].u.pointer.addr = pMapName; 5305 parms[1].u.pointer.size = sizeof 5312 parms[1].u.pointer.size = sizeof(SHFLSTRING) + (uint16_t)cbString; 5306 5313 5307 5314 parms[2].type = VBOX_HGCM_SVC_PARM_32BIT; 5308 5315 parms[2].u.uint32 = aData.mWritable; 5309 5316 5310 int vrc = mVMMDev->hgcmHostCall ("VBoxSharedFolders", 5311 SHFL_FN_ADD_MAPPING, 5312 SHFL_CPARMS_ADD_MAPPING, &parms[0]); 5313 RTMemFree (pFolderName); 5314 RTMemFree (pMapName); 5315 5316 if (VBOX_FAILURE (vrc)) 5317 return setError (E_FAIL, 5318 tr ("Could not create a shared folder '%ls' " 5319 "mapped to '%ls' (%Rrc)"), 5320 aName, aData.mHostPath.raw(), vrc); 5317 int vrc = mVMMDev->hgcmHostCall("VBoxSharedFolders", 5318 SHFL_FN_ADD_MAPPING, 5319 SHFL_CPARMS_ADD_MAPPING, &parms[0]); 5320 RTMemFree(pFolderName); 5321 RTMemFree(pMapName); 5322 5323 if (RT_FAILURE(vrc)) 5324 return setError(E_FAIL, 5325 tr("Could not create a shared folder '%ls' mapped to '%ls' (%Rrc)"), 5326 aName, aData.mHostPath.raw(), vrc); 5321 5327 5322 5328 return S_OK; … … 5324 5330 5325 5331 /** 5326 * 5327 * 5328 * 5329 * 5330 * 5331 * 5332 * Calls the HGCM service to remove the shared folder definition. 5333 * 5334 * @param aName Shared folder name. 5335 * 5336 * @note Must be called from under AutoVMCaller and when mpVM != NULL! 5337 * @note Doesn't lock anything. 5332 5338 */ 5333 HRESULT Console::removeSharedFolder 5334 { 5335 ComAssertRet 5339 HRESULT Console::removeSharedFolder(CBSTR aName) 5340 { 5341 ComAssertRet(aName && *aName, E_FAIL); 5336 5342 5337 5343 /* sanity checks */ … … 5339 5345 AssertReturn(mVMMDev->isShFlActive(), E_FAIL); 5340 5346 5341 VBOXHGCMSVCPARM 5342 SHFLSTRING 5343 size_t 5344 5345 Log 5346 5347 cbString = (RTUtf16Len (aName) + 1) * sizeof(RTUTF16);5347 VBOXHGCMSVCPARM parms; 5348 SHFLSTRING *pMapName; 5349 size_t cbString; 5350 5351 Log(("Removing shared folder '%ls'\n", aName)); 5352 5353 cbString = (RTUtf16Len(aName) + 1) * sizeof(RTUTF16); 5348 5354 if (cbString >= UINT16_MAX) 5349 return setError (E_INVALIDARG, tr("The name is too long"));5350 pMapName = (SHFLSTRING *) RTMemAllocZ (sizeof(SHFLSTRING) + cbString);5351 Assert 5352 memcpy 5355 return setError(E_INVALIDARG, tr("The name is too long")); 5356 pMapName = (SHFLSTRING *) RTMemAllocZ(sizeof(SHFLSTRING) + cbString); 5357 Assert(pMapName); 5358 memcpy(pMapName->String.ucs2, aName, cbString); 5353 5359 5354 5360 pMapName->u16Size = (uint16_t)cbString; 5355 pMapName->u16Length = (uint16_t)cbString - sizeof 5361 pMapName->u16Length = (uint16_t)cbString - sizeof(RTUTF16); 5356 5362 5357 5363 parms.type = VBOX_HGCM_SVC_PARM_PTR; 5358 5364 parms.u.pointer.addr = pMapName; 5359 parms.u.pointer.size = sizeof 5360 5361 int vrc = mVMMDev->hgcmHostCall 5362 5363 5365 parms.u.pointer.size = sizeof(SHFLSTRING) + (uint16_t)cbString; 5366 5367 int vrc = mVMMDev->hgcmHostCall("VBoxSharedFolders", 5368 SHFL_FN_REMOVE_MAPPING, 5369 1, &parms); 5364 5370 RTMemFree(pMapName); 5365 if ( VBOX_FAILURE(vrc))5366 return setError 5367 tr("Could not remove the shared folder '%ls' (%Rrc)"),5368 5371 if (RT_FAILURE(vrc)) 5372 return setError(E_FAIL, 5373 tr("Could not remove the shared folder '%ls' (%Rrc)"), 5374 aName, vrc); 5369 5375 5370 5376 return S_OK; … … 5372 5378 5373 5379 /** 5374 * 5375 * 5376 * 5377 * 5378 * 5379 * 5380 * 5381 * 5382 * 5383 * 5384 * 5385 * 5386 * 5387 * 5380 * VM state callback function. Called by the VMM 5381 * using its state machine states. 5382 * 5383 * Primarily used to handle VM initiated power off, suspend and state saving, 5384 * but also for doing termination completed work (VMSTATE_TERMINATE). 5385 * 5386 * In general this function is called in the context of the EMT. 5387 * 5388 * @param aVM The VM handle. 5389 * @param aState The new state. 5390 * @param aOldState The old state. 5391 * @param aUser The user argument (pointer to the Console object). 5392 * 5393 * @note Locks the Console object for writing. 5388 5394 */ 5389 5395 DECLCALLBACK(void) Console::vmstateChangeCallback(PVM aVM, … … 5395 5401 aOldState, aState, aVM)); 5396 5402 5397 Console *that = static_cast<Console *> 5403 Console *that = static_cast<Console *>(aUser); 5398 5404 AssertReturnVoid(that); 5399 5405 … … 5551 5557 /* Change the machine state from Starting, Restoring or Paused 5552 5558 * to Running */ 5553 Assert 5554 5555 5556 5557 5558 5559 5560 that->setMachineState 5559 Assert( ( ( that->mMachineState == MachineState_Starting 5560 || that->mMachineState == MachineState_Paused) 5561 && aOldState == VMSTATE_POWERING_ON) 5562 || ( ( that->mMachineState == MachineState_Restoring 5563 || that->mMachineState == MachineState_Paused) 5564 && aOldState == VMSTATE_RESUMING)); 5565 5566 that->setMachineState(MachineState_Running); 5561 5567 } 5562 5568 … … 5590 5596 5591 5597 /* Guru are only for running VMs */ 5592 Assert(Global::IsOnline 5598 Assert(Global::IsOnline(that->mMachineState)); 5593 5599 5594 5600 that->setMachineState(MachineState_Stuck); … … 5604 5610 5605 5611 /** 5606 * 5607 * 5608 * 5609 * 5610 * 5611 * 5612 * 5613 * 5612 * Sends a request to VMM to attach the given host device. 5613 * After this method succeeds, the attached device will appear in the 5614 * mUSBDevices collection. 5615 * 5616 * @param aHostDevice device to attach 5617 * 5618 * @note Synchronously calls EMT. 5619 * @note Must be called from under this object's lock. 5614 5620 */ 5615 HRESULT Console::attachUSBDevice 5621 HRESULT Console::attachUSBDevice(IUSBDevice *aHostDevice, ULONG aMaskedIfs) 5616 5622 { 5617 5623 AssertReturn(aHostDevice, E_FAIL); … … 5624 5630 5625 5631 /* 5626 * 5627 * 5632 * Get the address and the Uuid, and call the pfnCreateProxyDevice roothub 5633 * method in EMT (using usbAttachCallback()). 5628 5634 */ 5629 5635 Bstr BstrAddress; 5630 hrc = aHostDevice->COMGETTER (Address)(BstrAddress.asOutParam());5631 ComAssertComRCRetRC 5632 5633 Utf8Str Address 5636 hrc = aHostDevice->COMGETTER(Address)(BstrAddress.asOutParam()); 5637 ComAssertComRCRetRC(hrc); 5638 5639 Utf8Str Address(BstrAddress); 5634 5640 5635 5641 Bstr id; 5636 hrc = aHostDevice->COMGETTER (Id)(id.asOutParam());5637 ComAssertComRCRetRC 5642 hrc = aHostDevice->COMGETTER(Id)(id.asOutParam()); 5643 ComAssertComRCRetRC(hrc); 5638 5644 Guid uuid(id); 5639 5645 5640 5646 BOOL fRemote = FALSE; 5641 hrc = aHostDevice->COMGETTER (Remote)(&fRemote);5642 ComAssertComRCRetRC 5647 hrc = aHostDevice->COMGETTER(Remote)(&fRemote); 5648 ComAssertComRCRetRC(hrc); 5643 5649 5644 5650 /* protect mpVM */ 5645 AutoVMCaller autoVMCaller 5651 AutoVMCaller autoVMCaller(this); 5646 5652 CheckComRCReturnRC(autoVMCaller.rc()); 5647 5653 … … 5653 5659 5654 5660 /** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */ 5655 int vrc = VMR3ReqCallWait 5656 5661 int vrc = VMR3ReqCallWait(mpVM, VMCPUID_ANY, 5662 (PFNRT) usbAttachCallback, 6, this, aHostDevice, uuid.ptr(), fRemote, Address.raw(), aMaskedIfs); 5657 5663 5658 5664 /* restore the lock */ … … 5661 5667 /* hrc is S_OK here */ 5662 5668 5663 if ( VBOX_FAILURE(vrc))5669 if (RT_FAILURE(vrc)) 5664 5670 { 5665 5671 LogWarningThisFunc(("Failed to create proxy device for '%s' {%RTuuid} (%Rrc)\n", … … 5669 5675 { 5670 5676 case VERR_VUSB_NO_PORTS: 5671 hrc = setError 5672 tr ("Failed to attach the USB device.(No available ports on the USB controller)."));5677 hrc = setError(E_FAIL, 5678 tr("Failed to attach the USB device. (No available ports on the USB controller).")); 5673 5679 break; 5674 5680 case VERR_VUSB_USBFS_PERMISSION: 5675 hrc = setError 5676 tr 5681 hrc = setError(E_FAIL, 5682 tr("Not permitted to open the USB device, check usbfs options")); 5677 5683 break; 5678 5684 default: 5679 hrc = setError (E_FAIL, 5680 tr ("Failed to create a proxy device for the USB device. (Error: %Rrc)"), vrc); 5685 hrc = setError(E_FAIL, 5686 tr("Failed to create a proxy device for the USB device. (Error: %Rrc)"), 5687 vrc); 5681 5688 break; 5682 5689 } … … 5687 5694 5688 5695 /** 5689 * 5690 * 5691 * 5692 * 5693 * 5694 * 5695 * 5696 * USB device attach callback used by AttachUSBDevice(). 5697 * Note that AttachUSBDevice() doesn't return until this callback is executed, 5698 * so we don't use AutoCaller and don't care about reference counters of 5699 * interface pointers passed in. 5700 * 5701 * @thread EMT 5702 * @note Locks the console object for writing. 5696 5703 */ 5697 5704 //static 5698 5705 DECLCALLBACK(int) 5699 Console::usbAttachCallback 5706 Console::usbAttachCallback(Console *that, IUSBDevice *aHostDevice, PCRTUUID aUuid, bool aRemote, const char *aAddress, ULONG aMaskedIfs) 5700 5707 { 5701 5708 LogFlowFuncEnter(); 5702 LogFlowFunc 5709 LogFlowFunc(("that={%p}\n", that)); 5703 5710 5704 5711 AssertReturn(that && aUuid, VERR_INVALID_PARAMETER); … … 5707 5714 if (aRemote) 5708 5715 { 5709 RemoteUSBDevice *pRemoteUSBDevice = static_cast <RemoteUSBDevice *>(aHostDevice);5710 Guid guid 5711 5712 pvRemoteBackend = that->consoleVRDPServer ()->USBBackendRequestPointer (pRemoteUSBDevice->clientId(), &guid);5716 RemoteUSBDevice *pRemoteUSBDevice = static_cast<RemoteUSBDevice *>(aHostDevice); 5717 Guid guid(*aUuid); 5718 5719 pvRemoteBackend = that->consoleVRDPServer()->USBBackendRequestPointer(pRemoteUSBDevice->clientId(), &guid); 5713 5720 if (!pvRemoteBackend) 5714 return VERR_INVALID_PARAMETER; 5721 return VERR_INVALID_PARAMETER; /* The clientId is invalid then. */ 5715 5722 } 5716 5723 … … 5720 5727 Assert(portVersion == 1 || portVersion == 2); 5721 5728 5722 int vrc = PDMR3USBCreateProxyDevice 5723 5724 if ( VBOX_SUCCESS(vrc))5729 int vrc = PDMR3USBCreateProxyDevice(that->mpVM, aUuid, aRemote, aAddress, pvRemoteBackend, 5730 portVersion == 1 ? VUSB_STDVER_11 : VUSB_STDVER_20, aMaskedIfs); 5731 if (RT_SUCCESS(vrc)) 5725 5732 { 5726 5733 /* Create a OUSBDevice and add it to the device list */ 5727 5734 ComObjPtr<OUSBDevice> device; 5728 5735 device.createObject(); 5729 HRESULT hrc = device->init 5730 AssertComRC 5736 HRESULT hrc = device->init(aHostDevice); 5737 AssertComRC(hrc); 5731 5738 5732 5739 AutoWriteLock alock(that); 5733 that->mUSBDevices.push_back 5734 LogFlowFunc 5740 that->mUSBDevices.push_back(device); 5741 LogFlowFunc(("Attached device {%RTuuid}\n", device->id().raw())); 5735 5742 5736 5743 /* notify callbacks */ 5737 that->onUSBDeviceStateChange 5738 } 5739 5740 LogFlowFunc 5744 that->onUSBDeviceStateChange(device, true /* aAttached */, NULL); 5745 } 5746 5747 LogFlowFunc(("vrc=%Rrc\n", vrc)); 5741 5748 LogFlowFuncLeave(); 5742 5749 return vrc; … … 5744 5751 5745 5752 /** 5746 * 5747 * 5748 * 5749 * 5750 * 5751 * 5752 * 5753 * 5753 * Sends a request to VMM to detach the given host device. After this method 5754 * succeeds, the detached device will disappear from the mUSBDevices 5755 * collection. 5756 * 5757 * @param aIt Iterator pointing to the device to detach. 5758 * 5759 * @note Synchronously calls EMT. 5760 * @note Must be called from under this object's lock. 5754 5761 */ 5755 HRESULT Console::detachUSBDevice 5762 HRESULT Console::detachUSBDevice(USBDeviceList::iterator &aIt) 5756 5763 { 5757 5764 AssertReturn(isWriteLockOnCurrentThread(), E_FAIL); … … 5761 5768 5762 5769 /* protect mpVM */ 5763 AutoVMCaller autoVMCaller 5770 AutoVMCaller autoVMCaller(this); 5764 5771 CheckComRCReturnRC(autoVMCaller.rc()); 5765 5772 5766 5773 /* if the device is attached, then there must at least one USB hub. */ 5767 AssertReturn(PDMR3USBHasHub 5774 AssertReturn(PDMR3USBHasHub(mpVM), E_FAIL); 5768 5775 5769 5776 LogFlowThisFunc(("Detaching USB proxy device {%RTuuid}...\n", … … 5774 5781 5775 5782 /** @todo just do everything here and only wrap the PDMR3Usb call. That'll offload some notification stuff from the EMT thread. */ 5776 int vrc = VMR3ReqCallWait 5777 5778 ComAssertRCRet 5783 int vrc = VMR3ReqCallWait(mpVM, VMCPUID_ANY, 5784 (PFNRT) usbDetachCallback, 4, this, &aIt, (*aIt)->id().raw()); 5785 ComAssertRCRet(vrc, E_FAIL); 5779 5786 5780 5787 return S_OK; … … 5782 5789 5783 5790 /** 5784 * 5785 * 5786 * 5787 * 5788 * 5789 * 5790 * 5791 * USB device detach callback used by DetachUSBDevice(). 5792 * Note that DetachUSBDevice() doesn't return until this callback is executed, 5793 * so we don't use AutoCaller and don't care about reference counters of 5794 * interface pointers passed in. 5795 * 5796 * @thread EMT 5797 * @note Locks the console object for writing. 5791 5798 */ 5792 5799 //static 5793 5800 DECLCALLBACK(int) 5794 Console::usbDetachCallback 5801 Console::usbDetachCallback(Console *that, USBDeviceList::iterator *aIt, PCRTUUID aUuid) 5795 5802 { 5796 5803 LogFlowFuncEnter(); 5797 LogFlowFunc 5804 LogFlowFunc(("that={%p}\n", that)); 5798 5805 5799 5806 AssertReturn(that && aUuid, VERR_INVALID_PARAMETER); … … 5806 5813 BOOL fRemote = FALSE; 5807 5814 5808 HRESULT hrc2 = (**aIt)->COMGETTER (Remote)(&fRemote);5809 ComAssertComRC 5815 HRESULT hrc2 = (**aIt)->COMGETTER(Remote)(&fRemote); 5816 ComAssertComRC(hrc2); 5810 5817 5811 5818 if (fRemote) 5812 5819 { 5813 Guid guid 5814 that->consoleVRDPServer ()->USBBackendReleasePointer(&guid);5815 } 5816 5817 int vrc = PDMR3USBDetachDevice 5818 5819 if ( VBOX_SUCCESS(vrc))5820 Guid guid(*aUuid); 5821 that->consoleVRDPServer()->USBBackendReleasePointer(&guid); 5822 } 5823 5824 int vrc = PDMR3USBDetachDevice(that->mpVM, aUuid); 5825 5826 if (RT_SUCCESS(vrc)) 5820 5827 { 5821 5828 AutoWriteLock alock(that); 5822 5829 5823 5830 /* Remove the device from the collection */ 5824 that->mUSBDevices.erase 5825 LogFlowFunc 5831 that->mUSBDevices.erase(*aIt); 5832 LogFlowFunc(("Detached device {%RTuuid}\n", device->id().raw())); 5826 5833 5827 5834 /* notify callbacks */ 5828 that->onUSBDeviceStateChange 5829 } 5830 5831 LogFlowFunc 5835 that->onUSBDeviceStateChange(device, false /* aAttached */, NULL); 5836 } 5837 5838 LogFlowFunc(("vrc=%Rrc\n", vrc)); 5832 5839 LogFlowFuncLeave(); 5833 5840 return vrc; … … 5838 5845 5839 5846 /** 5840 * 5841 * 5842 * 5843 * 5844 * 5845 * 5846 * 5847 * 5847 * Helper function to handle host interface device creation and attachment. 5848 * 5849 * @param networkAdapter the network adapter which attachment should be reset 5850 * @return COM status code 5851 * 5852 * @note The caller must lock this object for writing. 5853 * 5854 * @todo Move this back into the driver! 5848 5855 */ 5849 5856 HRESULT Console::attachToTapInterface(INetworkAdapter *networkAdapter) … … 5872 5879 int rcVBox = RTFileOpen(&maTapFD[slot], "/dev/net/tun", 5873 5880 RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_INHERIT); 5874 if ( VBOX_SUCCESS(rcVBox))5881 if (RT_SUCCESS(rcVBox)) 5875 5882 { 5876 5883 /* … … 5883 5890 rc = networkAdapter->COMGETTER(HostInterface)(tapDeviceName.asOutParam()); 5884 5891 if (FAILED(rc)) 5885 tapDeviceName.setNull(); 5892 tapDeviceName.setNull(); /* Is this necessary? */ 5886 5893 if (tapDeviceName.isEmpty()) 5887 5894 { 5888 5895 LogRel(("No TAP device name was supplied.\n")); 5889 rc = setError(E_FAIL, tr 5896 rc = setError(E_FAIL, tr("No TAP device name was supplied for the host networking interface")); 5890 5897 } 5891 5898 … … 5903 5910 { 5904 5911 LogRel(("Failed to open the host network interface %ls\n", tapDeviceName.raw())); 5905 rc = setError(E_FAIL, tr ("Failed to open the host network interface %ls"), 5906 tapDeviceName.raw()); 5912 rc = setError(E_FAIL, 5913 tr("Failed to open the host network interface %ls"), 5914 tapDeviceName.raw()); 5907 5915 } 5908 5916 } … … 5929 5937 LogRel(("Configuration error: Failed to configure /dev/net/tun non blocking. Error: %s\n", strerror(iErr))); 5930 5938 rcVBox = VERR_HOSTIF_BLOCKING; 5931 rc = setError(E_FAIL, tr ("could not set up the host networking device for non blocking access: %s"), 5932 strerror(errno)); 5939 rc = setError(E_FAIL, 5940 tr("could not set up the host networking device for non blocking access: %s"), 5941 strerror(errno)); 5933 5942 } 5934 5943 } … … 5944 5953 break; 5945 5954 default: 5946 rc = setError(E_FAIL, tr ("Could not set up the host networking device: %Rrc"), rcVBox); 5955 rc = setError(E_FAIL, 5956 tr("Could not set up the host networking device: %Rrc"), 5957 rcVBox); 5947 5958 break; 5948 5959 } … … 5957 5968 rc = networkAdapter->COMGETTER(HostInterface)(tapDeviceName.asOutParam()); 5958 5969 if (FAILED(rc)) 5959 tapDeviceName.setNull(); 5970 tapDeviceName.setNull(); /* Is this necessary? */ 5960 5971 if (tapDeviceName.isEmpty()) 5961 5972 { 5962 5973 LogRel(("No TAP device name was supplied.\n")); 5963 rc = setError(E_FAIL, tr 5974 rc = setError(E_FAIL, tr("No TAP device name was supplied for the host networking interface")); 5964 5975 } 5965 5976 char szTapdev[1024] = "/dev/"; … … 5984 5995 break; 5985 5996 default: 5986 rc = setError(E_FAIL, tr ("Failed to open the host network interface %ls"), 5987 tapDeviceName.raw()); 5997 rc = setError(E_FAIL, 5998 tr("Failed to open the host network interface %ls"), 5999 tapDeviceName.raw()); 5988 6000 break; 5989 6001 } … … 5993 6005 # endif 5994 6006 /* in case of failure, cleanup. */ 5995 if ( VBOX_FAILURE(rcVBox) && SUCCEEDED(rc))6007 if (RT_FAILURE(rcVBox) && SUCCEEDED(rc)) 5996 6008 { 5997 6009 LogRel(("General failure attaching to host interface\n")); 5998 rc = setError(E_FAIL, tr ("General failure attaching to host interface")); 6010 rc = setError(E_FAIL, 6011 tr("General failure attaching to host interface")); 5999 6012 } 6000 6013 LogFlowThisFunc(("rc=%d\n", rc)); … … 6004 6017 6005 6018 /** 6006 * 6007 * 6008 * 6009 * 6010 * 6011 * 6012 * 6013 * 6019 * Helper function to handle detachment from a host interface 6020 * 6021 * @param networkAdapter the network adapter which attachment should be reset 6022 * @return COM status code 6023 * 6024 * @note The caller must lock this object for writing. 6025 * 6026 * @todo Move this back into the driver! 6014 6027 */ 6015 6028 HRESULT Console::detachFromTapInterface(INetworkAdapter *networkAdapter) … … 6043 6056 { 6044 6057 /* If the name is empty, this is a dynamic TAP device, so close it now, 6045 so that the termination script can remove the interface. 6058 so that the termination script can remove the interface. Otherwise we still 6046 6059 need the FD to pass to the termination script. */ 6047 6060 isStatic = false; … … 6068 6081 6069 6082 /** 6070 * 6071 * 6072 * 6083 * Called at power down to terminate host interface networking. 6084 * 6085 * @note The caller must lock this object for writing. 6073 6086 */ 6074 6087 HRESULT Console::powerDownHostInterfaces() … … 6087 6100 ComPtr<INetworkAdapter> networkAdapter; 6088 6101 rc = mMachine->GetNetworkAdapter(slot, networkAdapter.asOutParam()); 6089 CheckComRCBreakRC 6102 CheckComRCBreakRC(rc); 6090 6103 6091 6104 BOOL enabled = FALSE; 6092 networkAdapter->COMGETTER(Enabled) 6105 networkAdapter->COMGETTER(Enabled)(&enabled); 6093 6106 if (!enabled) 6094 6107 continue; … … 6111 6124 6112 6125 /** 6113 * 6114 * 6115 * 6116 * 6117 * 6118 * 6126 * Process callback handler for VMR3Load and VMR3Save. 6127 * 6128 * @param pVM The VM handle. 6129 * @param uPercent Completetion precentage (0-100). 6130 * @param pvUser Pointer to the VMProgressTask structure. 6131 * @return VINF_SUCCESS. 6119 6132 */ 6120 6133 /*static*/ 6121 6134 DECLCALLBACK(int) Console::stateProgressCallback(PVM pVM, unsigned uPercent, void *pvUser) 6122 6135 { 6123 VMProgressTask *task = static_cast<VMProgressTask *> 6136 VMProgressTask *task = static_cast<VMProgressTask *>(pvUser); 6124 6137 AssertReturn(task, VERR_INVALID_PARAMETER); 6125 6138 … … 6146 6159 * safe. 6147 6160 */ 6148 /* static */ DECLCALLBACK 6149 Console::setVMErrorCallback 6150 6151 { 6152 VMProgressTask *task = static_cast <VMProgressTask *>(pvUser);6153 AssertReturnVoid 6161 /* static */ DECLCALLBACK(void) 6162 Console::setVMErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL, 6163 const char *pszFormat, va_list args) 6164 { 6165 VMProgressTask *task = static_cast<VMProgressTask *>(pvUser); 6166 AssertReturnVoid(task); 6154 6167 6155 6168 /* we ignore RT_SRC_POS_DECL arguments to avoid confusion of end-users */ 6156 6169 va_list va2; 6157 va_copy 6170 va_copy(va2, args); /* Have to make a copy here or GCC will break. */ 6158 6171 6159 6172 /* append to the existing error message if any */ 6160 6173 if (task->mErrorMsg.length()) 6161 task->mErrorMsg = Utf8StrFmt 6162 6174 task->mErrorMsg = Utf8StrFmt("%s.\n%N (%Rrc)", task->mErrorMsg.raw(), 6175 pszFormat, &va2, rc, rc); 6163 6176 else 6164 task->mErrorMsg = Utf8StrFmt 6165 6177 task->mErrorMsg = Utf8StrFmt("%N (%Rrc)", 6178 pszFormat, &va2, rc, rc); 6166 6179 6167 6180 va_end (va2); … … 6181 6194 */ 6182 6195 /* static */ DECLCALLBACK(void) 6183 Console::setVMRuntimeErrorCallback 6184 6185 6196 Console::setVMRuntimeErrorCallback(PVM pVM, void *pvUser, uint32_t fFlags, 6197 const char *pszErrorId, 6198 const char *pszFormat, va_list va) 6186 6199 { 6187 6200 bool const fFatal = !!(fFlags & VMSETRTERR_FLAGS_FATAL); 6188 6201 LogFlowFuncEnter(); 6189 6202 6190 Console *that = static_cast <Console *> (pvUser); 6191 AssertReturnVoid (that); 6192 6193 Utf8Str message = Utf8StrFmtVA (pszFormat, va); 6194 6195 LogRel (("Console: VM runtime error: fatal=%RTbool, " 6196 "errorID=%s message=\"%s\"\n", 6203 Console *that = static_cast<Console *>(pvUser); 6204 AssertReturnVoid(that); 6205 6206 Utf8Str message = Utf8StrFmtVA(pszFormat, va); 6207 6208 LogRel(("Console: VM runtime error: fatal=%RTbool, errorID=%s message=\"%s\"\n", 6197 6209 fFatal, pszErrorId, message.raw())); 6198 6210 6199 that->onRuntimeError (BOOL (fFatal), Bstr (pszErrorId), Bstr(message));6211 that->onRuntimeError(BOOL(fFatal), Bstr(pszErrorId), Bstr(message)); 6200 6212 6201 6213 LogFlowFuncLeave(); … … 6203 6215 6204 6216 /** 6205 * 6206 * 6207 * 6208 * 6209 * 6210 * 6217 * Captures USB devices that match filters of the VM. 6218 * Called at VM startup. 6219 * 6220 * @param pVM The VM handle. 6221 * 6222 * @note The caller must lock this object for writing. 6211 6223 */ 6212 HRESULT Console::captureUSBDevices 6224 HRESULT Console::captureUSBDevices(PVM pVM) 6213 6225 { 6214 6226 LogFlowThisFunc(("\n")); 6215 6227 6216 6228 /* sanity check */ 6217 ComAssertRet 6229 ComAssertRet(isWriteLockOnCurrentThread(), E_FAIL); 6218 6230 6219 6231 /* If the machine has an USB controller, ask the USB proxy service to 6220 6232 * capture devices */ 6221 6233 PPDMIBASE pBase; 6222 int vrc = PDMR3QueryLun 6223 if ( VBOX_SUCCESS(vrc))6234 int vrc = PDMR3QueryLun(pVM, "usb-ohci", 0, 0, &pBase); 6235 if (RT_SUCCESS(vrc)) 6224 6236 { 6225 6237 /* leave the lock before calling Host in VBoxSVC since Host may call … … 6230 6242 6231 6243 HRESULT hrc = mControl->AutoCaptureUSBDevices(); 6232 ComAssertComRCRetRC 6244 ComAssertComRCRetRC(hrc); 6233 6245 } 6234 6246 else if ( vrc == VERR_PDM_DEVICE_NOT_FOUND … … 6236 6248 vrc = VINF_SUCCESS; 6237 6249 else 6238 AssertRC 6239 6240 return VBOX_SUCCESS(vrc) ? S_OK : E_FAIL;6250 AssertRC(vrc); 6251 6252 return RT_SUCCESS(vrc) ? S_OK : E_FAIL; 6241 6253 } 6242 6254 6243 6255 6244 6256 /** 6245 * 6246 * 6247 * 6248 * 6257 * Detach all USB device which are attached to the VM for the 6258 * purpose of clean up and such like. 6259 * 6260 * @note The caller must lock this object for writing. 6249 6261 */ 6250 void Console::detachAllUSBDevices 6262 void Console::detachAllUSBDevices(bool aDone) 6251 6263 { 6252 6264 LogFlowThisFunc(("aDone=%RTbool\n", aDone)); 6253 6265 6254 6266 /* sanity check */ 6255 AssertReturnVoid 6267 AssertReturnVoid(isWriteLockOnCurrentThread()); 6256 6268 6257 6269 mUSBDevices.clear(); … … 6263 6275 alock.leave(); 6264 6276 6265 mControl->DetachAllUSBDevices 6277 mControl->DetachAllUSBDevices(aDone); 6266 6278 } 6267 6279 6268 6280 /** 6269 * 6281 * @note Locks this object for writing. 6270 6282 */ 6271 void Console::processRemoteUSBDevices 6283 void Console::processRemoteUSBDevices(uint32_t u32ClientId, VRDPUSBDEVICEDESC *pDevList, uint32_t cbDevList) 6272 6284 { 6273 6285 LogFlowThisFuncEnter(); … … 6278 6290 { 6279 6291 /* Console has been already uninitialized, deny request */ 6280 AssertMsgFailed (("Temporary assertion to prove that it happens, " 6281 "please report to dmik\n")); 6292 AssertMsgFailed(("Console is already uninitialized\n")); 6282 6293 LogFlowThisFunc(("Console is already uninitialized\n")); 6283 6294 LogFlowThisFuncLeave(); … … 6293 6304 while (it != mRemoteUSBDevices.end()) 6294 6305 { 6295 (*it)->dirty 6306 (*it)->dirty(true); 6296 6307 ++ it; 6297 6308 } … … 6317 6328 while (it != mRemoteUSBDevices.end()) 6318 6329 { 6319 if ((*it)->devId 6320 && (*it)->clientId 6330 if ((*it)->devId() == e->id 6331 && (*it)->clientId() == u32ClientId) 6321 6332 { 6322 6333 /* The device is already in the list. */ 6323 (*it)->dirty 6334 (*it)->dirty(false); 6324 6335 fNewDevice = false; 6325 6336 break; … … 6332 6343 { 6333 6344 LogRel(("Remote USB: ++++ Vendor %04X. Product %04X. Name = [%s].\n", 6334 e->idVendor, e->idProduct, e->oProduct? (char *)e + e->oProduct: "" 6335 )); 6345 e->idVendor, e->idProduct, e->oProduct? (char *)e + e->oProduct: "")); 6336 6346 6337 6347 /* Create the device object and add the new device to list. */ 6338 6348 ComObjPtr<RemoteUSBDevice> device; 6339 6349 device.createObject(); 6340 device->init 6341 6342 mRemoteUSBDevices.push_back 6350 device->init(u32ClientId, e); 6351 6352 mRemoteUSBDevices.push_back(device); 6343 6353 6344 6354 /* Check if the device is ok for current USB filters. */ … … 6348 6358 HRESULT hrc = mControl->RunUSBDeviceFilters(device, &fMatched, &fMaskedIfs); 6349 6359 6350 AssertComRC 6360 AssertComRC(hrc); 6351 6361 6352 6362 LogFlowThisFunc(("USB filters return %d %#x\n", fMatched, fMaskedIfs)); … … 6354 6364 if (fMatched) 6355 6365 { 6356 hrc = onUSBDeviceAttach 6366 hrc = onUSBDeviceAttach(device, NULL, fMaskedIfs); 6357 6367 6358 6368 /// @todo (r=dmik) warning reporting subsystem … … 6361 6371 { 6362 6372 LogFlowThisFunc(("Device attached\n")); 6363 device->captured 6373 device->captured(true); 6364 6374 } 6365 6375 } … … 6388 6398 while (it != mRemoteUSBDevices.end()) 6389 6399 { 6390 if ((*it)->dirty 6400 if ((*it)->dirty()) 6391 6401 { 6392 6402 device = *it; … … 6403 6413 6404 6414 USHORT vendorId = 0; 6405 device->COMGETTER(VendorId) 6415 device->COMGETTER(VendorId)(&vendorId); 6406 6416 6407 6417 USHORT productId = 0; 6408 device->COMGETTER(ProductId) 6418 device->COMGETTER(ProductId)(&productId); 6409 6419 6410 6420 Bstr product; 6411 device->COMGETTER(Product) 6421 device->COMGETTER(Product)(product.asOutParam()); 6412 6422 6413 6423 LogRel(("Remote USB: ---- Vendor %04X. Product %04X. Name = [%ls].\n", 6414 vendorId, productId, product.raw () 6415 )); 6424 vendorId, productId, product.raw())); 6416 6425 6417 6426 /* Detach the device from VM. */ 6418 if (device->captured 6427 if (device->captured()) 6419 6428 { 6420 6429 Bstr uuid; 6421 device->COMGETTER (Id)(uuid.asOutParam());6422 onUSBDeviceDetach 6430 device->COMGETTER(Id)(uuid.asOutParam()); 6431 onUSBDeviceDetach(uuid, NULL); 6423 6432 } 6424 6433 6425 6434 /* And remove it from the list. */ 6426 mRemoteUSBDevices.erase 6435 mRemoteUSBDevices.erase(it); 6427 6436 } 6428 6437 … … 6431 6440 6432 6441 /** 6433 * 6434 * 6435 * 6436 * 6437 * 6438 * 6439 * 6440 * 6442 * Thread function which starts the VM (also from saved state) and 6443 * track progress. 6444 * 6445 * @param Thread The thread id. 6446 * @param pvUser Pointer to a VMPowerUpTask structure. 6447 * @return VINF_SUCCESS (ignored). 6448 * 6449 * @note Locks the Console object for writing. 6441 6450 */ 6442 6451 /*static*/ 6443 DECLCALLBACK (int) Console::powerUpThread(RTTHREAD Thread, void *pvUser)6452 DECLCALLBACK(int) Console::powerUpThread(RTTHREAD Thread, void *pvUser) 6444 6453 { 6445 6454 LogFlowFuncEnter(); 6446 6455 6447 std::auto_ptr <VMPowerUpTask> task (static_cast <VMPowerUpTask *>(pvUser));6456 std::auto_ptr<VMPowerUpTask> task(static_cast<VMPowerUpTask *>(pvUser)); 6448 6457 AssertReturn(task.get(), VERR_INVALID_PARAMETER); 6449 6458 … … 6454 6463 { 6455 6464 /* initialize COM */ 6456 HRESULT hrc = CoInitializeEx 6457 6458 6459 LogFlowFunc 6465 HRESULT hrc = CoInitializeEx(NULL, 6466 COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE | 6467 COINIT_SPEED_OVER_MEMORY); 6468 LogFlowFunc(("CoInitializeEx()=%08X\n", hrc)); 6460 6469 } 6461 6470 #endif … … 6479 6488 6480 6489 /* sanity */ 6481 Assert 6490 Assert(console->mpVM == NULL); 6482 6491 6483 6492 try … … 6489 6498 it != task->hardDiskProgresses.end(); ++ it) 6490 6499 { 6491 HRESULT rc2 = (*it)->WaitForCompletion 6492 AssertComRC 6500 HRESULT rc2 = (*it)->WaitForCompletion(-1); 6501 AssertComRC(rc2); 6493 6502 } 6494 6503 … … 6497 6506 * by SessionMachine::setMachineState() when the VM is powered down. */ 6498 6507 rc = console->mControl->LockMedia(); 6499 CheckComRCThrowRC 6508 CheckComRCThrowRC(rc); 6500 6509 6501 6510 #ifdef VBOX_WITH_VRDP … … 6505 6514 */ 6506 6515 ConsoleVRDPServer *server = console->consoleVRDPServer(); 6507 Assert 6508 6509 / // @todo (dmik)6510 // does VRDP server call Console from the other thread?6511 // Not sure, so leave the lock just in case6516 Assert(server); 6517 6518 /* Does VRDP server call Console from the other thread? 6519 * Not sure (and can change), so leave the lock just in case. 6520 */ 6512 6521 alock.leave(); 6513 6522 vrc = server->Launch(); … … 6518 6527 Utf8Str errMsg; 6519 6528 ULONG port = 0; 6520 console->mVRDPServer->COMGETTER(Port) 6521 errMsg = Utf8StrFmt (tr("VRDP server port %d is already in use"),6522 6523 LogRel 6524 6525 } 6526 else if (RT_FAILURE 6529 console->mVRDPServer->COMGETTER(Port)(&port); 6530 errMsg = Utf8StrFmt(tr("VRDP server port %d is already in use"), 6531 port); 6532 LogRel(("Warning: failed to launch VRDP server (%Rrc): '%s'\n", 6533 vrc, errMsg.raw())); 6534 } 6535 else if (RT_FAILURE(vrc)) 6527 6536 { 6528 6537 Utf8Str errMsg; … … 6531 6540 case VERR_FILE_NOT_FOUND: 6532 6541 { 6533 errMsg = Utf8StrFmt (tr("Could not load the VRDP library"));6542 errMsg = Utf8StrFmt(tr("Could not load the VRDP library")); 6534 6543 break; 6535 6544 } 6536 6545 default: 6537 errMsg = Utf8StrFmt (tr("Failed to launch VRDP server (%Rrc)"),6538 6546 errMsg = Utf8StrFmt(tr("Failed to launch VRDP server (%Rrc)"), 6547 vrc); 6539 6548 } 6540 LogRel 6549 LogRel(("Failed to launch VRDP server (%Rrc), error message: '%s'\n", 6541 6550 vrc, errMsg.raw())); 6542 6551 throw setError(E_FAIL, errMsg.c_str()); … … 6554 6563 PVM pVM; 6555 6564 /* 6556 * 6557 * 6565 * leave the lock since EMT will call Console. It's safe because 6566 * mMachineState is either Starting or Restoring state here. 6558 6567 */ 6559 6568 alock.leave(); 6560 6569 6561 vrc = VMR3Create 6562 task->mConfigConstructor, static_cast <Console *>(console),6563 6570 vrc = VMR3Create(cCpus, task->mSetVMErrorCallback, task.get(), 6571 task->mConfigConstructor, static_cast<Console *>(console), 6572 &pVM); 6564 6573 6565 6574 alock.enter(); … … 6567 6576 #ifdef VBOX_WITH_VRDP 6568 6577 /* Enable client connections to the server. */ 6569 console->consoleVRDPServer()->EnableConnections 6578 console->consoleVRDPServer()->EnableConnections(); 6570 6579 #endif /* VBOX_WITH_VRDP */ 6571 6580 6572 if ( VBOX_SUCCESS(vrc))6581 if (RT_SUCCESS(vrc)) 6573 6582 { 6574 6583 do … … 6584 6593 AssertRCBreak(vrc); 6585 6594 6586 vrc = static_cast 6587 AssertRC 6588 if ( VBOX_FAILURE(vrc))6595 vrc = static_cast<Console *>(console)->getDisplay()->registerSSM(pVM); 6596 AssertRC(vrc); 6597 if (RT_FAILURE(vrc)) 6589 6598 break; 6590 6599 … … 6603 6612 if (console->getVMMDev()->isShFlActive()) 6604 6613 { 6605 /// @todo (dmik) 6606 // does the code below call Console from the other thread? 6607 // Not sure, so leave the lock just in case 6614 /* Does the code below call Console from the other thread? 6615 * Not sure, so leave the lock just in case. */ 6608 6616 alock.leave(); 6609 6617 … … 6613 6621 ++ it) 6614 6622 { 6615 rc = console->createSharedFolder 6616 CheckComRCBreakRC 6623 rc = console->createSharedFolder((*it).first, (*it).second); 6624 CheckComRCBreakRC(rc); 6617 6625 } 6618 6626 … … 6620 6628 alock.enter(); 6621 6629 6622 CheckComRCBreakRC 6630 CheckComRCBreakRC(rc); 6623 6631 } 6624 6632 … … 6626 6634 * Capture USB devices. 6627 6635 */ 6628 rc = console->captureUSBDevices 6629 CheckComRCBreakRC 6636 rc = console->captureUSBDevices(pVM); 6637 CheckComRCBreakRC(rc); 6630 6638 6631 6639 /* leave the lock before a lengthy operation */ … … 6635 6643 if (task->mSavedStateFile.length()) 6636 6644 { 6637 LogFlowFunc 6638 6645 LogFlowFunc(("Restoring saved state from '%s'...\n", 6646 task->mSavedStateFile.raw())); 6639 6647 6640 6648 vrc = VMR3Load(pVM, … … 6643 6651 static_cast<VMProgressTask*>(task.get())); 6644 6652 6645 if ( VBOX_SUCCESS(vrc))6653 if (RT_SUCCESS(vrc)) 6646 6654 { 6647 6655 if (task->mStartPaused) 6648 6656 /* done */ 6649 console->setMachineState 6657 console->setMachineState(MachineState_Paused); 6650 6658 else 6651 6659 { 6652 6660 /* Start/Resume the VM execution */ 6653 vrc = VMR3Resume 6654 AssertRC 6661 vrc = VMR3Resume(pVM); 6662 AssertRC(vrc); 6655 6663 } 6656 6664 } 6657 6665 6658 6666 /* Power off in case we failed loading or resuming the VM */ 6659 if ( VBOX_FAILURE(vrc))6667 if (RT_FAILURE(vrc)) 6660 6668 { 6661 int vrc2 = VMR3PowerOff 6662 AssertRC 6669 int vrc2 = VMR3PowerOff(pVM); 6670 AssertRC(vrc2); 6663 6671 } 6664 6672 } 6665 6673 else if (task->mStartPaused) 6666 6674 /* done */ 6667 console->setMachineState 6675 console->setMachineState(MachineState_Paused); 6668 6676 else 6669 6677 { 6670 6678 /* Power on the VM (i.e. start executing) */ 6671 6679 vrc = VMR3PowerOn(pVM); 6672 AssertRC 6680 AssertRC(vrc); 6673 6681 } 6674 6682 … … 6679 6687 6680 6688 /* On failure, destroy the VM */ 6681 if (FAILED (rc) || VBOX_FAILURE(vrc))6689 if (FAILED(rc) || RT_FAILURE(vrc)) 6682 6690 { 6683 6691 /* preserve existing error info */ … … 6687 6695 * cleanup (VRDP, USB devices) */ 6688 6696 HRESULT rc2 = console->powerDown(); 6689 AssertComRC 6697 AssertComRC(rc2); 6690 6698 } 6691 6699 else … … 6710 6718 } 6711 6719 6712 if (SUCCEEDED(rc) && VBOX_FAILURE(vrc))6720 if (SUCCEEDED(rc) && RT_FAILURE(vrc)) 6713 6721 { 6714 6722 /* If VMR3Create() or one of the other calls in this function fail, … … 6724 6732 * appropriate error message themselves. 6725 6733 */ 6726 AssertMsgFailed (("Missing error message during powerup for " 6727 "status code %Rrc\n", vrc)); 6728 task->mErrorMsg = Utf8StrFmt ( 6729 tr ("Failed to start VM execution (%Rrc)"), vrc); 6734 AssertMsgFailed(("Missing error message during powerup for status code %Rrc\n", vrc)); 6735 task->mErrorMsg = Utf8StrFmt(tr("Failed to start VM execution (%Rrc)"), 6736 vrc); 6730 6737 } 6731 6738 … … 6753 6760 ErrorInfoKeeper eik; 6754 6761 6755 Assert 6756 vmstateChangeCallback 6757 6762 Assert(console->mpVM == NULL); 6763 vmstateChangeCallback(NULL, VMSTATE_TERMINATED, VMSTATE_CREATING, 6764 console); 6758 6765 } 6759 6766 … … 6769 6776 { 6770 6777 /* Notify the progress object of the success */ 6771 task->mProgress->notifyComplete 6778 task->mProgress->notifyComplete(S_OK); 6772 6779 } 6773 6780 else 6774 6781 { 6775 6782 /* The progress object will fetch the current error info */ 6776 task->mProgress->notifyComplete 6777 6778 LogRel 6783 task->mProgress->notifyComplete(rc); 6784 6785 LogRel(("Power up failed (vrc=%Rrc, rc=%Rhrc (%#08X))\n", vrc, rc, rc)); 6779 6786 } 6780 6787 … … 6791 6798 6792 6799 /** 6793 * 6794 * 6795 * 6796 * 6797 * 6798 * 6799 * 6800 * 6800 * Reconfigures a VDI. 6801 * 6802 * @param pVM The VM handle. 6803 * @param lInstance The instance of the controller. 6804 * @param enmController The type of the controller. 6805 * @param hda The harddisk attachment. 6806 * @param phrc Where to store com error - only valid if we return VERR_GENERAL_FAILURE. 6807 * @return VBox status code. 6801 6808 */ 6802 6809 static DECLCALLBACK(int) reconfigureHardDisks(PVM pVM, ULONG lInstance, … … 6805 6812 HRESULT *phrc) 6806 6813 { 6807 LogFlowFunc 6814 LogFlowFunc(("pVM=%p hda=%p phrc=%p\n", pVM, hda, phrc)); 6808 6815 6809 6816 int rc; … … 6811 6818 Bstr bstr; 6812 6819 *phrc = S_OK; 6813 #define RC_CHECK() do { if (VBOX_FAILURE(rc)) { AssertMsgFailed(("rc=%Rrc\n", rc)); return rc; } } while (0)6820 #define RC_CHECK() do { if (RT_FAILURE(rc)) { AssertMsgFailed(("rc=%Rrc\n", rc)); return rc; } } while (0) 6814 6821 #define H() do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%Rhrc (%#x)\n", hrc, hrc)); *phrc = hrc; return VERR_GENERAL_FAILURE; } } while (0) 6815 6822 … … 6947 6954 */ 6948 6955 hrc = hardDisk->COMGETTER(Location)(bstr.asOutParam()); H(); 6949 LogFlowFunc 6956 LogFlowFunc(("LUN#%d: leaf location '%ls'\n", iLUN, bstr.raw())); 6950 6957 rc = CFGMR3InsertString(pCfg, "Path", Utf8Str(bstr).c_str()); RC_CHECK(); 6951 6958 hrc = hardDisk->COMGETTER(Format)(bstr.asOutParam()); H(); 6952 LogFlowFunc 6959 LogFlowFunc(("LUN#%d: leaf format '%ls'\n", iLUN, bstr.raw())); 6953 6960 rc = CFGMR3InsertString(pCfg, "Format", Utf8Str(bstr).c_str()); RC_CHECK(); 6954 6961 … … 6957 6964 SafeArray<BSTR> names; 6958 6965 SafeArray<BSTR> values; 6959 hrc = hardDisk->GetProperties 6960 ComSafeArrayAsOutParam(names),6961 ComSafeArrayAsOutParam (values));H();6966 hrc = hardDisk->GetProperties(NULL, 6967 ComSafeArrayAsOutParam(names), 6968 ComSafeArrayAsOutParam(values)); H(); 6962 6969 6963 6970 if (names.size() != 0) 6964 6971 { 6965 6972 PCFGMNODE pVDC; 6966 rc = CFGMR3InsertNode (pCfg, "VDConfig", &pVDC);RC_CHECK();6973 rc = CFGMR3InsertNode(pCfg, "VDConfig", &pVDC); RC_CHECK(); 6967 6974 for (size_t i = 0; i < names.size(); ++ i) 6968 6975 { 6969 if (values 6976 if (values[i]) 6970 6977 { 6971 6978 Utf8Str name = names[i]; … … 6998 7005 SafeArray<BSTR> names; 6999 7006 SafeArray<BSTR> values; 7000 hrc = hardDisk->GetProperties 7001 ComSafeArrayAsOutParam(names),7002 ComSafeArrayAsOutParam (values));H();7007 hrc = hardDisk->GetProperties(NULL, 7008 ComSafeArrayAsOutParam(names), 7009 ComSafeArrayAsOutParam(values)); H(); 7003 7010 7004 7011 if (names.size() != 0) 7005 7012 { 7006 7013 PCFGMNODE pVDC; 7007 rc = CFGMR3InsertNode (pCur, "VDConfig", &pVDC);RC_CHECK();7014 rc = CFGMR3InsertNode(pCur, "VDConfig", &pVDC); RC_CHECK(); 7008 7015 for (size_t i = 0; i < names.size(); ++ i) 7009 7016 { 7010 if (values 7017 if (values[i]) 7011 7018 { 7012 Utf8Str name = names 7013 Utf8Str value = values 7014 rc = CFGMR3InsertString 7019 Utf8Str name = names[i]; 7020 Utf8Str value = values[i]; 7021 rc = CFGMR3InsertString(pVDC, name.c_str(), value.c_str()); 7015 7022 if ( !(name.compare("HostIPStack")) 7016 7023 && !(value.compare("0"))) … … 7025 7032 if (!fHostIP) 7026 7033 { 7027 rc = CFGMR3InsertInteger (pCfg, "HostIPStack", 0);RC_CHECK();7034 rc = CFGMR3InsertInteger(pCfg, "HostIPStack", 0); RC_CHECK(); 7028 7035 } 7029 7036 … … 7041 7048 rc = PDMR3DeviceAttach(pVM, pcszDevice, 0, iLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/); RC_CHECK(); 7042 7049 7043 LogFlowFunc 7050 LogFlowFunc(("Returns success\n")); 7044 7051 return rc; 7045 7052 } … … 7077 7084 try 7078 7085 { 7079 /* 7080 * 7081 * 7082 * 7086 /* STEP 1 + 2: 7087 * request creating the diff images on the server and create the snapshot object 7088 * (this will set the machine state to Saving on the server to block 7089 * others from accessing this machine) 7083 7090 */ 7084 7091 rc = pTask->mConsole->mControl->BeginTakingSnapshot(that, … … 7093 7100 7094 7101 /* 7095 * 7096 * 7102 * state file is non-null only when the VM is paused 7103 * (i.e. creating a snapshot online) 7097 7104 */ 7098 7105 ComAssertThrow( (!pTask->bstrSavedStateFile.isNull() && pTask->fTakingSnapshotOnline) … … 7118 7125 Console::stateProgressCallback, 7119 7126 (void*)pTask); 7120 if ( VBOX_FAILURE(vrc))7127 if (RT_FAILURE(vrc)) 7121 7128 throw setError(E_FAIL, 7122 7129 tr("Failed to save the machine state to '%s' (%Rrc)"), 7123 strSavedStateFile.c_str(), 7124 vrc); 7130 strSavedStateFile.c_str(), vrc); 7125 7131 7126 7132 alock.enter(); … … 7155 7161 7156 7162 rc = that->mMachine->GetStorageControllerByName(controllerName, controller.asOutParam()); 7157 if (FAILED 7163 if (FAILED(rc)) throw rc; 7158 7164 7159 7165 rc = controller->COMGETTER(ControllerType)(&enmController); … … 7161 7167 7162 7168 /* 7163 *don't leave the lock since reconfigureHardDisks isn't going7164 *to access Console.7165 */7169 * don't leave the lock since reconfigureHardDisks isn't going 7170 * to access Console. 7171 */ 7166 7172 int vrc = VMR3ReqCallWait(that->mpVM, 7167 7173 VMCPUID_ANY, … … 7183 7189 7184 7190 /* 7185 * 7186 * 7187 * 7191 * finalize the requested snapshot object. 7192 * This will reset the machine state to the state it had right 7193 * before calling mControl->BeginTakingSnapshot(). 7188 7194 */ 7189 7195 rc = that->mControl->EndTakingSnapshot(TRUE); // success … … 7218 7224 7219 7225 /** 7220 * 7221 * 7222 * 7223 * 7224 * 7225 * 7226 * 7226 * Thread for executing the saved state operation. 7227 * 7228 * @param Thread The thread handle. 7229 * @param pvUser Pointer to a VMSaveTask structure. 7230 * @return VINF_SUCCESS (ignored). 7231 * 7232 * @note Locks the Console object for writing. 7227 7233 */ 7228 7234 /*static*/ 7229 DECLCALLBACK 7235 DECLCALLBACK(int) Console::saveStateThread(RTTHREAD Thread, void *pvUser) 7230 7236 { 7231 7237 LogFlowFuncEnter(); 7232 7238 7233 std::auto_ptr<VMSaveTask> task 7239 std::auto_ptr<VMSaveTask> task(static_cast<VMSaveTask*>(pvUser)); 7234 7240 AssertReturn(task.get(), VERR_INVALID_PARAMETER); 7235 7241 … … 7241 7247 HRESULT rc = S_OK; 7242 7248 7243 LogFlowFunc 7249 LogFlowFunc(("Saving the state to '%s'...\n", task->mSavedStateFile.raw())); 7244 7250 7245 7251 int vrc = VMR3Save(that->mpVM, … … 7248 7254 Console::stateProgressCallback, 7249 7255 static_cast<VMProgressTask*>(task.get())); 7250 if ( VBOX_FAILURE(vrc))7256 if (RT_FAILURE(vrc)) 7251 7257 { 7252 7258 errMsg = Utf8StrFmt(Console::tr("Failed to save the machine state to '%s' (%Rrc)"), … … 7256 7262 7257 7263 /* lock the console once we're going to access it */ 7258 AutoWriteLock thatLock 7264 AutoWriteLock thatLock(that); 7259 7265 7260 7266 /* 7261 * 7262 * 7263 * 7264 * 7267 * finalize the requested save state procedure. 7268 * In case of success, the server will set the machine state to Saved; 7269 * in case of failure it will reset the it to the state it had right 7270 * before calling mControl->BeginSavingState(). 7265 7271 */ 7266 that->mControl->EndSavingState 7272 that->mControl->EndSavingState(SUCCEEDED(rc)); 7267 7273 7268 7274 /* synchronize the state with the server */ … … 7270 7276 { 7271 7277 /* 7272 * 7273 * 7274 * 7275 * 7278 * The machine has been successfully saved, so power it down 7279 * (vmstateChangeCallback() will set state to Saved on success). 7280 * Note: we release the task's VM caller, otherwise it will 7281 * deadlock. 7276 7282 */ 7277 7283 task->releaseVMCaller(); … … 7282 7288 /* notify the progress object about operation completion */ 7283 7289 if (SUCCEEDED(rc)) 7284 task->mProgress->notifyComplete 7290 task->mProgress->notifyComplete(S_OK); 7285 7291 else 7286 7292 { … … 7291 7297 errMsg.c_str()); 7292 7298 else 7293 task->mProgress->notifyComplete 7299 task->mProgress->notifyComplete(rc); 7294 7300 } 7295 7301 … … 7299 7305 7300 7306 /** 7301 * 7302 * 7303 * 7304 * 7305 * 7306 * 7307 * 7307 * Thread for powering down the Console. 7308 * 7309 * @param Thread The thread handle. 7310 * @param pvUser Pointer to the VMTask structure. 7311 * @return VINF_SUCCESS (ignored). 7312 * 7313 * @note Locks the Console object for writing. 7308 7314 */ 7309 7315 /*static*/ 7310 DECLCALLBACK 7316 DECLCALLBACK(int) Console::powerDownThread(RTTHREAD Thread, void *pvUser) 7311 7317 { 7312 7318 LogFlowFuncEnter(); 7313 7319 7314 std::auto_ptr <VMProgressTask> task (static_cast <VMProgressTask *>(pvUser));7320 std::auto_ptr<VMProgressTask> task(static_cast<VMProgressTask *>(pvUser)); 7315 7321 AssertReturn(task.get(), VERR_INVALID_PARAMETER); 7316 7322 … … 7323 7329 7324 7330 /* wait until the method tat started us returns */ 7325 AutoWriteLock thatLock 7331 AutoWriteLock thatLock(that); 7326 7332 7327 7333 /* release VM caller to avoid the powerDown() deadlock */ 7328 7334 task->releaseVMCaller(); 7329 7335 7330 that->powerDown 7336 that->powerDown(task->mProgress); 7331 7337 7332 7338 LogFlowFuncLeave(); … … 7369 7375 PPDMLED pLed; 7370 7376 int rc = pData->pLedPorts->pfnQueryStatusLed(pData->pLedPorts, iLUN, &pLed); 7371 if ( VBOX_FAILURE(rc))7377 if (RT_FAILURE(rc)) 7372 7378 pLed = NULL; 7373 7379 ASMAtomicXchgPtr((void * volatile *)&pData->papLeds[iLUN - pData->iFirstLUN], pLed); … … 7449 7455 */ 7450 7456 int rc = CFGMR3QueryPtr(pCfgHandle, "papLeds", (void **)&pData->papLeds); 7451 if ( VBOX_FAILURE(rc))7457 if (RT_FAILURE(rc)) 7452 7458 { 7453 7459 AssertMsgFailed(("Configuration error: Failed to query the \"papLeds\" value! rc=%Rrc\n", rc)); … … 7458 7464 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 7459 7465 pData->iFirstLUN = 0; 7460 else if ( VBOX_FAILURE(rc))7466 else if (RT_FAILURE(rc)) 7461 7467 { 7462 7468 AssertMsgFailed(("Configuration error: Failed to query the \"First\" value! rc=%Rrc\n", rc)); … … 7467 7473 if (rc == VERR_CFGM_VALUE_NOT_FOUND) 7468 7474 pData->iLastLUN = 0; 7469 else if ( VBOX_FAILURE(rc))7475 else if (RT_FAILURE(rc)) 7470 7476 { 7471 7477 AssertMsgFailed(("Configuration error: Failed to query the \"Last\" value! rc=%Rrc\n", rc)); … … 7489 7495 } 7490 7496 7491 for (unsigned i = pData->iFirstLUN; i <= pData->iLastLUN; i++)7497 for (unsigned i = pData->iFirstLUN; i <= pData->iLastLUN; ++i) 7492 7498 Console::drvStatus_UnitChanged(&pData->ILedConnectors, i); 7493 7499
Note:
See TracChangeset
for help on using the changeset viewer.