Changeset 42507 in vbox for trunk/src/VBox/Main
- Timestamp:
- Aug 1, 2012 12:40:05 PM (12 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r42461 r42507 9900 9900 <interface 9901 9901 name="IProcess" extends="$unknown" 9902 uuid=" f55af4a1-e280-40ac-83e1-921c0abcaf18"9902 uuid="83275f41-01ee-4362-ac44-298191b5186c" 9903 9903 wsmap="managed" 9904 9904 > … … 10033 10033 <param name="handle" type="unsigned long" dir="in"> 10034 10034 <desc>TODO</desc> 10035 </param> 10036 <param name="flags" type="unsigned long" dir="in"> 10037 <desc> 10038 <link to="ProcessInputFlag"/> flags. 10039 </desc> 10040 </param> 10041 <param name="data" type="octet" dir="in" safearray="yes"> 10042 <desc>TODO</desc> 10043 </param> 10044 <param name="timeoutMS" type="unsigned long" dir="in"> 10045 <desc>TODO</desc> 10046 </param> 10047 <param name="written" type="unsigned long" dir="return"> 10048 <desc>TODO</desc> 10049 </param> 10050 </method> 10051 10052 <method name="WriteArray"> 10053 <desc> 10054 TODO 10055 10056 <result name="VBOX_E_NOT_SUPPORTED"> 10057 TODO 10058 </result> 10059 </desc> 10060 <param name="handle" type="unsigned long" dir="in"> 10061 <desc>TODO</desc> 10062 </param> 10063 <param name="flags" type="ProcessInputFlag" dir="in" safearray="yes"> 10064 <desc> 10065 <link to="ProcessInputFlag"/> flags. 10066 </desc> 10035 10067 </param> 10036 10068 <param name="data" type="octet" dir="in" safearray="yes"> -
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r42485 r42507 133 133 void Destroy(void); 134 134 135 int FillData(const void *pvToWrite, size_t cbToWrite);136 137 135 int Init(eVBoxGuestCtrlCallbackType enmType); 138 136 139 137 eVBoxGuestCtrlCallbackType GetCallbackType(void) { return mType; } 140 138 139 const void* GetDataRaw(void) const { return pvData; } 140 141 size_t GetDataSize(void) { return cbData; } 142 141 143 const void* GetPayloadRaw(void) const { return pvPayload; } 142 144 143 145 size_t GetPayloadSize(void) { return cbPayload; } 146 147 int SetData(const void *pvCallback, size_t cbCallback); 148 149 int SetPayload(const void *pvToWrite, size_t cbToWrite); 144 150 145 151 protected: … … 156 162 * waiting (optional). */ 157 163 void *pvPayload; 158 /** Size of the payload . */164 /** Size of the payload (optional). */ 159 165 size_t cbPayload; 160 166 }; -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r42461 r42507 65 65 STDMETHOD(WaitFor)(ULONG aWaitFlags, ULONG aTimeoutMS, ProcessWaitResult_T *aReason); 66 66 STDMETHOD(WaitForArray)(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason); 67 STDMETHOD(Write)(ULONG aHandle, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten); 67 STDMETHOD(Write)(ULONG aHandle, ULONG aFlags, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten); 68 STDMETHOD(WriteArray)(ULONG aHandle, ComSafeArrayIn(ProcessInputFlag_T, aFlags), ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten); 68 69 /** @} */ 69 70 … … 72 73 * @{ */ 73 74 int callbackDispatcher(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData); 74 inline bool callbackExists( ULONGuContextID);75 inline bool callbackExists(uint32_t uContextID); 75 76 void close(void); 76 77 bool isReady(void); 77 78 ULONG getPID(void) { return mData.mPID; } 78 int readData( ULONG uHandle, ULONG uSize, ULONG uTimeoutMS, BYTE *pbData, size_t cbData, size_t *pcbRead);79 int readData(uint32_t uHandle, uint32_t uSize, uint32_t uTimeoutMS, void *pvData, size_t cbData, size_t *pcbRead); 79 80 int startProcess(void); 80 81 int startProcessAsync(void); 81 82 int terminateProcess(void); 82 83 int waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestProcessWaitResult &guestResult); 83 int writeData( ULONG uHandle, BYTE const *pbData, size_t cbData, ULONG uTimeoutMS, ULONG*puWritten);84 int writeData(uint32_t uHandle, uint32_t uFlags, void *pvData, size_t cbData, uint32_t uTimeoutMS, uint32_t *puWritten); 84 85 /** @} */ 85 86 … … 87 88 /** @name Protected internal methods. 88 89 * @{ */ 89 inline int callbackAdd(GuestCtrlCallback *pCallback, ULONG*puContextID);90 inline int callbackRemove( ULONGuContextID);90 inline int callbackAdd(GuestCtrlCallback *pCallback, uint32_t *puContextID); 91 inline int callbackRemove(uint32_t uContextID); 91 92 inline bool isAlive(void); 92 93 int onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData); -
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r42485 r42507 196 196 GuestCtrlEvent::Destroy(); 197 197 198 switch (mType) 199 { 200 case VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT: 201 { 202 PCALLBACKDATAEXECOUT pThis = (PCALLBACKDATAEXECOUT)pvData; 203 AssertPtr(pThis); 204 if (pThis->pvData) 205 RTMemFree(pThis->pvData); 206 } 207 208 default: 209 break; 210 } 211 198 212 mType = VBOXGUESTCTRLCALLBACKTYPE_UNKNOWN; 199 213 if (pvData) … … 212 226 } 213 227 214 int GuestCtrlCallback::FillData(const void *pvToWrite, size_t cbToWrite) 228 int GuestCtrlCallback::SetData(const void *pvCallback, size_t cbCallback) 229 { 230 if (!cbCallback) 231 return VINF_SUCCESS; 232 AssertPtr(pvCallback); 233 234 switch (mType) 235 { 236 case VBOXGUESTCTRLCALLBACKTYPE_EXEC_START: 237 { 238 PCALLBACKDATAEXECSTATUS pThis = (PCALLBACKDATAEXECSTATUS)pvData; 239 PCALLBACKDATAEXECSTATUS pCB = (PCALLBACKDATAEXECSTATUS)pvCallback; 240 Assert(cbCallback == sizeof(CALLBACKDATAEXECSTATUS)); 241 242 pThis->u32Flags = pCB->u32Flags; 243 pThis->u32PID = pCB->u32PID; 244 pThis->u32Status = pCB->u32Status; 245 break; 246 } 247 248 case VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT: 249 { 250 PCALLBACKDATAEXECOUT pThis = (PCALLBACKDATAEXECOUT)pvData; 251 PCALLBACKDATAEXECOUT pCB = (PCALLBACKDATAEXECOUT)pvCallback; 252 Assert(cbCallback == sizeof(CALLBACKDATAEXECOUT)); 253 254 pThis->cbData = pCB->cbData; 255 if (pThis->cbData) 256 { 257 pThis->pvData = RTMemAlloc(pCB->cbData); 258 AssertPtrReturn(pThis->pvData, VERR_NO_MEMORY); 259 memcpy(pThis->pvData, pCB->pvData, pCB->cbData); 260 } 261 pThis->u32Flags = pCB->u32Flags; 262 pThis->u32PID = pCB->u32PID; 263 break; 264 } 265 266 case VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS: 267 { 268 PCALLBACKDATAEXECINSTATUS pThis = (PCALLBACKDATAEXECINSTATUS)pvData; 269 PCALLBACKDATAEXECINSTATUS pCB = (PCALLBACKDATAEXECINSTATUS)pvCallback; 270 Assert(cbCallback == sizeof(CALLBACKDATAEXECINSTATUS)); 271 272 pThis->cbProcessed = pCB->cbProcessed; 273 pThis->u32Flags = pCB->u32Flags; 274 pThis->u32PID = pCB->u32PID; 275 pThis->u32Status = pCB->u32Status; 276 } 277 278 default: 279 AssertMsgFailed(("Callback type not handled (%d)\n", mType)); 280 break; 281 } 282 283 return VINF_SUCCESS; 284 } 285 286 int GuestCtrlCallback::SetPayload(const void *pvToWrite, size_t cbToWrite) 215 287 { 216 288 if (!cbToWrite) -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r42485 r42507 17 17 */ 18 18 19 /** 20 * Locking rules: 21 * - When the main dispatcher (callbackDispatcher) is called it takes the 22 * WriteLock while dispatching to the various on* methods. 23 * - All other outer functions (accessible by Main) must not own a lock 24 * while waiting for a callback or for an event. 25 * - Only keep Read/WriteLocks as short as possible and only when necessary. 26 */ 19 27 20 28 /******************************************************************************* … … 308 316 ///////////////////////////////////////////////////////////////////////////// 309 317 310 inline int GuestProcess::callbackAdd(GuestCtrlCallback *pCallback, ULONG*puContextID)318 inline int GuestProcess::callbackAdd(GuestCtrlCallback *pCallback, uint32_t *puContextID) 311 319 { 312 320 const ComObjPtr<GuestSession> pSession(mData.mParent); … … 360 368 361 369 LogFlowThisFunc(("Added new callback (Session: %RU32, Process: %RU32, Count=%RU32) CID=%RU32\n", 362 uSessionID, mData.mProcessID, uCount, uNewContextID));370 uSessionID, mData.mProcessID, uCount, uNewContextID)); 363 371 } 364 372 … … 370 378 #ifdef DEBUG 371 379 LogFlowThisFunc(("uPID=%RU32, uContextID=%RU32, uFunction=%RU32, pvData=%p, cbData=%RU32\n", 372 mData.mPID, uContextID, uFunction, pvData, cbData));380 mData.mPID, uContextID, uFunction, pvData, cbData)); 373 381 #endif 374 382 … … 453 461 } 454 462 455 inline bool GuestProcess::callbackExists( ULONGuContextID)463 inline bool GuestProcess::callbackExists(uint32_t uContextID) 456 464 { 457 465 GuestCtrlCallbacks::const_iterator it = … … 460 468 } 461 469 462 inline int GuestProcess::callbackRemove( ULONGuContextID)470 inline int GuestProcess::callbackRemove(uint32_t uContextID) 463 471 { 464 472 GuestCtrlCallbacks::iterator it = … … 595 603 596 604 LogFlowThisFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32, pCallback=%p, pData=%p\n", 597 pData->u32PID, pData->u32Status, pData->u32Flags, pCallback, pData));605 pData->u32PID, pData->u32Status, pData->u32Flags, pCallback, pData)); 598 606 599 607 int rc = VINF_SUCCESS; … … 779 787 780 788 LogFlowThisFunc(("uPID=%RU32, uHandle=%RU32, uFlags=%RU32, pvData=%p, cbData=%RU32, pCallback=%p, pData=%p\n", 781 mData.mPID, pData->u32HandleId, pData->u32Flags, pData->pvData, pData->cbData, pCallback, pData));789 mData.mPID, pData->u32HandleId, pData->u32Flags, pData->pvData, pData->cbData, pCallback, pData)); 782 790 783 791 /* Copy data into callback (if any). */ … … 787 795 if (pCallback) 788 796 { 789 if (pData->pvData && pData->cbData) 790 { 791 rc = pCallback->FillData(pData->pvData, pData->cbData); 792 Assert(pCallback->GetPayloadSize() == pData->cbData); 793 } 797 rc = pCallback->SetData(pData, sizeof(CALLBACKDATAEXECOUT)); 794 798 795 799 int rc2 = pCallback->Signal(); … … 831 835 } 832 836 833 int GuestProcess::readData( ULONG uHandle, ULONG uSize, ULONGuTimeoutMS,834 BYTE *pbData, size_t cbData, size_t *pcbRead)835 { 836 LogFlowThisFunc(("uPID=%RU32, uHandle=%RU32, uSize=%RU32, uTimeoutMS=%RU32, p bData=%p, cbData=%RU32\n",837 mData.mPID, uHandle, uSize, uTimeoutMS, pbData, cbData));837 int GuestProcess::readData(uint32_t uHandle, uint32_t uSize, uint32_t uTimeoutMS, 838 void *pvData, size_t cbData, size_t *pcbRead) 839 { 840 LogFlowThisFunc(("uPID=%RU32, uHandle=%RU32, uSize=%RU32, uTimeoutMS=%RU32, pvData=%p, cbData=%RU32\n", 841 mData.mPID, uHandle, uSize, uTimeoutMS, pvData, cbData)); 838 842 AssertReturn(uSize, VERR_INVALID_PARAMETER); 839 AssertPtrReturn(p bData, VERR_INVALID_POINTER);843 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 840 844 AssertReturn(cbData >= uSize, VERR_INVALID_PARAMETER); 841 845 /* pcbRead is optional. */ … … 846 850 return VERR_NOT_AVAILABLE; 847 851 848 ULONGuContextID = 0;852 uint32_t uContextID = 0; 849 853 GuestCtrlCallback *pCallbackRead = new GuestCtrlCallback(); 850 854 if (!pCallbackRead) … … 882 886 { 883 887 rc = pCallbackRead->GetResultCode(); 884 LogFlowThisFunc(("Callback returned rc=%Rrc, cbData=%RU32\n", rc, pCallbackRead->Get PayloadSize()));888 LogFlowThisFunc(("Callback returned rc=%Rrc, cbData=%RU32\n", rc, pCallbackRead->GetDataSize())); 885 889 886 890 if (RT_SUCCESS(rc)) 887 891 { 888 size_t cbDataCB = pCallbackRead->GetPayloadSize(); 889 if (cbDataCB) 892 Assert(pCallbackRead->GetDataSize() == sizeof(CALLBACKDATAEXECOUT)); 893 PCALLBACKDATAEXECOUT pData = (PCALLBACKDATAEXECOUT)pCallbackRead->GetDataRaw(); 894 AssertPtr(pData); 895 896 size_t cbRead = pData->cbData; 897 if (cbRead) 890 898 { 891 Assert(cbData >= cb DataCB);892 memcpy(p bData, pCallbackRead->GetPayloadRaw(), cbDataCB);899 Assert(cbData >= cbRead); 900 memcpy(pvData, pData->pvData, cbRead); 893 901 } 894 902 903 LogFlowThisFunc(("cbRead=%RU32\n", cbRead)); 904 895 905 if (pcbRead) 896 *pcbRead = cb DataCB;906 *pcbRead = cbRead; 897 907 } 898 908 } … … 944 954 } 945 955 956 /* Does not do locking; caller is responsible for that! */ 946 957 int GuestProcess::setErrorInternal(int rc, const Utf8Str &strMessage) 947 958 { … … 958 969 #endif 959 970 960 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);961 962 971 mData.mStatus = ProcessStatus_Error; 963 972 mData.mRC = rc; … … 999 1008 1000 1009 int rc; 1001 ULONGuContextID = 0;1010 uint32_t uContextID = 0; 1002 1011 GuestCtrlCallback *pCallbackStart = new GuestCtrlCallback(); 1003 1012 if (!pCallbackStart) … … 1013 1022 if (RT_SUCCESS(rc)) 1014 1023 { 1015 // AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);1016 1017 1024 GuestSession *pSession = mData.mParent; 1018 1025 AssertPtr(pSession); … … 1070 1077 paParms[i++].setUInt32(mData.mProcess.mTimeoutMS); 1071 1078 1079 /* Note: Don't hold the write lock in here, because setErrorInternal */ 1072 1080 rc = sendCommand(HOST_EXEC_CMD, i, paParms); 1073 1081 } … … 1079 1087 uint32_t uTimeoutMS = mData.mProcess.mTimeoutMS; 1080 1088 1081 alock.release(); /* Drop the write lock again. */ 1089 /* Drop the write lock again before waiting. */ 1090 alock.release(); 1082 1091 1083 1092 if (RT_SUCCESS(rc)) … … 1135 1144 DECLCALLBACK(int) GuestProcess::startProcessThread(RTTHREAD Thread, void *pvUser) 1136 1145 { 1137 LogFlowFuncEnter( );1146 LogFlowFuncEnter(("pvUser=%p\n", pvUser)); 1138 1147 1139 1148 std::auto_ptr<GuestProcessStartTask> pTask(static_cast<GuestProcessStartTask*>(pvUser)); … … 1153 1162 1154 1163 LogFlowFuncLeaveRC(rc); 1155 return VINF_SUCCESS;1164 return rc; 1156 1165 } 1157 1166 … … 1174 1183 1175 1184 LogFlowThisFunc(("fWaitFlags=%x, uTimeoutMS=%RU32, mStatus=%RU32, mWaitCount=%RU32, mWaitEvent=%p\n", 1176 fWaitFlags, uTimeoutMS, mData.mStatus, mData.mWaitCount, mData.mWaitEvent));1185 fWaitFlags, uTimeoutMS, mData.mStatus, mData.mWaitCount, mData.mWaitEvent)); 1177 1186 1178 1187 ProcessStatus_T curStatus; … … 1445 1454 } 1446 1455 1447 int GuestProcess::writeData(ULONG uHandle, const BYTE *pbData, size_t cbData, ULONG uTimeoutMS, ULONG *puWritten) 1448 { 1449 LogFlowThisFunc(("uPID=%RU32, uHandle=%RU32, pbData=%p, cbData=%RU32, uTimeoutMS=%RU32, puWritten=%p\n", 1450 mData.mPID, uHandle, pbData, cbData, uTimeoutMS, puWritten)); 1451 AssertPtrReturn(pbData, VERR_INVALID_POINTER); 1452 AssertReturn(pbData, VERR_INVALID_PARAMETER); 1456 int GuestProcess::writeData(uint32_t uHandle, uint32_t uFlags, 1457 void *pvData, size_t cbData, uint32_t uTimeoutMS, uint32_t *puWritten) 1458 { 1459 LogFlowThisFunc(("uPID=%RU32, uHandle=%RU32, pvData=%p, cbData=%RU32, uTimeoutMS=%RU32, puWritten=%p\n", 1460 mData.mPID, uHandle, pvData, cbData, uTimeoutMS, puWritten)); 1461 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 1462 AssertReturn(cbData, VERR_INVALID_PARAMETER); 1453 1463 /* Rest is optional. */ 1454 1464 1455 LogFlowThisFuncLeave(); 1456 return 0; 1465 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1466 1467 if (mData.mStatus != ProcessStatus_Started) 1468 return VERR_NOT_AVAILABLE; 1469 1470 uint32_t uContextID = 0; 1471 GuestCtrlCallback *pCallbackWrite = new GuestCtrlCallback(); 1472 if (!pCallbackWrite) 1473 return VERR_NO_MEMORY; 1474 1475 /* Create callback and add it to the map. */ 1476 int rc = pCallbackWrite->Init(VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS); 1477 if (RT_SUCCESS(rc)) 1478 rc = callbackAdd(pCallbackWrite, &uContextID); 1479 1480 alock.release(); /* Drop the write lock again. */ 1481 1482 if (RT_SUCCESS(rc)) 1483 { 1484 VBOXHGCMSVCPARM paParms[5]; 1485 1486 int i = 0; 1487 paParms[i++].setUInt32(uContextID); 1488 paParms[i++].setUInt32(mData.mPID); 1489 paParms[i++].setUInt32(uFlags); 1490 paParms[i++].setPointer(pvData, cbData); 1491 paParms[i++].setUInt32(cbData); 1492 1493 rc = sendCommand(HOST_EXEC_SET_INPUT, i, paParms); 1494 } 1495 1496 if (RT_SUCCESS(rc)) 1497 { 1498 /* 1499 * Let's wait for the process being started. 1500 * Note: Be sure not keeping a AutoRead/WriteLock here. 1501 */ 1502 LogFlowThisFunc(("Waiting for callback (%RU32ms) ...\n", uTimeoutMS)); 1503 rc = pCallbackWrite->Wait(uTimeoutMS); 1504 if (RT_SUCCESS(rc)) /* Wait was successful, check for supplied information. */ 1505 { 1506 rc = pCallbackWrite->GetResultCode(); 1507 LogFlowThisFunc(("Callback returned rc=%Rrc, cbData=%RU32\n", rc, pCallbackWrite->GetDataSize())); 1508 1509 if (RT_SUCCESS(rc)) 1510 { 1511 Assert(pCallbackWrite->GetDataSize() == sizeof(CALLBACKDATAEXECINSTATUS)); 1512 PCALLBACKDATAEXECINSTATUS pData = (PCALLBACKDATAEXECINSTATUS)pCallbackWrite->GetDataRaw(); 1513 AssertPtr(pData); 1514 1515 uint32_t cbWritten = 0; 1516 switch (pData->u32Status) 1517 { 1518 case INPUT_STS_WRITTEN: 1519 cbWritten = pData->cbProcessed; 1520 break; 1521 1522 case INPUT_STS_ERROR: 1523 rc = pData->u32Flags; /** @todo Fix int vs. uint32_t! */ 1524 break; 1525 1526 case INPUT_STS_TERMINATED: 1527 rc = VERR_CANCELLED; 1528 break; 1529 1530 case INPUT_STS_OVERFLOW: 1531 rc = VERR_BUFFER_OVERFLOW; 1532 break; 1533 1534 default: 1535 /* Silently skip unknown errors. */ 1536 break; 1537 } 1538 1539 LogFlowThisFunc(("cbWritten=%RU32\n", cbWritten)); 1540 1541 if (puWritten) 1542 *puWritten = cbWritten; 1543 } 1544 } 1545 else 1546 rc = VERR_TIMEOUT; 1547 } 1548 1549 alock.acquire(); 1550 1551 AssertPtr(pCallbackWrite); 1552 int rc2 = callbackRemove(uContextID); 1553 if (RT_SUCCESS(rc)) 1554 rc = rc2; 1555 1556 LogFlowFuncLeaveRC(rc); 1557 return rc; 1457 1558 } 1458 1559 … … 1579 1680 } 1580 1681 1581 STDMETHODIMP GuestProcess::Write(ULONG aHandle, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten) 1682 STDMETHODIMP GuestProcess::Write(ULONG aHandle, ULONG aFlags, 1683 ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten) 1582 1684 { 1583 1685 #ifndef VBOX_WITH_GUEST_CONTROL … … 1594 1696 1595 1697 com::SafeArray<BYTE> data(ComSafeArrayInArg(aData)); 1596 int rc = writeData(aHandle, data.raw(), data.size(), aTimeoutMS,aWritten);1698 int rc = writeData(aHandle, aFlags, data.raw(), data.size(), aTimeoutMS, (uint32_t*)aWritten); 1597 1699 /** @todo Do setError() here. */ 1598 1700 HRESULT hr = RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR; … … 1603 1705 } 1604 1706 1707 STDMETHODIMP GuestProcess::WriteArray(ULONG aHandle, ComSafeArrayIn(ProcessInputFlag_T, aFlags), 1708 ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten) 1709 { 1710 #ifndef VBOX_WITH_GUEST_CONTROL 1711 ReturnComNotImplemented(); 1712 #else 1713 LogFlowThisFuncEnter(); 1714 1715 CheckComArgOutPointerValid(aWritten); 1716 1717 AutoCaller autoCaller(this); 1718 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1719 1720 /* 1721 * Note: Do not hold any locks here while writing! 1722 */ 1723 ULONG fWrite = ProcessInputFlag_None; 1724 com::SafeArray<ProcessInputFlag_T> flags(ComSafeArrayInArg(aFlags)); 1725 for (size_t i = 0; i < flags.size(); i++) 1726 fWrite |= flags[i]; 1727 1728 return Write(aHandle, fWrite, ComSafeArrayInArg(aData), aTimeoutMS, aWritten); 1729 #endif /* VBOX_WITH_GUEST_CONTROL */ 1730 } 1731
Note:
See TracChangeset
for help on using the changeset viewer.