Changeset 70766 in vbox for trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
- Timestamp:
- Jan 28, 2018 8:53:14 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r70753 r70766 5079 5079 } 5080 5080 5081 5082 /** 5083 * Performs the Serial Port attachment change in EMT. 5084 * 5085 * @returns VBox status code. 5086 * 5087 * @param pThis Pointer to the Console object. 5088 * @param pUVM The VM handle. 5089 * @param pSerialPort The serial port whose attachment needs to be changed 5090 * 5091 * @thread EMT 5092 * @note Locks the Console object for writing. 5093 * @note The VM must not be running. 5094 */ 5095 DECLCALLBACK(int) Console::i_changeSerialPortAttachment(Console *pThis, PUVM pUVM, 5096 ISerialPort *pSerialPort) 5097 { 5098 LogFlowFunc(("pThis=%p pUVM=%p pSerialPort=%p\n", pThis, pUVM, pSerialPort)); 5099 5100 AssertReturn(pThis, VERR_INVALID_PARAMETER); 5101 5102 AutoCaller autoCaller(pThis); 5103 AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED); 5104 5105 AutoWriteLock alock(pThis COMMA_LOCKVAL_SRC_POS); 5106 5107 /* 5108 * Check the VM for correct state. 5109 */ 5110 VMSTATE enmVMState = VMR3GetStateU(pUVM); 5111 AssertReturn(enmVMState == VMSTATE_SUSPENDED, VERR_INVALID_STATE); 5112 5113 HRESULT hrc = S_OK; 5114 int rc = VINF_SUCCESS; 5115 ULONG ulSlot; 5116 hrc = pSerialPort->COMGETTER(Slot)(&ulSlot); 5117 if (SUCCEEDED(hrc)) 5118 { 5119 /* Check whether the port mode changed and act accordingly. */ 5120 Assert(ulSlot < 4); 5121 5122 PortMode_T eHostMode; 5123 hrc = pSerialPort->COMGETTER(HostMode)(&eHostMode); 5124 if (SUCCEEDED(hrc)) 5125 { 5126 PCFGMNODE pInst = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/serial/%d/", ulSlot); 5127 AssertRelease(pInst); 5128 5129 /* Remove old driver. */ 5130 if (pThis->m_aeSerialPortMode[ulSlot] != PortMode_Disconnected) 5131 { 5132 rc = PDMR3DeviceDetach(pUVM, "serial", ulSlot, 0, 0); 5133 PCFGMNODE pLunL0 = CFGMR3GetChildF(pInst, "LUN#0"); 5134 CFGMR3RemoveNode(pLunL0); 5135 } 5136 5137 if (RT_SUCCESS(rc)) 5138 { 5139 BOOL fServer; 5140 Bstr bstrPath; 5141 hrc = pSerialPort->COMGETTER(Server)(&fServer); 5142 if (SUCCEEDED(hrc)) 5143 hrc = pSerialPort->COMGETTER(Path)(bstrPath.asOutParam()); 5144 5145 /* Configure new driver. */ 5146 if ( SUCCEEDED(hrc) 5147 && eHostMode != PortMode_Disconnected) 5148 { 5149 rc = pThis->i_configSerialPort(pInst, eHostMode, Utf8Str(bstrPath).c_str(), RT_BOOL(fServer)); 5150 if (RT_SUCCESS(rc)) 5151 { 5152 /* 5153 * Attach the driver. 5154 */ 5155 PPDMIBASE pBase; 5156 rc = PDMR3DeviceAttach(pUVM, "serial", ulSlot, 0, 0, &pBase); 5157 5158 CFGMR3Dump(pInst); 5159 } 5160 } 5161 } 5162 } 5163 } 5164 5165 if (RT_SUCCESS(rc) && FAILED(hrc)) 5166 rc = VERR_INTERNAL_ERROR; 5167 5168 LogFlowFunc(("Returning %Rrc\n", rc)); 5169 return rc; 5170 } 5171 5172 5081 5173 /** 5082 5174 * Called by IInternalSessionControl::OnSerialPortChange(). … … 5089 5181 AssertComRCReturnRC(autoCaller.rc()); 5090 5182 5091 fireSerialPortChangedEvent(mEventSource, aSerialPort); 5183 HRESULT hrc = S_OK; 5184 5185 /* don't trigger audio changes if the VM isn't running */ 5186 SafeVMPtrQuiet ptrVM(this); 5187 if (ptrVM.isOk()) 5188 { 5189 ULONG ulSlot; 5190 BOOL fEnabled; 5191 hrc = aSerialPort->COMGETTER(Slot)(&ulSlot); 5192 if (SUCCEEDED(hrc)) 5193 hrc = aSerialPort->COMGETTER(Enabled)(&fEnabled); 5194 if (SUCCEEDED(hrc) && fEnabled) 5195 { 5196 /* Check whether the port mode changed and act accordingly. */ 5197 Assert(ulSlot < 4); 5198 5199 PortMode_T eHostMode; 5200 hrc = aSerialPort->COMGETTER(HostMode)(&eHostMode); 5201 if (m_aeSerialPortMode[ulSlot] != eHostMode) 5202 { 5203 /* 5204 * Suspend the VM first. 5205 */ 5206 bool fResume = false; 5207 HRESULT hr = i_suspendBeforeConfigChange(ptrVM.rawUVM(), NULL, &fResume); 5208 if (FAILED(hr)) 5209 return hr; 5210 5211 /* 5212 * Call worker in EMT, that's faster and safer than doing everything 5213 * using VM3ReqCallWait. 5214 */ 5215 int rc = VMR3ReqCallWaitU(ptrVM.rawUVM(), 0 /*idDstCpu*/, 5216 (PFNRT)i_changeSerialPortAttachment, 6, 5217 this, ptrVM.rawUVM(), aSerialPort); 5218 5219 if (fResume) 5220 i_resumeAfterConfigChange(ptrVM.rawUVM()); 5221 if (RT_SUCCESS(rc)) 5222 m_aeSerialPortMode[ulSlot] = eHostMode; 5223 else 5224 hrc = setError(E_FAIL, 5225 tr("Failed to change the serial port attachment (%Rrc)"), rc); 5226 } 5227 } 5228 } 5229 5230 if (SUCCEEDED(hrc)) 5231 fireSerialPortChangedEvent(mEventSource, aSerialPort); 5092 5232 5093 5233 LogFlowThisFunc(("Leaving rc=%#x\n", S_OK)); 5094 return S_OK;5234 return hrc; 5095 5235 } 5096 5236
Note:
See TracChangeset
for help on using the changeset viewer.