Changeset 39487 in vbox
- Timestamp:
- Dec 1, 2011 10:58:19 AM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 75146
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/GuestImpl.h
r39450 r39487 179 179 int executeStreamGetNextBlock(ULONG ulPID, ULONG ulFlags, GuestProcessStream &stream, GuestProcessStreamBlock &streamBlock); 180 180 int executeStreamParseNextBlock(ULONG ulPID, ULONG ulFlags, GuestProcessStream &stream, GuestProcessStreamBlock &streamBlock); 181 HRESULT executeStreamParse(ULONG ulPID, ULONG ulFlags, GuestCtrlStreamObjects &streamObjects); 182 HRESULT executeWaitForStatusChange(ULONG uPID, ULONG uTimeoutMS, ExecuteProcessStatus_T *pRetStatus, ULONG *puRetExitCode); 181 HRESULT executeStreamParse(ULONG uPID, ULONG ulFlags, GuestCtrlStreamObjects &streamObjects); 182 HRESULT executeWaitForExit(ULONG uPID, ComPtr<IProgress> pProgress, ULONG uTimeoutMS, 183 ExecuteProcessStatus_T *pRetStatus, ULONG *puRetExitCode); 183 184 // Internal guest file functions 184 185 HRESULT fileExistsInternal(IN_BSTR aFile, IN_BSTR aUsername, IN_BSTR aPassword, BOOL *aExists); -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r39475 r39487 1506 1506 1507 1507 /** 1508 * Does busy waiting on a formerly started guest process. 1508 * Waits for a fomerly started guest process to exit using its progress 1509 * object and returns its final status. Returns E_ABORT if guest process 1510 * was canceled. 1509 1511 * 1510 * @return HRESULT1512 * @return IPRT status code. 1511 1513 * @param uPID PID of guest process to wait for. 1512 * @param uTimeoutMS Waiting timeout (in ms). Specify 0 for an infinite timeout. 1513 * @param pRetStatus Pointer which receives current process status after the change. 1514 * Optional. 1515 * @param puRetExitCode Pointer which receives the final exit code in case of guest process 1516 * termination. Optional. 1514 * @param pProgress Progress object to wait for. 1515 * @param uTimeoutMS Timeout (in ms) for waiting; use 0 for 1516 * an indefinite timeout. 1517 * @param pRetStatus Pointer where to store the final process 1518 * status. Optional. 1519 * @param puRetExitCode Pointer where to store the final process 1520 * exit code. Optional. 1517 1521 */ 1518 HRESULT Guest::executeWaitForStatusChange(ULONG uPID, ULONG uTimeoutMS, 1519 ExecuteProcessStatus_T *pRetStatus, ULONG *puRetExitCode) 1520 { 1521 ULONG uExitCode, uRetFlags; 1522 ExecuteProcessStatus_T curStatus; 1523 HRESULT hRC = GetProcessStatus(uPID, &uExitCode, &uRetFlags, &curStatus); 1524 if (FAILED(hRC)) 1525 return hRC; 1526 1527 /* We only want to wait for started processes. All other statuses 1528 * won't be found anyway anymore (see processGetStatus() to know why). */ 1529 if (curStatus == ExecuteProcessStatus_Started) 1530 { 1531 uint64_t u64StartMS = RTTimeMilliTS(); 1532 if (uTimeoutMS == 0) 1533 uTimeoutMS = UINT32_MAX; 1534 1535 do 1536 { 1537 if ( uTimeoutMS != UINT32_MAX 1538 && RTTimeMilliTS() - u64StartMS > uTimeoutMS) 1539 { 1540 hRC = setError(VBOX_E_IPRT_ERROR, 1541 tr("The process (PID %u) did not change its status within time (%ums)"), 1542 uPID, uTimeoutMS); 1543 break; 1544 } 1545 hRC = GetProcessStatus(uPID, &uExitCode, &uRetFlags, &curStatus); 1546 if (FAILED(hRC)) 1547 break; 1548 RTThreadSleep(100); 1549 } while(*pRetStatus == curStatus); 1550 } 1551 1552 if (SUCCEEDED(hRC)) 1553 { 1522 HRESULT Guest::executeWaitForExit(ULONG uPID, ComPtr<IProgress> pProgress, ULONG uTimeoutMS, 1523 ExecuteProcessStatus_T *pRetStatus, ULONG *puRetExitCode) 1524 { 1525 HRESULT rc = S_OK; 1526 1527 BOOL fCanceled = FALSE; 1528 if ( SUCCEEDED(pProgress->COMGETTER(Canceled(&fCanceled))) 1529 && fCanceled) 1530 { 1531 return E_ABORT; 1532 } 1533 1534 BOOL fCompleted = FALSE; 1535 if ( SUCCEEDED(pProgress->COMGETTER(Completed(&fCompleted))) 1536 && !fCompleted) 1537 { 1538 rc = pProgress->WaitForCompletion( !uTimeoutMS 1539 ? -1 /* No timeout */ 1540 : uTimeoutMS); 1541 if (FAILED(rc)) 1542 rc = setError(VBOX_E_IPRT_ERROR, 1543 tr("Waiting for guest process to end failed (%Rhrc)"), 1544 rc); 1545 } 1546 1547 if (SUCCEEDED(rc)) 1548 { 1549 ULONG uExitCode, uRetFlags; 1550 ExecuteProcessStatus_T enmStatus; 1551 HRESULT hRC = GetProcessStatus(uPID, &uExitCode, &uRetFlags, &enmStatus); 1552 if (FAILED(hRC)) 1553 return hRC; 1554 1554 1555 if (pRetStatus) 1555 *pRetStatus = curStatus;1556 *pRetStatus = enmStatus; 1556 1557 if (puRetExitCode) 1557 1558 *puRetExitCode = uExitCode; 1558 } 1559 return hRC; 1559 /** @todo Flags? */ 1560 } 1561 1562 return rc; 1560 1563 } 1561 1564 … … 2209 2212 ReturnComNotImplemented(); 2210 2213 #else /* VBOX_WITH_GUEST_CONTROL */ 2211 CheckComArgNotNull(aExitCode);2212 CheckComArgNotNull(aFlags);2213 CheckComArgNotNull(aStatus);2214 2214 2215 2215 AutoCaller autoCaller(this); … … 2224 2224 if (RT_SUCCESS(vrc)) 2225 2225 { 2226 *aExitCode = process.mExitCode; 2227 *aFlags = process.mFlags; 2228 *aStatus = process.mStatus; 2226 if (aExitCode) 2227 *aExitCode = process.mExitCode; 2228 if (aFlags) 2229 *aFlags = process.mFlags; 2230 if (aStatus) 2231 *aStatus = process.mStatus; 2229 2232 } 2230 2233 else -
trunk/src/VBox/Main/src-client/GuestCtrlImplTasks.cpp
r39475 r39487 70 70 71 71 LogFlowFuncEnter(); 72 LogFlowFunc(("Guest %p\n", pGuest));73 72 74 73 HRESULT rc = S_OK; … … 295 294 } 296 295 else 296 { 297 297 rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress, 298 298 Guest::tr("Seeking file \"%s\" failed; offset = %RU64 (%Rrc)"), 299 299 aTask->strSource.c_str(), cbTransferedTotal, vrc); 300 break; 301 } 300 302 /* Resize buffer to reflect amount we just have read. 301 303 * Size 0 is allowed! */ … … 360 362 ExecuteProcessStatus_T retStatus; 361 363 ULONG uRetExitCode; 362 rc = pGuest->executeWaitForStatusChange(uPID, 0 /* No timeout. */, 363 &retStatus, &uRetExitCode); 364 365 rc = executeWaitForExit(uPID, execProgress, 0 /* No timeout */, 366 &retStatus, &uRetExitCode); 364 367 if (FAILED(rc)) 365 368 { … … 372 375 { 373 376 rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress, 374 Guest::tr("Guest reported error %uwhile copying file \"%s\" to \"%s\""),375 uRetExitCode, aTask->strSource.c_str(), aTask->strDest.c_str());377 Guest::tr("Guest process reported error %u (status: %u) while copying file \"%s\" to \"%s\""), 378 uRetExitCode, retStatus, aTask->strSource.c_str(), aTask->strDest.c_str()); 376 379 } 377 380 } … … 592 595 RTFileClose(hFileDest); 593 596 594 if ( cbTransfered595 && (cbTransfered != lFileSize))596 {597 /*598 * Only bitch about an unexpected end of a file when there already599 * was data read from that file. If this was the very first read we can600 * be (almost) sure that this file is not meant to be read by the specified user.601 */602 rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress,603 Guest::tr("Unexpected end of file \"%s\" (%u bytes total, %u bytes transferred)"),604 aTask->strSource.c_str(), lFileSize, cbTransfered);605 }606 607 597 if (SUCCEEDED(rc)) 608 aTask->pProgress->notifyComplete(S_OK); 598 { 599 if ( cbTransfered 600 && (cbTransfered != lFileSize)) 601 { 602 /* 603 * Only bitch about an unexpected end of a file when there already 604 * was data read from that file. If this was the very first read we can 605 * be (almost) sure that this file is not meant to be read by the specified user. 606 */ 607 rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress, 608 Guest::tr("Unexpected end of file \"%s\" (%u bytes total, %u bytes transferred)"), 609 aTask->strSource.c_str(), lFileSize, cbTransfered); 610 } 611 612 if (SUCCEEDED(rc)) 613 aTask->pProgress->notifyComplete(S_OK); 614 } 609 615 } 610 616 }
Note:
See TracChangeset
for help on using the changeset viewer.