Changeset 60622 in vbox
- Timestamp:
- Apr 21, 2016 1:00:20 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 106770
- Location:
- trunk
- Files:
-
- 2 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/HostServices/GuestControlSvc.h
r57753 r60622 1 /* $Id$ */ 1 2 /** @file 2 3 * Guest control service - Common header for host service and guest clients. … … 4 5 5 6 /* 6 * Copyright (C) 2011-201 5Oracle Corporation7 * Copyright (C) 2011-2016 Oracle Corporation 7 8 * 8 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 82 83 83 84 /** 84 * Process status when executed in the guest.85 */86 enum eProcessStatus87 {88 /** Process is in an undefined state. */89 PROC_STS_UNDEFINED = 0,90 /** Process has been started. */91 PROC_STS_STARTED = 1,92 /** Process terminated normally. */93 PROC_STS_TEN = 2,94 /** Process terminated via signal. */95 PROC_STS_TES = 3,96 /** Process terminated abnormally. */97 PROC_STS_TEA = 4,98 /** Process timed out and was killed. */99 PROC_STS_TOK = 5,100 /** Process timed out and was not killed successfully. */101 PROC_STS_TOA = 6,102 /** Service/OS is stopping, process was killed. */103 PROC_STS_DWN = 7,104 /** Something went wrong (error code in flags). */105 PROC_STS_ERROR = 8106 };107 108 /** @todo r=bird: Most defines in this file needs to be scoped a little109 * better! For instance INPUT_FLAG_NONE is very generic. */110 111 /**112 * Input flags, set by the host. This is needed for113 * handling flags on the guest side.114 * Note: Has to match Main's ProcessInputFlag_* flags!115 */116 #define INPUT_FLAG_NONE 0x0117 #define INPUT_FLAG_EOF RT_BIT(0)118 119 /**120 * Guest session creation flags.121 * Only handled internally at the moment.122 */123 #define SESSIONCREATIONFLAG_NONE 0x0124 125 /**126 * Guest directory removement flags.127 * Essentially using what IPRT's RTDIRRMREC_F_128 * defines have to offer.129 */130 #define DIRREMOVE_FLAG_RECURSIVE RT_BIT(0)131 /** Delete the content of the directory and the directory itself. */132 #define DIRREMOVE_FLAG_CONTENT_AND_DIR RT_BIT(1)133 /** Only delete the content of the directory, omit the directory it self. */134 #define DIRREMOVE_FLAG_CONTENT_ONLY RT_BIT(2)135 /** Mask of valid flags. */136 #define DIRREMOVE_FLAG_VALID_MASK UINT32_C(0x00000003)137 138 /** @name EXECUTEPROCESSFLAG_XXX Guest process creation flags.139 * @note Has to match Main's ProcessCreateFlag_* flags!140 */141 #define EXECUTEPROCESSFLAG_NONE UINT32_C(0x0)142 #define EXECUTEPROCESSFLAG_WAIT_START RT_BIT(0)143 #define EXECUTEPROCESSFLAG_IGNORE_ORPHANED RT_BIT(1)144 #define EXECUTEPROCESSFLAG_HIDDEN RT_BIT(2)145 #define EXECUTEPROCESSFLAG_NO_PROFILE RT_BIT(3) /** @todo Rename to EXECUTEPROCESSFLAG_PROFILE in next API change. */146 #define EXECUTEPROCESSFLAG_WAIT_STDOUT RT_BIT(4)147 #define EXECUTEPROCESSFLAG_WAIT_STDERR RT_BIT(5)148 #define EXECUTEPROCESSFLAG_EXPAND_ARGUMENTS RT_BIT(6)149 #define EXECUTEPROCESSFLAG_UNQUOTED_ARGS RT_BIT(7)150 /** @} */151 152 /**153 * Pipe handle IDs used internally for referencing to154 * a certain pipe buffer.155 */156 #define OUTPUT_HANDLE_ID_STDOUT_DEPRECATED 0 /* Needed for VBox hosts < 4.1.0. */157 #define OUTPUT_HANDLE_ID_STDOUT 1158 #define OUTPUT_HANDLE_ID_STDERR 2159 160 /**161 * Guest path rename flags.162 * Essentially using what IPRT's RTPATHRENAME_FLAGS_163 * defines have to offer.164 */165 /** Do not replace anything. */166 #define PATHRENAME_FLAG_NO_REPLACE UINT32_C(0)167 /** This will replace attempt any target which isn't a directory. */168 #define PATHRENAME_FLAG_REPLACE RT_BIT(0)169 /** Don't allow symbolic links as part of the path. */170 #define PATHRENAME_FLAG_NO_SYMLINKS RT_BIT(1)171 /** Mask of valid flags. */172 #define PATHRENAME_FLAG_VALID_MASK UINT32_C(0x00000002)173 174 /**175 * Defines for guest process array lengths.176 */177 #define GUESTPROCESS_MAX_CMD_LEN _1K178 #define GUESTPROCESS_MAX_ARGS_LEN _1K179 #define GUESTPROCESS_MAX_ENV_LEN _64K180 #define GUESTPROCESS_MAX_USER_LEN 128181 #define GUESTPROCESS_MAX_PASSWORD_LEN 128182 #define GUESTPROCESS_MAX_DOMAIN_LEN 256183 184 /** @name Internal tools built into VBoxService which are used in order to185 * accomplish tasks host<->guest.186 * @{187 */188 #define VBOXSERVICE_TOOL_CAT "vbox_cat"189 #define VBOXSERVICE_TOOL_LS "vbox_ls"190 #define VBOXSERVICE_TOOL_RM "vbox_rm"191 #define VBOXSERVICE_TOOL_MKDIR "vbox_mkdir"192 #define VBOXSERVICE_TOOL_MKTEMP "vbox_mktemp"193 #define VBOXSERVICE_TOOL_STAT "vbox_stat"194 /** @} */195 196 /**197 * Input status, reported by the client.198 */199 enum eInputStatus200 {201 /** Input is in an undefined state. */202 INPUT_STS_UNDEFINED = 0,203 /** Input was written (partially, see cbProcessed). */204 INPUT_STS_WRITTEN = 1,205 /** Input failed with an error (see flags for rc). */206 INPUT_STS_ERROR = 20,207 /** Process has abandoned / terminated input handling. */208 INPUT_STS_TERMINATED = 21,209 /** Too much input data. */210 INPUT_STS_OVERFLOW = 30211 };212 213 /**214 85 * Structure keeping the context of a host callback. 215 86 */ -
trunk/include/VBox/err.h
r59375 r60622 4 4 5 5 /* 6 * Copyright (C) 2006-201 5Oracle Corporation6 * Copyright (C) 2006-2016 Oracle Corporation 7 7 * 8 8 * This file is part of VirtualBox Open Source Edition (OSE), as … … 2659 2659 /** A guest control object has changed its overall status. */ 2660 2660 #define VWRN_GSTCTL_OBJECTSTATE_CHANGED 6220 2661 /** Guest process is in a wrong state. */ 2662 #define VERR_GSTCTL_PROCESS_WRONG_STATE (-6221) 2663 /** Started guest process terminated with an exit code <> 0. */ 2664 #define VWRN_GSTCTL_PROCESS_EXIT_CODE 6221 2661 2665 /** @} */ 2662 2666 -
trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp
r60583 r60622 91 91 #ifdef VBOX_WITH_VBOXSERVICE_CONTROL 92 92 # include "VBoxServiceControl.h" 93 #endif 94 #ifdef VBOX_WITH_VBOXSERVICE_TOOLBOX 95 # include "VBoxServiceToolBox.h" 93 96 #endif 94 97 -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h
r59134 r60622 5 5 6 6 /* 7 * Copyright (C) 2013-201 5Oracle Corporation7 * Copyright (C) 2013-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 24 24 25 25 #include <VBox/VBoxGuestLib.h> 26 #include <VBox/GuestHost/GuestControl.h> 26 27 #include <VBox/HostServices/GuestControlSvc.h> 27 28 -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
r60583 r60622 40 40 #include "VBoxServiceInternal.h" 41 41 #include "VBoxServiceControl.h" 42 #include "VBoxServiceToolBox.h" 42 43 43 44 using namespace guestControl; -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
r60583 r60622 200 200 #endif 201 201 202 #ifdef VBOX_WITH_VBOXSERVICE_TOOLBOX203 extern bool VGSvcToolboxMain(int argc, char **argv, RTEXITCODE *prcExit);204 #endif205 206 202 #ifdef RT_OS_WINDOWS 207 203 # ifdef VBOX_WITH_GUEST_PROPS -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp
r58089 r60622 5 5 6 6 /* 7 * Copyright (C) 2012-201 5Oracle Corporation7 * Copyright (C) 2012-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 41 41 #include <VBox/VBoxGuestLib.h> 42 42 #include <VBox/version.h> 43 44 #include <VBox/GuestHost/GuestControl.h> 45 43 46 #include "VBoxServiceInternal.h" 47 #include "VBoxServiceToolBox.h" 44 48 #include "VBoxServiceUtils.h" 45 49 50 using namespace guestControl; 46 51 47 52 /********************************************************************************************************************************* … … 78 83 } VBOXSERVICETOOLBOXOUTPUTFLAG; 79 84 85 /********************************************************************************************************************************* 86 * Prototypes * 87 *********************************************************************************************************************************/ 88 static RTEXITCODE vgsvcToolboxCat(int argc, char **argv); 89 static RTEXITCODE vgsvcToolboxLs(int argc, char **argv); 90 static RTEXITCODE vgsvcToolboxRm(int argc, char **argv); 91 static RTEXITCODE vgsvcToolboxMkTemp(int argc, char **argv); 92 static RTEXITCODE vgsvcToolboxMkDir(int argc, char **argv); 93 static RTEXITCODE vgsvcToolboxStat(int argc, char **argv); 80 94 81 95 /********************************************************************************************************************************* 82 96 * Structures and Typedefs * 83 97 *********************************************************************************************************************************/ 84 /** Pointer to a handler function. */98 /** Pointer to a tool handler function. */ 85 99 typedef RTEXITCODE (*PFNHANDLER)(int , char **); 100 101 /** Definition for a specific toolbox tool. */ 102 typedef struct VBOXSERVICETOOLBOXTOOL 103 { 104 /** Friendly name of the tool. */ 105 const char *pszName; 106 /** Main handler to be invoked to use the tool. */ 107 RTEXITCODE (*pfnHandler)(int argc, char **argv); 108 /** Conversion routine to convert the tool's exit code back to an IPRT rc. Optional. */ 109 int (*pfnExitCodeConvertToRc)(RTEXITCODE rcExit); 110 } VBOXSERVICETOOLBOXTOOL, *PVBOXSERVICETOOLBOXTOOL; 111 112 static VBOXSERVICETOOLBOXTOOL s_aTools[] = 113 { 114 { VBOXSERVICE_TOOL_CAT, vgsvcToolboxCat , NULL }, 115 { VBOXSERVICE_TOOL_LS, vgsvcToolboxLs , NULL }, 116 { VBOXSERVICE_TOOL_RM, vgsvcToolboxRm , NULL }, 117 { VBOXSERVICE_TOOL_MKTEMP, vgsvcToolboxMkTemp, NULL }, 118 { VBOXSERVICE_TOOL_MKDIR, vgsvcToolboxMkDir , NULL }, 119 { VBOXSERVICE_TOOL_STAT, vgsvcToolboxStat , NULL } 120 }; 86 121 87 122 /** … … 468 503 } 469 504 470 /* If no tinput files were defined, process stdin. */505 /* If no input files were defined, process stdin. */ 471 506 if (RTListNodeIsFirst(&inputList, &inputList)) 472 507 rc = vgsvcToolboxCatOutput(hInput, hOutput); … … 478 513 vgsvcToolboxPathBufDestroy(&inputList); 479 514 480 return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 515 if (RT_FAILURE(rc)) 516 { 517 switch (rc) 518 { 519 case VERR_ACCESS_DENIED: 520 return (RTEXITCODE)VBOXSERVICETOOLBOX_CAT_EXITCODE_ACCESS_DENIED; 521 522 case VERR_FILE_NOT_FOUND: 523 return (RTEXITCODE)VBOXSERVICETOOLBOX_CAT_EXITCODE_FILE_NOT_FOUND; 524 525 case VERR_PATH_NOT_FOUND: 526 return (RTEXITCODE)VBOXSERVICETOOLBOX_CAT_EXITCODE_PATH_NOT_FOUND; 527 528 case VERR_SHARING_VIOLATION: 529 return (RTEXITCODE)VBOXSERVICETOOLBOX_CAT_EXITCODE_SHARING_VIOLATION; 530 531 default: 532 AssertMsgFailed(("Exit code for %Rrc not implemented\n", rc)); 533 break; 534 } 535 536 return RTEXITCODE_FAILURE; 537 } 538 539 return RTEXITCODE_SUCCESS; 481 540 } 482 541 … … 1403 1462 if (RT_FAILURE(rc2)) 1404 1463 { 1405 /** @todo r=bird: You can get a number of other errors here, like access denied. */1406 1464 if (!(fOutputFlags & VBOXSERVICETOOLBOXOUTPUTFLAG_PARSEABLE)) 1407 RTMsgError("Cannot stat for '%s': No such file or directory (%Rrc)\n", pNodeIt->pszName, rc); 1408 rc = VERR_FILE_NOT_FOUND; 1409 /* Do not break here -- process every element in the list 1410 * and keep failing rc. */ 1465 RTMsgError("Cannot stat for '%s': %Rrc\n", pNodeIt->pszName, rc2); 1411 1466 } 1412 1467 else … … 1416 1471 fOutputFlags, 1417 1472 &objInfo); 1418 if (RT_FAILURE(rc2))1419 rc = rc2;1420 1473 } 1474 1475 if (RT_SUCCESS(rc)) 1476 rc = rc2; 1477 /* Do not break here -- process every element in the list 1478 * and keep (initial) failing rc. */ 1421 1479 } 1422 1480 … … 1433 1491 1434 1492 vgsvcToolboxPathBufDestroy(&fileList); 1435 return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE; 1436 } 1437 1438 1439 1440 /** 1441 * Looks up the handler for the tool give by @a pszTool. 1442 * 1443 * @returns Pointer to handler function. NULL if not found. 1493 1494 if (RT_FAILURE(rc)) 1495 { 1496 switch (rc) 1497 { 1498 case VERR_ACCESS_DENIED: 1499 return (RTEXITCODE)VBOXSERVICETOOLBOX_STAT_EXITCODE_ACCESS_DENIED; 1500 1501 case VERR_FILE_NOT_FOUND: 1502 return (RTEXITCODE)VBOXSERVICETOOLBOX_STAT_EXITCODE_FILE_NOT_FOUND; 1503 1504 case VERR_PATH_NOT_FOUND: 1505 return (RTEXITCODE)VBOXSERVICETOOLBOX_STAT_EXITCODE_PATH_NOT_FOUND; 1506 1507 default: 1508 AssertMsgFailed(("Exit code for %Rrc not implemented\n", rc)); 1509 break; 1510 } 1511 1512 return RTEXITCODE_FAILURE; 1513 } 1514 1515 return RTEXITCODE_SUCCESS; 1516 } 1517 1518 1519 /** 1520 * Looks up the tool definition entry for the tool give by @a pszTool. 1521 * 1522 * @returns Pointer to the tool definition. NULL if not found. 1444 1523 * @param pszTool The name of the tool. 1445 1524 */ 1446 static PFNHANDLER vgsvcToolboxLookUpHandler(const char *pszTool) 1447 { 1448 static struct 1449 { 1450 const char *pszName; 1451 RTEXITCODE (*pfnHandler)(int argc, char **argv); 1452 } 1453 const s_aTools[] = 1454 { 1455 { "cat", vgsvcToolboxCat }, 1456 { "ls", vgsvcToolboxLs }, 1457 { "rm", vgsvcToolboxRm }, 1458 { "mktemp", vgsvcToolboxMkTemp }, 1459 { "mkdir", vgsvcToolboxMkDir }, 1460 { "stat", vgsvcToolboxStat }, 1461 }; 1462 1463 /* Skip optional 'vbox_' prefix. */ 1464 if ( pszTool[0] == 'v' 1465 && pszTool[1] == 'b' 1466 && pszTool[2] == 'o' 1467 && pszTool[3] == 'x' 1468 && pszTool[4] == '_') 1469 pszTool += 5; 1525 static PVBOXSERVICETOOLBOXTOOL const vgsvcToolboxLookUp(const char *pszTool) 1526 { 1527 AssertPtrReturn(pszTool, NULL); 1470 1528 1471 1529 /* Do a linear search, since we don't have that much stuff in the table. */ 1472 1530 for (unsigned i = 0; i < RT_ELEMENTS(s_aTools); i++) 1473 1531 if (!strcmp(s_aTools[i].pszName, pszTool)) 1474 return s_aTools[i].pfnHandler;1532 return &s_aTools[i]; 1475 1533 1476 1534 return NULL; 1535 } 1536 1537 1538 /** 1539 * Converts a tool's exit code back to an IPRT error code. 1540 * 1541 * @return Converted IPRT status code. 1542 * @param pszTool Name of the toolbox tool to convert exit code for. 1543 * @param rcExit The tool's exit code to convert. 1544 */ 1545 int VGSvcToolboxExitCodeConvertToRc(const char *pszTool, RTEXITCODE rcExit) 1546 { 1547 AssertPtrReturn(pszTool, VERR_INVALID_POINTER); 1548 1549 PVBOXSERVICETOOLBOXTOOL pTool = vgsvcToolboxLookUp(pszTool); 1550 if (pTool) 1551 return pTool->pfnExitCodeConvertToRc(rcExit); 1552 1553 AssertMsgFailed(("Tool '%s' not found\n", pszTool)); 1554 return VERR_GENERAL_FAILURE; /* Lookup failed, should not happen. */ 1477 1555 } 1478 1556 … … 1494 1572 */ 1495 1573 AssertReturn(argc > 0, false); 1496 const char *pszTool= RTPathFilename(argv[0]);1497 P FNHANDLER pfnHandler = vgsvcToolboxLookUpHandler(pszTool);1498 if (!p fnHandler)1574 const char *pszTool = RTPathFilename(argv[0]); 1575 PVBOXSERVICETOOLBOXTOOL pTool = vgsvcToolboxLookUp(pszTool); 1576 if (!pTool) 1499 1577 { 1500 1578 /* … … 1507 1585 argv += 2; 1508 1586 pszTool = argv[0]; 1509 p fnHandler = vgsvcToolboxLookUpHandler(pszTool);1510 if (!p fnHandler)1587 pTool = vgsvcToolboxLookUp(pszTool); 1588 if (!pTool) 1511 1589 { 1512 1590 *prcExit = RTEXITCODE_SUCCESS; … … 1528 1606 */ 1529 1607 RTMsgSetProgName("VBoxService/%s", pszTool); 1530 *prcExit = pfnHandler(argc, argv); 1608 AssertPtr(pTool); 1609 *prcExit = pTool->pfnHandler(argc, argv); 1531 1610 1532 1611 return true; -
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r59747 r60622 5 5 6 6 /* 7 * Copyright (C) 2011-201 5Oracle Corporation7 * Copyright (C) 2011-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 38 38 39 39 #ifdef VBOX_WITH_GUEST_CONTROL 40 # include <VBox/GuestHost/GuestControl.h> 40 41 # include <VBox/HostServices/GuestControlSvc.h> 41 42 using namespace guestControl; … … 702 703 GuestProcessStartupInfo(void) 703 704 : mFlags(ProcessCreateFlag_None), 704 mTimeoutMS( 30 * 1000 /* 30stimeout by default */),705 mTimeoutMS(UINT32_MAX /* No timeout by default */), 705 706 mPriority(ProcessPriority_Default) { } 706 707 … … 715 716 /** Process creation flags. */ 716 717 uint32_t mFlags; 718 /** Timeout (in ms) the process is allowed to run. 719 * Specify UINT32_MAX if no timeout (unlimited run time) is given. */ 717 720 ULONG mTimeoutMS; 718 721 /** Process priority. */ -
trunk/src/VBox/Main/include/GuestDirectoryImpl.h
r51556 r60622 5 5 6 6 /* 7 * Copyright (C) 2012-201 4Oracle Corporation7 * Copyright (C) 2012-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 73 73 /** The directory's ID. */ 74 74 uint32_t mID; 75 /** The process tool instance to use. */ 75 76 GuestProcessTool mProcessTool; 76 77 } mData; -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r58521 r60622 5 5 6 6 /* 7 * Copyright (C) 2012-201 4Oracle Corporation7 * Copyright (C) 2012-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 184 184 185 185 /** 186 * Internal class for handling a VBoxService tool ("vbox_ls", vbox_stat", ...). 186 * Structure for keeping a VBoxService toolbox tool's error info around. 187 */ 188 struct GuestProcessToolErrorInfo 189 { 190 /** Return code from the guest side for executing the process tool. */ 191 int guestRc; 192 /** The process tool's returned exit code. */ 193 LONG lExitCode; 194 }; 195 196 /** 197 * Internal class for handling the BusyBox-like tools built into VBoxService 198 * on the guest side. It's also called the VBoxService Toolbox (tm). 199 * 200 * Those initially were necessary to guarantee execution of commands (like "ls", "cat") 201 * under the behalf of a certain guest user. 202 * 203 * This class essentially helps to wrap all the gory details like process creation, 204 * information extraction and maintaining the overall status. 187 205 */ 188 206 class GuestProcessTool … … 198 216 int Init(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, bool fAsync, int *pGuestRc); 199 217 218 int i_getCurrentBlock(uint32_t uHandle, GuestProcessStreamBlock &strmBlock); 219 220 int i_getRc(void) const; 221 200 222 GuestProcessStream &i_getStdOut(void) { return mStdOut; } 201 223 … … 206 228 int i_waitEx(uint32_t fFlags, GuestProcessStreamBlock *pStreamBlock, int *pGuestRc); 207 229 208 int i_getCurrentBlock(uint32_t uHandle, GuestProcessStreamBlock &strmBlock);209 210 230 bool i_isRunning(void); 211 231 232 int i_terminatedOk(LONG *plExitCode = NULL); 233 234 int i_terminate(uint32_t uTimeoutMS, int *pGuestRc); 235 236 public: 237 212 238 static int i_run(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, int *pGuestRc); 239 240 static int i_runErrorInfo(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, GuestProcessToolErrorInfo &errorInfo); 213 241 214 242 static int i_runEx(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, 215 243 GuestCtrlStreamObjects *pStrmOutObjects, uint32_t cStrmOutObjects, int *pGuestRc); 216 244 217 int i_terminatedOk(LONG *pExitCode); 218 219 int i_terminate(uint32_t uTimeoutMS, int *pGuestRc); 245 static int i_runExErrorInfo(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, 246 GuestCtrlStreamObjects *pStrmOutObjects, uint32_t cStrmOutObjects, GuestProcessToolErrorInfo &errorInfo); 247 248 static int i_exitCodeToRc(const GuestProcessStartupInfo &startupInfo, LONG lExitCode); 249 250 static int i_exitCodeToRc(const char *pszTool, LONG lExitCode); 220 251 221 252 protected: -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r58521 r60622 5 5 6 6 /* 7 * Copyright (C) 2006-201 4Oracle Corporation7 * Copyright (C) 2006-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 600 600 hr = E_OUTOFMEMORY; 601 601 } 602 catch( HRESULT eHR)602 catch(...) 603 603 { 604 LogFlowThisFunc(("Exception was caught in the function 604 LogFlowThisFunc(("Exception was caught in the function\n")); 605 605 } 606 606 } 607 607 } 608 609 LogFlowFunc(("Returning hr=%Rhrc\n", hr)); 608 610 return hr; 609 611 #endif /* VBOX_WITH_GUEST_CONTROL */ -
trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp
r57358 r60622 5 5 6 6 /* 7 * Copyright (C) 2012-201 5Oracle Corporation7 * Copyright (C) 2012-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 322 322 && !mData.mProcessTool.i_isRunning()) 323 323 { 324 rc = mData.mProcessTool.i_terminatedOk(NULL /* Exit code */); 325 if (rc == VERR_NOT_EQUAL) 326 rc = VERR_ACCESS_DENIED; 324 rc = mData.mProcessTool.i_terminatedOk(); 327 325 } 328 326 … … 373 371 break; 374 372 375 case V ERR_ACCESS_DENIED:376 hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Unable to read / access denied"),377 mData.mOpenInfo.mPath.c_str() );373 case VWRN_GSTCTL_PROCESS_EXIT_CODE: 374 hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: %Rrc"), 375 mData.mOpenInfo.mPath.c_str(), mData.mProcessTool.i_getRc()); 378 376 break; 379 377 -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r58552 r60622 5 5 6 6 /* 7 * Copyright (C) 2012-201 5Oracle Corporation7 * Copyright (C) 2012-2016 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 543 543 break; 544 544 545 case VERR_NOT_EQUAL: /** @todo Imprecise to the user; can mean anything and all. */546 strError += Utf8StrFmt(tr("Unable to retrieve requested information"));547 break;548 549 545 case VERR_NOT_FOUND: 550 546 strError += Utf8StrFmt(tr("The guest execution service is not ready (yet)")); … … 1950 1946 int vrc = pSession->i_processCreateExInternal(mStartupInfo, pProcess); 1951 1947 if (RT_SUCCESS(vrc)) 1948 { 1949 int guestRc; 1952 1950 vrc = fAsync 1953 1951 ? pProcess->i_startProcessAsync() 1954 : pProcess->i_startProcess(30 * 1000 /* 30s timeout */, pGuestRc); 1955 1956 if ( RT_SUCCESS(vrc) 1957 && !fAsync 1958 && ( pGuestRc 1959 && RT_FAILURE(*pGuestRc) 1952 : pProcess->i_startProcess(30 * 1000 /* 30s timeout */, &guestRc); 1953 1954 if ( RT_SUCCESS(vrc) 1955 && !fAsync 1956 && RT_FAILURE(guestRc) 1960 1957 ) 1961 ) 1962 { 1963 vrc = VERR_GSTCTL_GUEST_ERROR; 1958 { 1959 if (pGuestRc) 1960 *pGuestRc = guestRc; 1961 vrc = VERR_GSTCTL_GUEST_ERROR; 1962 } 1964 1963 } 1965 1964 … … 1993 1992 } 1994 1993 1994 int GuestProcessTool::i_getRc(void) const 1995 { 1996 LONG exitCode; 1997 HRESULT hr = pProcess->COMGETTER(ExitCode(&exitCode)); 1998 Assert(SUCCEEDED(hr)); 1999 2000 return GuestProcessTool::i_exitCodeToRc(mStartupInfo, exitCode); 2001 } 2002 1995 2003 bool GuestProcessTool::i_isRunning(void) 1996 2004 { … … 2012 2020 2013 2021 /* static */ 2014 int GuestProcessTool::i_run( GuestSession *pGuestSession, 2015 const GuestProcessStartupInfo &startupInfo, 2016 int *pGuestRc) 2017 { 2018 return i_runEx(pGuestSession, startupInfo, 2019 NULL /* pStrmOutObjects */, 0 /* cStrmOutObjects */, 2020 pGuestRc); 2022 int GuestProcessTool::i_run( GuestSession *pGuestSession, 2023 const GuestProcessStartupInfo &startupInfo, 2024 int *pGuestRc /* = NULL */) 2025 { 2026 int guestRc; 2027 2028 GuestProcessToolErrorInfo errorInfo; 2029 int vrc = i_runErrorInfo(pGuestSession, startupInfo, errorInfo); 2030 if (RT_SUCCESS(vrc)) 2031 { 2032 if (errorInfo.guestRc == VWRN_GSTCTL_PROCESS_EXIT_CODE) 2033 { 2034 guestRc = GuestProcessTool::i_exitCodeToRc(startupInfo, errorInfo.lExitCode); 2035 } 2036 else 2037 guestRc = errorInfo.guestRc; 2038 2039 if (pGuestRc) 2040 *pGuestRc = guestRc; 2041 } 2042 2043 return vrc; 2044 } 2045 2046 /* static */ 2047 int GuestProcessTool::i_runErrorInfo( GuestSession *pGuestSession, 2048 const GuestProcessStartupInfo &startupInfo, 2049 GuestProcessToolErrorInfo &errorInfo) 2050 { 2051 return i_runExErrorInfo(pGuestSession, startupInfo, 2052 NULL /* pStrmOutObjects */, 0 /* cStrmOutObjects */, 2053 errorInfo); 2054 } 2055 2056 /* static */ 2057 int GuestProcessTool::i_runEx( GuestSession *pGuestSession, 2058 const GuestProcessStartupInfo &startupInfo, 2059 GuestCtrlStreamObjects *pStrmOutObjects, 2060 uint32_t cStrmOutObjects, 2061 int *pGuestRc /* = NULL */) 2062 { 2063 int guestRc; 2064 2065 GuestProcessToolErrorInfo errorInfo; 2066 int vrc = GuestProcessTool::i_runExErrorInfo(pGuestSession, startupInfo, pStrmOutObjects, cStrmOutObjects, errorInfo); 2067 if (RT_SUCCESS(vrc)) 2068 { 2069 if (errorInfo.guestRc == VWRN_GSTCTL_PROCESS_EXIT_CODE) 2070 { 2071 guestRc = GuestProcessTool::i_exitCodeToRc(startupInfo, errorInfo.lExitCode); 2072 } 2073 else 2074 guestRc = errorInfo.guestRc; 2075 2076 if (pGuestRc) 2077 *pGuestRc = guestRc; 2078 } 2079 2080 return vrc; 2021 2081 } 2022 2082 … … 2030 2090 */ 2031 2091 /* static */ 2032 int GuestProcessTool::i_runEx ( GuestSession*pGuestSession,2033 const GuestProcessStartupInfo&startupInfo,2034 GuestCtrlStreamObjects*pStrmOutObjects,2035 uint32_tcStrmOutObjects,2036 int *pGuestRc)2092 int GuestProcessTool::i_runExErrorInfo( GuestSession *pGuestSession, 2093 const GuestProcessStartupInfo &startupInfo, 2094 GuestCtrlStreamObjects *pStrmOutObjects, 2095 uint32_t cStrmOutObjects, 2096 GuestProcessToolErrorInfo &errorInfo) 2037 2097 { 2038 2098 GuestProcessTool procTool; 2039 int guestRc; 2040 int vrc = procTool.Init(pGuestSession, startupInfo, false /* Async */, &guestRc); 2099 int vrc = procTool.Init(pGuestSession, startupInfo, false /* Async */, &errorInfo.guestRc); 2041 2100 if (RT_SUCCESS(vrc)) 2042 2101 { … … 2048 2107 vrc = procTool.i_waitEx( pStrmOutObjects 2049 2108 ? GUESTPROCESSTOOL_FLAG_STDOUT_BLOCK 2050 : GUESTPROCESSTOOL_FLAG_NONE, &strmBlk, & guestRc);2109 : GUESTPROCESSTOOL_FLAG_NONE, &strmBlk, &errorInfo.guestRc); 2051 2110 if (pStrmOutObjects) 2052 2111 pStrmOutObjects->push_back(strmBlk); … … 2062 2121 { 2063 2122 /* Make sure the process runs until completion. */ 2064 vrc = procTool.i_wait(GUESTPROCESSTOOL_FLAG_NONE, & guestRc);2123 vrc = procTool.i_wait(GUESTPROCESSTOOL_FLAG_NONE, &errorInfo.guestRc); 2065 2124 if (RT_SUCCESS(vrc)) 2066 { 2067 guestRc = procTool.i_terminatedOk(NULL /* Exit code */); 2068 if (RT_FAILURE(guestRc)) 2069 vrc = VERR_GSTCTL_GUEST_ERROR; 2070 } 2071 } 2072 2073 if (pGuestRc) 2074 *pGuestRc = guestRc; 2075 2076 LogFlowFunc(("Returned rc=%Rrc, guestRc=%Rrc\n", vrc, guestRc)); 2125 errorInfo.guestRc = procTool.i_terminatedOk(&errorInfo.lExitCode); 2126 } 2127 2128 LogFlowFunc(("Returned rc=%Rrc, guestRc=%Rrc, exitCode=%ld\n", vrc, errorInfo.guestRc, errorInfo.lExitCode)); 2077 2129 return vrc; 2078 2130 } 2079 2131 2080 int GuestProcessTool::i_terminatedOk(LONG *pExitCode) 2132 /** 2133 * Reports if the tool has been run correctly. 2134 * 2135 * @return Will return VWRN_GSTCTL_PROCESS_EXIT_CODE if the tool process returned an exit code <> 0, 2136 * VERR_GSTCTL_PROCESS_WRONG_STATE if the tool process is in a wrong state (e.g. still running), 2137 * or VINF_SUCCESS otherwise. 2138 * 2139 * @param plExitCode Exit code of the tool. Optional. 2140 */ 2141 int GuestProcessTool::i_terminatedOk(LONG *plExitCode /* = NULL */) 2081 2142 { 2082 2143 Assert(!pProcess.isNull()); … … 2086 2147 if (!i_isRunning()) 2087 2148 { 2088 LONG exitCode;2089 HRESULT hr = pProcess->COMGETTER(ExitCode(& exitCode));2149 LONG lExitCode; 2150 HRESULT hr = pProcess->COMGETTER(ExitCode(&lExitCode)); 2090 2151 Assert(SUCCEEDED(hr)); 2091 2152 2092 if (pExitCode) 2093 *pExitCode = exitCode; 2094 2095 vrc = (exitCode != 0) 2096 /** @todo Special guest control rc needed! */ 2097 ? VERR_NOT_EQUAL : VINF_SUCCESS; 2153 if (plExitCode) 2154 *plExitCode = lExitCode; 2155 2156 vrc = (lExitCode != 0) 2157 ? VWRN_GSTCTL_PROCESS_EXIT_CODE : VINF_SUCCESS; 2098 2158 } 2099 2159 else 2100 vrc = VERR_ INVALID_STATE; /** @todo Special guest control rc needed! */2160 vrc = VERR_GSTCTL_PROCESS_WRONG_STATE; 2101 2161 2102 2162 LogFlowFuncLeaveRC(vrc); … … 2315 2375 } 2316 2376 2377 /** 2378 * Converts a toolbox tool's exit code to an IPRT error code. 2379 * 2380 * @return int Returned IPRT error for the particular tool. 2381 * @param startupInfo Startup info of the toolbox tool to lookup error code for. 2382 * @param lExitCode The toolbox tool's exit code to lookup IPRT error for. 2383 */ 2384 /* static */ 2385 int GuestProcessTool::i_exitCodeToRc(const GuestProcessStartupInfo &startupInfo, LONG lExitCode) 2386 { 2387 if (startupInfo.mArguments.size() == 0) 2388 { 2389 AssertFailed(); 2390 return VERR_GENERAL_FAILURE; /* Should not happen. */ 2391 } 2392 2393 return i_exitCodeToRc(startupInfo.mArguments[0].c_str(), lExitCode); 2394 } 2395 2396 /** 2397 * Converts a toolbox tool's exit code to an IPRT error code. 2398 * 2399 * @return int Returned IPRT error for the particular tool. 2400 * @param pszTool Name of toolbox tool to lookup error code for. 2401 * @param rcExit The toolbox tool's exit code to lookup IPRT error for. 2402 */ 2403 /* static */ 2404 int GuestProcessTool::i_exitCodeToRc(const char *pszTool, LONG lExitCode) 2405 { 2406 AssertPtrReturn(pszTool, VERR_INVALID_POINTER); 2407 2408 LogFlowFunc(("%s: %ld\n", pszTool, lExitCode)); 2409 2410 if (lExitCode == 0) /* No error? Bail out early. */ 2411 return VINF_SUCCESS; 2412 2413 if (!RTStrICmp(pszTool, VBOXSERVICE_TOOL_CAT)) 2414 { 2415 switch (lExitCode) 2416 { 2417 case VBOXSERVICETOOLBOX_CAT_EXITCODE_ACCESS_DENIED: return VERR_ACCESS_DENIED; 2418 case VBOXSERVICETOOLBOX_CAT_EXITCODE_FILE_NOT_FOUND: return VERR_FILE_NOT_FOUND; 2419 case VBOXSERVICETOOLBOX_CAT_EXITCODE_PATH_NOT_FOUND: return VERR_PATH_NOT_FOUND; 2420 case VBOXSERVICETOOLBOX_CAT_EXITCODE_SHARING_VIOLATION: return VERR_SHARING_VIOLATION; 2421 default: 2422 break; 2423 } 2424 } 2425 else if (!RTStrICmp(pszTool, VBOXSERVICE_TOOL_STAT)) 2426 { 2427 switch (lExitCode) 2428 { 2429 case VBOXSERVICETOOLBOX_STAT_EXITCODE_ACCESS_DENIED: return VERR_ACCESS_DENIED; 2430 case VBOXSERVICETOOLBOX_STAT_EXITCODE_FILE_NOT_FOUND: return VERR_FILE_NOT_FOUND; 2431 case VBOXSERVICETOOLBOX_STAT_EXITCODE_PATH_NOT_FOUND: return VERR_PATH_NOT_FOUND; 2432 default: 2433 break; 2434 } 2435 } 2436 2437 AssertMsgFailed(("Error code %ld for tool '%s' not handled\n", lExitCode, pszTool)); 2438 return VERR_GENERAL_FAILURE; 2439 } 2440 -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r60494 r60622 589 589 int GuestSession::i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc) 590 590 { 591 AssertPtrReturn(pGuestRc, VERR_INVALID_POINTER); 592 591 593 LogFlowThisFunc(("uFlags=%x, uTimeoutMS=%RU32\n", uFlags, uTimeoutMS)); 592 594 … … 651 653 652 654 int GuestSession::i_directoryCreateInternal(const Utf8Str &strPath, uint32_t uMode, 653 uint32_t uFlags, int *pGuestRc) 654 { 655 LogFlowThisFunc(("strPath=%s, uMode=%x, uFlags=%x\n", 656 strPath.c_str(), uMode, uFlags)); 655 uint32_t uFlags, int *pGuestRc) 656 { 657 AssertPtrReturn(pGuestRc, VERR_INVALID_POINTER); 658 659 LogFlowThisFunc(("strPath=%s, uMode=%x, uFlags=%x\n", strPath.c_str(), uMode, uFlags)); 657 660 658 661 int vrc = VINF_SUCCESS; … … 717 720 GuestFsObjData &objData, int *pGuestRc) 718 721 { 719 LogFlowThisFunc(("strPath=%s fFollowSymlinks=%RTbool\n", strPath.c_str(), fFollowSymlinks)); 722 AssertPtrReturn(pGuestRc, VERR_INVALID_POINTER); 723 724 LogFlowThisFunc(("strPath=%s, fFollowSymlinks=%RTbool\n", strPath.c_str(), fFollowSymlinks)); 720 725 721 726 int vrc = i_fsQueryInfoInternal(strPath, fFollowSymlinks, objData, pGuestRc); … … 732 737 int GuestSession::i_directoryRemoveFromList(GuestDirectory *pDirectory) 733 738 { 739 AssertPtrReturn(pDirectory, VERR_INVALID_POINTER); 740 734 741 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 735 742 … … 773 780 { 774 781 AssertReturn(!(uFlags & ~DIRREMOVE_FLAG_VALID_MASK), VERR_INVALID_PARAMETER); 782 AssertPtrReturn(pGuestRc, VERR_INVALID_POINTER); 775 783 776 784 LogFlowThisFunc(("strPath=%s, uFlags=0x%x\n", strPath.c_str(), uFlags)); … … 812 820 bool fDirectory, Utf8Str &strName, int *pGuestRc) 813 821 { 822 AssertPtrReturn(pGuestRc, VERR_INVALID_POINTER); 823 814 824 LogFlowThisFunc(("strTemplate=%s, strPath=%s, fDirectory=%RTbool\n", 815 825 strTemplate.c_str(), strPath.c_str(), fDirectory)); … … 878 888 ComObjPtr<GuestDirectory> &pDirectory, int *pGuestRc) 879 889 { 890 AssertPtrReturn(pGuestRc, VERR_INVALID_POINTER); 891 880 892 LogFlowThisFunc(("strPath=%s, strPath=%s, uFlags=%x\n", 881 893 openInfo.mPath.c_str(), openInfo.mFilter.c_str(), openInfo.mFlags)); … … 1429 1441 *pGuestRc = guestRc; 1430 1442 1431 LogFlowThisFunc(("Returning rc=%Rrc, guestRc=%Rrc\n", 1432 vrc, guestRc)); 1443 LogFlowThisFunc(("Returning rc=%Rrc, guestRc=%Rrc\n", vrc, guestRc)); 1433 1444 return vrc; 1434 1445 } … … 1482 1493 case VERR_MAX_PROCS_REACHED: 1483 1494 strError += Utf8StrFmt(tr("Maximum number of concurrent guest processes has been reached")); 1484 break;1485 1486 case VERR_NOT_EQUAL: /** @todo Imprecise to the user; can mean anything and all. */1487 strError += Utf8StrFmt(tr("Unable to retrieve requested information"));1488 1495 break; 1489 1496 … … 1935 1942 } 1936 1943 1937 /* Adjust timeout. If set to 0, we define1938 * an infinite timeout. */1944 /* Adjust timeout. 1945 * If set to 0, we define an infinite timeout (unlimited process run time). */ 1939 1946 if (procInfo.mTimeoutMS == 0) 1940 1947 procInfo.mTimeoutMS = UINT32_MAX; … … 2650 2657 { 2651 2658 case VERR_GSTCTL_GUEST_ERROR: 2652 /** @todo Handle VERR_NOT_EQUAL (meaning process exit code <> 0). */2653 hr = setError(VBOX_E_IPRT_ERROR, tr("Directory creation failed: Could not create directory"));2659 hr = setError(VBOX_E_IPRT_ERROR, tr("Directory creation failed: %s", 2660 GuestDirectory::i_guestErrorToString(guestRc).c_str())); 2654 2661 break; 2655 2662 -
trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp
r60494 r60622 297 297 int rc; 298 298 299 RTMSINTERVAL msTimeout = 30 * 1000; /** @todo 30s timeout for all actions. Make this configurable? */ 300 299 301 RTFILE fileLocal; 300 302 PRTFILE pFile = &fileLocal; … … 338 340 } 339 341 342 /* 343 * Query information about our destination first. 344 */ 345 int guestRc; 346 if (RT_SUCCESS(rc)) 347 { 348 GuestFsObjData objData; 349 rc = pSession->i_directoryQueryInfoInternal(mDest, true /* fFollowSymlinks */, objData, &guestRc); 350 if (RT_SUCCESS(rc)) 351 { 352 mDest = Utf8StrFmt("%s/%s", mDest.c_str(), RTPathFilename(mSource.c_str())); 353 } 354 else if (rc == VERR_NOT_A_DIRECTORY) 355 { 356 rc = VINF_SUCCESS; 357 } 358 } 359 360 /** @todo Implement sparse file support? */ 361 362 /* 363 * Start the actual copying process by cat'ing the source file to the 364 * destination file on the guest. 365 */ 340 366 GuestProcessStartupInfo procInfo; 341 367 procInfo.mExecutable = Utf8Str(VBOXSERVICE_TOOL_CAT); … … 347 373 348 374 /* Startup process. */ 349 ComObjPtr<GuestProcess> pProcess; int guestRc;375 ComObjPtr<GuestProcess> pProcess; 350 376 if (RT_SUCCESS(rc)) 351 377 rc = pSession->i_processCreateExInternal(procInfo, pProcess); … … 353 379 { 354 380 Assert(!pProcess.isNull()); 355 rc = pProcess->i_startProcess(30 * 1000 /* 30s timeout */, 356 &guestRc); 381 rc = pProcess->i_startProcess(msTimeout, &guestRc); 357 382 } 358 383 … … 370 395 Utf8StrFmt(GuestSession::tr( 371 396 "Error while creating guest process for copying file \"%s\" from guest to host: %Rrc"), 372 397 mSource.c_str(), rc)); 373 398 break; 374 399 } … … 386 411 for (;;) 387 412 { 388 rc = pProcess->i_waitFor(ProcessWaitForFlag_StdIn, 389 30 * 1000 /* Timeout */, waitRes, &guestRc); 413 rc = pProcess->i_waitFor(ProcessWaitForFlag_StdIn, msTimeout, waitRes, &guestRc); 390 414 if ( RT_FAILURE(rc) 391 415 || ( waitRes != ProcessWaitResult_StdIn … … 418 442 { 419 443 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 420 Utf8StrFmt(GuestSession::tr("Could not read from file \"%s\" (%Rrc)"),444 Utf8StrFmt(GuestSession::tr("Could not read from host file \"%s\" (%Rrc)"), 421 445 mSource.c_str(), rc)); 422 446 break; … … 426 450 { 427 451 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 428 Utf8StrFmt(GuestSession::tr("Seeking file \"%s\" to offset %RU64 failed: %Rrc"),452 Utf8StrFmt(GuestSession::tr("Seeking host file \"%s\" to offset %RU64 failed: %Rrc"), 429 453 mSource.c_str(), cbWrittenTotal, rc)); 430 454 break; … … 452 476 rc = pProcess->i_writeData(0 /* StdIn */, fFlags, 453 477 byBuf, cbRead, 454 30 * 1000 /* Timeout */, &cbWritten, &guestRc);478 msTimeout, &cbWritten, &guestRc); 455 479 if (RT_FAILURE(rc)) 456 480 { … … 464 488 default: 465 489 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 466 Utf8StrFmt(GuestSession::tr("Writing to file \"%s\" (offset %RU64) failed: %Rrc"),490 Utf8StrFmt(GuestSession::tr("Writing to guest file \"%s\" (offset %RU64) failed: %Rrc"), 467 491 mDest.c_str(), cbWrittenTotal, rc)); 468 492 break; … … 503 527 rc, cbToRead, cbWrittenTotal, mSourceSize)); 504 528 529 /* 530 * Wait on termination of guest process until it completed all operations. 531 */ 505 532 if ( !fCanceled 506 533 || RT_SUCCESS(rc)) 507 534 { 535 rc = pProcess->i_waitFor(ProcessWaitForFlag_Terminate, msTimeout, waitRes, &guestRc); 536 if ( RT_FAILURE(rc) 537 || waitRes != ProcessWaitResult_Terminate) 538 { 539 if (RT_FAILURE(rc)) 540 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 541 Utf8StrFmt( 542 GuestSession::tr("Waiting on termination for copying file \"%s\" to guest failed: %Rrc"), 543 mSource.c_str(), rc)); 544 else 545 { 546 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 547 Utf8StrFmt(GuestSession::tr( 548 "Waiting on termination for copying file \"%s\" to guest failed with wait result %ld"), 549 mSource.c_str(), waitRes)); 550 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 551 } 552 } 553 } 554 555 if (RT_SUCCESS(rc)) 556 { 557 /* 558 * Newer VBoxService toolbox versions report what went wrong via exit code. 559 * So handle this first. 560 */ 561 ProcessStatus_T procStatus; 562 LONG exitCode; 563 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 564 && procStatus != ProcessStatus_TerminatedNormally) 565 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 566 && exitCode != 0) 567 ) 568 { 569 LogFlowThisFunc(("procStatus=%ld, exitCode=%ld\n", procStatus, exitCode)); 570 rc = GuestProcessTool::i_exitCodeToRc(procInfo, exitCode); 571 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 572 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" to guest failed: %Rrc"), 573 mSource.c_str(), rc)); 574 } 508 575 /* 509 576 * Even if we succeeded until here make sure to check whether we really transfered 510 577 * everything. 511 578 */ 512 if ( mSourceSize > 0513 && cbWrittenTotal == 0)579 else if ( mSourceSize > 0 580 && cbWrittenTotal == 0) 514 581 { 515 582 /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write 516 583 * to the destination -> access denied. */ 517 584 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 518 Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to \"%s\""),585 Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to guest \"%s\""), 519 586 mSource.c_str(), mDest.c_str())); 520 rc = VERR_ GENERAL_FAILURE; /* Fudge. */587 rc = VERR_ACCESS_DENIED; 521 588 } 522 589 else if (cbWrittenTotal < mSourceSize) … … 524 591 /* If we did not copy all let the user know. */ 525 592 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 526 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed (%RU64/%RU64 bytes transfered)"),593 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" to guest failed (%RU64/%RU64 bytes transfered)"), 527 594 mSource.c_str(), cbWrittenTotal, mSourceSize)); 528 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 529 } 530 else 531 { 532 rc = pProcess->i_waitFor(ProcessWaitForFlag_Terminate, 533 30 * 1000 /* Timeout */, waitRes, &guestRc); 534 if ( RT_FAILURE(rc) 535 || waitRes != ProcessWaitResult_Terminate) 536 { 537 if (RT_FAILURE(rc)) 538 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 539 Utf8StrFmt( 540 GuestSession::tr("Waiting on termination for copying file \"%s\" failed: %Rrc"), 541 mSource.c_str(), rc)); 542 else 543 { 544 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 545 Utf8StrFmt(GuestSession::tr( 546 "Waiting on termination for copying file \"%s\" failed with wait result %ld"), 547 mSource.c_str(), waitRes)); 548 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 549 } 550 } 551 552 if (RT_SUCCESS(rc)) 553 { 554 ProcessStatus_T procStatus; 555 LONG exitCode; 556 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 557 && procStatus != ProcessStatus_TerminatedNormally) 558 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 559 && exitCode != 0) 560 ) 561 { 562 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 563 Utf8StrFmt(GuestSession::tr( 564 "Copying file \"%s\" failed with status %ld, exit code %ld"), 565 mSource.c_str(), procStatus, exitCode)); /**@todo Add stringify methods! */ 566 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 567 } 568 } 569 570 571 if (RT_SUCCESS(rc)) 572 rc = setProgressSuccess(); 573 } 595 rc = VERR_INTERRUPTED; 596 } 597 598 if (RT_SUCCESS(rc)) 599 rc = setProgressSuccess(); 574 600 } 575 601 } /* processCreateExInteral */ … … 632 658 AutoCaller autoCaller(pSession); 633 659 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 660 661 RTMSINTERVAL msTimeout = 30 * 1000; /** @todo 30s timeout for all actions. Make this configurable? */ 634 662 635 663 /* … … 651 679 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 652 680 Utf8StrFmt(GuestSession::tr("Object \"%s\" on the guest is not a file"), mSource.c_str())); 653 rc = VERR_ GENERAL_FAILURE; /* Fudge. */681 rc = VERR_NOT_A_FILE; 654 682 } 655 683 … … 662 690 { 663 691 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 664 Utf8StrFmt(GuestSession::tr(" Error opening destination file \"%s\": %Rrc"),692 Utf8StrFmt(GuestSession::tr("Opening/creating destination file on host \"%s\" failed: %Rrc"), 665 693 mDest.c_str(), rc)); 666 694 } … … 681 709 rc = pSession->i_processCreateExInternal(procInfo, pProcess); 682 710 if (RT_SUCCESS(rc)) 683 rc = pProcess->i_startProcess(30 * 1000 /* 30s timeout */, 684 &guestRc); 711 rc = pProcess->i_startProcess(msTimeout, &guestRc); 685 712 if (RT_FAILURE(rc)) 686 713 { … … 688 715 { 689 716 case VERR_GSTCTL_GUEST_ERROR: 690 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 691 GuestProcess::i_guestErrorToString(guestRc)); 717 setProgressErrorMsg(VBOX_E_IPRT_ERROR, GuestProcess::i_guestErrorToString(guestRc)); 692 718 break; 693 719 … … 696 722 Utf8StrFmt(GuestSession::tr( 697 723 "Error while creating guest process for copying file \"%s\" from guest to host: %Rrc"), 698 724 mSource.c_str(), rc)); 699 725 break; 700 726 } … … 711 737 for (;;) 712 738 { 713 rc = pProcess->i_waitFor(ProcessWaitForFlag_StdOut, 714 30 * 1000 /* Timeout */, waitRes, &guestRc); 739 rc = pProcess->i_waitFor(ProcessWaitForFlag_StdOut, msTimeout, waitRes, &guestRc); 715 740 if (RT_FAILURE(rc)) 716 741 { … … 742 767 uint32_t cbRead = 0; /* readData can return with VWRN_GSTCTL_OBJECTSTATE_CHANGED. */ 743 768 rc = pProcess->i_readData(OUTPUT_HANDLE_ID_STDOUT, sizeof(byBuf), 744 30 * 1000 /* Timeout */, byBuf, sizeof(byBuf),769 msTimeout, byBuf, sizeof(byBuf), 745 770 &cbRead, &guestRc); 746 771 if (RT_FAILURE(rc)) … … 755 780 default: 756 781 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 757 Utf8StrFmt(GuestSession::tr("Reading from file \"%s\" (offset %RU64) failed: %Rrc"),782 Utf8StrFmt(GuestSession::tr("Reading from guest file \"%s\" (offset %RU64) failed: %Rrc"), 758 783 mSource.c_str(), cbWrittenTotal, rc)); 759 784 break; … … 769 794 { 770 795 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 771 Utf8StrFmt(GuestSession::tr(" Error writing to file \"%s\" (%RU64 bytes left): %Rrc"),796 Utf8StrFmt(GuestSession::tr("Writing to host file \"%s\" (%RU64 bytes left) failed: %Rrc"), 772 797 mDest.c_str(), cbToRead, rc)); 773 798 break; … … 802 827 rc, guestRc, waitRes, cbWrittenTotal, objData.mObjectSize, cbToRead)); 803 828 829 /* 830 * Wait on termination of guest process until it completed all operations. 831 */ 804 832 if ( !fCanceled 805 833 || RT_SUCCESS(rc)) 806 834 { 835 rc = pProcess->i_waitFor(ProcessWaitForFlag_Terminate, msTimeout, waitRes, &guestRc); 836 if ( RT_FAILURE(rc) 837 || waitRes != ProcessWaitResult_Terminate) 838 { 839 if (RT_FAILURE(rc)) 840 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 841 Utf8StrFmt( 842 GuestSession::tr("Waiting on termination for copying file \"%s\" from guest failed: %Rrc"), 843 mSource.c_str(), rc)); 844 else 845 { 846 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 847 Utf8StrFmt(GuestSession::tr( 848 "Waiting on termination for copying file \"%s\" from guest failed with wait result %ld"), 849 mSource.c_str(), waitRes)); 850 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 851 } 852 } 853 } 854 855 if (RT_SUCCESS(rc)) 856 { 857 ProcessStatus_T procStatus; 858 LONG exitCode; 859 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 860 && procStatus != ProcessStatus_TerminatedNormally) 861 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 862 && exitCode != 0) 863 ) 864 { 865 LogFlowThisFunc(("procStatus=%ld, exitCode=%ld\n", procStatus, exitCode)); 866 rc = GuestProcessTool::i_exitCodeToRc(procInfo, exitCode); 867 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 868 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" to host failed: %Rrc"), 869 mSource.c_str(), rc)); 870 } 807 871 /* 808 872 * Even if we succeeded until here make sure to check whether we really transfered 809 873 * everything. 810 874 */ 811 if ( objData.mObjectSize > 0812 && cbWrittenTotal == 0)875 else if ( objData.mObjectSize > 0 876 && cbWrittenTotal == 0) 813 877 { 814 878 /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write 815 879 * to the destination -> access denied. */ 816 880 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 817 Utf8StrFmt(GuestSession::tr(" Unable to write \"%s\" to \"%s\": Access denied"),818 mSource.c_str(), mDest.c_str()));819 rc = VERR_ GENERAL_FAILURE; /* Fudge. */881 Utf8StrFmt(GuestSession::tr("Writing guest file \"%s\" to host to \"%s\" failed: Access denied"), 882 mSource.c_str(), mDest.c_str())); 883 rc = VERR_ACCESS_DENIED; 820 884 } 821 885 else if (cbWrittenTotal < (uint64_t)objData.mObjectSize) … … 823 887 /* If we did not copy all let the user know. */ 824 888 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 825 Utf8StrFmt(GuestSession::tr("Copying file\"%s\" failed (%RU64/%RI64 bytes transfered)"),826 mSource.c_str(), cbWrittenTotal, objData.mObjectSize));827 rc = VERR_ GENERAL_FAILURE; /* Fudge. */889 Utf8StrFmt(GuestSession::tr("Copying guest file \"%s\" to host to \"%s\" failed (%RU64/%RI64 bytes transfered)"), 890 mSource.c_str(), mDest.c_str(), cbWrittenTotal, objData.mObjectSize)); 891 rc = VERR_INTERRUPTED; 828 892 } 829 else 830 { 831 ProcessStatus_T procStatus; 832 LONG exitCode; 833 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 834 && procStatus != ProcessStatus_TerminatedNormally) 835 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 836 && exitCode != 0) 837 ) 838 { 839 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 840 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed with status %ld, exit code %d"), 841 mSource.c_str(), procStatus, exitCode)); /**@todo Add 842 stringify methods! */ 843 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 844 } 845 else /* Yay, success! */ 846 rc = setProgressSuccess(); 847 } 893 894 if (RT_SUCCESS(rc)) 895 rc = setProgressSuccess(); 848 896 } 849 897 } … … 1098 1146 LogRel(("Running %s ...\n", procInfo.mName.c_str())); 1099 1147 1100 LONG exitCode;1101 1148 GuestProcessTool procTool; int guestRc; 1102 1149 int vrc = procTool.Init(pSession, procInfo, false /* Async */, &guestRc); … … 1106 1153 vrc = procTool.i_wait(GUESTPROCESSTOOL_FLAG_NONE, &guestRc); 1107 1154 if (RT_SUCCESS(vrc)) 1108 vrc = procTool.i_terminatedOk( &exitCode);1155 vrc = procTool.i_terminatedOk(); 1109 1156 } 1110 1157 … … 1113 1160 switch (vrc) 1114 1161 { 1115 case V ERR_NOT_EQUAL: /** @todo Special guest control rc needed! */1162 case VWRN_GSTCTL_PROCESS_EXIT_CODE: 1116 1163 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 1117 Utf8StrFmt(GuestSession::tr("Running update file \"%s\" on guest terminated with exit code %ld"),1118 procInfo.mExecutable.c_str(), exitCode));1164 Utf8StrFmt(GuestSession::tr("Running update file \"%s\" on guest failed: %Rrc"), 1165 procInfo.mExecutable.c_str(), procTool.i_getRc())); 1119 1166 break; 1120 1167
Note:
See TracChangeset
for help on using the changeset viewer.