Changeset 42611 in vbox for trunk/src/VBox
- Timestamp:
- Aug 6, 2012 8:42:23 AM (12 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/idl/VirtualBox.xidl
r42569 r42611 10265 10265 <interface 10266 10266 name="IFile" extends="$unknown" 10267 uuid=" 2615152d-35c0-4363-8325-ab7e1f2b8b34"10267 uuid="b3484293-b98b-4952-ae23-f18eca6a5ff9" 10268 10268 wsmap="managed" 10269 10269 > … … 10271 10271 TODO 10272 10272 </desc> 10273 10273 <attribute name="creationMode" type="unsigned long" readonly="yes"> 10274 <desc> 10275 TODO 10276 <note> 10277 TODO 10278 </note> 10279 </desc> 10280 </attribute> 10281 <attribute name="disposition" type="unsigned long" readonly="yes"> 10282 <desc> 10283 TODO 10284 <note> 10285 TODO 10286 </note> 10287 </desc> 10288 </attribute> 10274 10289 <attribute name="fileName" type="wstring" readonly="yes"> 10275 10290 <desc> -
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r42530 r42611 305 305 * starting parameters around. 306 306 */ 307 struct GuestProcessInfo 308 { 307 struct GuestProcessStartupInfo 308 { 309 GuestProcessStartupInfo(void) 310 : mFlags(ProcessCreateFlag_None), 311 mPriority(ProcessPriority_Default), 312 mTimeoutMS(30 * 1000 /* 30s timeout by default */) { } 313 309 314 /** The process' friendly name. */ 310 315 Utf8Str mName; … … 317 322 ProcessPriority_T mPriority; 318 323 ProcessAffinity mAffinity; 319 320 324 }; 321 325 -
trunk/src/VBox/Main/include/GuestFileImpl.h
r42095 r42611 24 24 #include "GuestFsObjInfoImpl.h" 25 25 26 class GuestSession; 27 class GuestProcess; 28 26 29 /** 27 30 * TODO … … 43 46 DECLARE_EMPTY_CTOR_DTOR(GuestFile) 44 47 45 HRESULT init(void);48 int init(GuestSession *pSession, const Utf8Str &strPath, const Utf8Str &strOpenMode, const Utf8Str &strDisposition, uint32_t uCreationMode, int64_t iOffset); 46 49 void uninit(void); 47 50 HRESULT FinalConstruct(void); … … 49 52 /** @} */ 50 53 51 /** @name I Directoryinterface.54 /** @name IFile interface. 52 55 * @{ */ 56 STDMETHOD(COMGETTER(CreationMode))(ULONG *aCreationMode); 57 STDMETHOD(COMGETTER(Disposition))(ULONG *aDisposition); 53 58 STDMETHOD(COMGETTER(FileName))(BSTR *aFileName); 54 59 STDMETHOD(COMGETTER(InitialSize))(LONG64 *aInitialSize); … … 57 62 58 63 STDMETHOD(Close)(void); 59 STDMETHOD(QueryInfo)(I GuestFsObjInfo **aInfo);64 STDMETHOD(QueryInfo)(IFsObjInfo **aInfo); 60 65 STDMETHOD(Read)(ULONG aToRead, ULONG *aRead, ComSafeArrayOut(BYTE, aData)); 61 66 STDMETHOD(ReadAt)(LONG64 aOffset, ULONG aToRead, ULONG *aRead, ComSafeArrayOut(BYTE, aData)); … … 66 71 /** @} */ 67 72 73 public: 74 /** @name Public internal methods. 75 * @{ */ 76 static uint32_t getDispositionFromString(const Utf8Str &strDisposition); 77 static uint32_t getOpenModeFromString(const Utf8Str &strOpenMode); 78 /** @} */ 79 68 80 private: 69 81 70 82 struct Data 71 83 { 72 Utf8Str mFileName; 73 LONG64 mInitialSize; 74 ULONG mOpenMode; 75 LONG64 mOffset; 84 /** The associate session this file belongs to. */ 85 ComObjPtr<GuestSession> mSession; 86 /** The process object this file is bound to. */ 87 ComObjPtr<GuestProcess> mProcess; 88 uint32_t mCreationMode; 89 uint32_t mDisposition; 90 Utf8Str mFileName; 91 int64_t mInitialSize; 92 uint32_t mOpenMode; 93 int64_t mOffset; 76 94 } mData; 77 95 }; -
trunk/src/VBox/Main/include/GuestProcessImpl.h
r42551 r42611 45 45 DECLARE_EMPTY_CTOR_DTOR(GuestProcess) 46 46 47 int init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcess Info &aProcInfo);47 int init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcessStartupInfo &aProcInfo); 48 48 void uninit(void); 49 49 HRESULT FinalConstruct(void); … … 117 117 GuestCtrlCallbacks mCallbacks; 118 118 /** The process start information. */ 119 GuestProcess InfomProcess;119 GuestProcessStartupInfo mProcess; 120 120 /** Exit code if process has been terminated. */ 121 121 LONG mExitCode; -
trunk/src/VBox/Main/include/GuestSessionImpl.h
r42566 r42611 205 205 int dispatchToProcess(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData); 206 206 int fileClose(ComObjPtr<GuestFile> pFile); 207 int fileOpenInternal(const Utf8Str &strPath, const Utf8Str &strOpenMode, const Utf8Str &strDisposition, 208 uint32_t uCreationMode, int64_t iOffset, ComObjPtr<GuestFile> &pFile); 207 209 int fileQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData); 208 210 int fileQuerySizeInternal(const Utf8Str &strPath, int64_t *pllSize); … … 212 214 uint32_t getProtocolVersion(void) { return mData.mProtocolVersion; } 213 215 int processClose(ComObjPtr<GuestProcess> pProcess); 214 int processCreateExInteral(GuestProcess Info &procInfo, ComObjPtr<GuestProcess> &pProgress);216 int processCreateExInteral(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProgress); 215 217 inline bool processExists(uint32_t uProcessID, ComObjPtr<GuestProcess> *pProcess); 216 218 inline int processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess); -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r42566 r42611 707 707 VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(pHeader->u32ContextID))); 708 708 #endif 709 int rc = pGuest->dispatchToSession(pHeader->u32ContextID, u32Function, pvParms, cbParms); 709 710 bool fDispatch = true; 711 #ifdef DEBUG 712 /* 713 * Pre-check: If we got a status message with an error and VERR_TOO_MUCH_DATA 714 * it means that that guest could not handle the entire message 715 * because of its exceeding size. This should not happen on daily 716 * use but testcases might try this. It then makes no sense to dispatch 717 * this further because we don't have a valid context ID. 718 */ 719 if (u32Function == GUEST_EXEC_SEND_STATUS) 720 { 721 PCALLBACKDATAEXECSTATUS pCallbackData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvParms); 722 AssertPtr(pCallbackData); 723 AssertReturn(sizeof(CALLBACKDATAEXECSTATUS) == cbParms, VERR_INVALID_PARAMETER); 724 AssertReturn(CALLBACKDATAMAGIC_EXEC_STATUS == pCallbackData->hdr.u32Magic, VERR_INVALID_PARAMETER); 725 726 if ( pCallbackData->u32Status == PROC_STS_ERROR 727 && pCallbackData->u32Flags == VERR_TOO_MUCH_DATA) 728 { 729 LogFlowFunc(("Requested command with too much data, skipping dispatching ...\n")); 730 731 Assert(pCallbackData->u32PID == 0); 732 fDispatch = false; 733 } 734 } 735 #endif 736 int rc = VINF_SUCCESS; 737 if (fDispatch) 738 rc = pGuest->dispatchToSession(pHeader->u32ContextID, u32Function, pvParms, cbParms); 710 739 711 740 #ifdef VBOX_WITH_GUEST_CONTROL_LEGACY -
trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp
r42530 r42611 47 47 int GuestCtrlEvent::Cancel(void) 48 48 { 49 LogFlowThisFuncEnter();50 51 49 int rc = VINF_SUCCESS; 52 50 if (!ASMAtomicReadBool(&fCompleted)) … … 56 54 ASMAtomicXchgBool(&fCanceled, true); 57 55 58 LogFlowThisFunc(("Cancelling ...\n"));56 LogFlowThisFunc(("Cancelling event ...\n")); 59 57 rc = hEventSem != NIL_RTSEMEVENT 60 58 ? RTSemEventSignal(hEventSem) : VINF_SUCCESS; … … 62 60 } 63 61 64 LogFlowFuncLeaveRC(rc);65 62 return rc; 66 63 } -
trunk/src/VBox/Main/src-client/GuestFileImpl.cpp
r42478 r42611 22 22 *******************************************************************************/ 23 23 #include "GuestFileImpl.h" 24 #include "GuestSessionImpl.h" 24 25 #include "GuestCtrlImplPrivate.h" 25 26 … … 52 53 ///////////////////////////////////////////////////////////////////////////// 53 54 54 HRESULT GuestFile::init(void) 55 int GuestFile::init(GuestSession *pSession, const Utf8Str &strPath, 56 const Utf8Str &strOpenMode, const Utf8Str &strDisposition, uint32_t uCreationMode, 57 int64_t iOffset) 55 58 { 56 59 /* Enclose the state transition NotReady->InInit->Ready. */ … … 58 61 AssertReturn(autoInitSpan.isOk(), E_FAIL); 59 62 63 mData.mSession = pSession; 64 mData.mCreationMode = uCreationMode; 65 mData.mDisposition = getDispositionFromString(strDisposition); 66 mData.mFileName = strPath; 67 mData.mInitialSize = 0; 68 mData.mOpenMode = getOpenModeFromString(strOpenMode); 69 mData.mOffset = iOffset; 70 71 /** @todo Validate parameters! */ 72 60 73 /* Confirm a successful initialization when it's the case. */ 61 74 autoInitSpan.setSucceeded(); 62 75 63 return S_OK;76 return VINF_SUCCESS; 64 77 } 65 78 … … 76 89 if (autoUninitSpan.uninitDone()) 77 90 return; 91 92 mData.mSession->fileClose(this); 78 93 } 79 94 … … 81 96 ///////////////////////////////////////////////////////////////////////////// 82 97 98 STDMETHODIMP GuestFile::COMGETTER(CreationMode)(ULONG *aCreationMode) 99 { 100 #ifndef VBOX_WITH_GUEST_CONTROL 101 ReturnComNotImplemented(); 102 #else 103 AutoCaller autoCaller(this); 104 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 105 106 CheckComArgOutPointerValid(aCreationMode); 107 108 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 109 110 *aCreationMode = mData.mCreationMode; 111 112 return S_OK; 113 #endif /* VBOX_WITH_GUEST_CONTROL */ 114 } 115 116 STDMETHODIMP GuestFile::COMGETTER(Disposition)(ULONG *aDisposition) 117 { 118 #ifndef VBOX_WITH_GUEST_CONTROL 119 ReturnComNotImplemented(); 120 #else 121 AutoCaller autoCaller(this); 122 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 123 124 CheckComArgOutPointerValid(aDisposition); 125 126 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 127 128 *aDisposition = mData.mDisposition; 129 130 return S_OK; 131 #endif /* VBOX_WITH_GUEST_CONTROL */ 132 } 133 83 134 STDMETHODIMP GuestFile::COMGETTER(FileName)(BSTR *aFileName) 84 135 { … … 89 140 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 90 141 91 ReturnComNotImplemented(); 142 CheckComArgOutPointerValid(aFileName); 143 144 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 145 146 mData.mFileName.cloneTo(aFileName); 147 148 return S_OK; 92 149 #endif /* VBOX_WITH_GUEST_CONTROL */ 93 150 } … … 101 158 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 102 159 103 ReturnComNotImplemented(); 160 CheckComArgOutPointerValid(aInitialSize); 161 162 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 163 164 *aInitialSize = mData.mInitialSize; 165 166 return S_OK; 104 167 #endif /* VBOX_WITH_GUEST_CONTROL */ 105 168 } … … 113 176 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 114 177 115 ReturnComNotImplemented(); 178 CheckComArgOutPointerValid(aOffset); 179 180 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 181 182 *aOffset = mData.mOffset; 183 184 return S_OK; 116 185 #endif /* VBOX_WITH_GUEST_CONTROL */ 117 186 } … … 125 194 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 126 195 127 ReturnComNotImplemented(); 128 #endif /* VBOX_WITH_GUEST_CONTROL */ 196 CheckComArgOutPointerValid(aOpenMode); 197 198 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 199 200 *aOpenMode = mData.mOpenMode; 201 202 return S_OK; 203 #endif /* VBOX_WITH_GUEST_CONTROL */ 204 } 205 206 // private methods 207 ///////////////////////////////////////////////////////////////////////////// 208 209 /* static */ 210 uint32_t GuestFile::getDispositionFromString(const Utf8Str &strDisposition) 211 { 212 return 0; /** @todo Implement me! */ 213 } 214 215 /* static */ 216 uint32_t GuestFile::getOpenModeFromString(const Utf8Str &strOpenMode) 217 { 218 return 0; /** @todo Implement me! */ 129 219 } 130 220 … … 144 234 } 145 235 146 STDMETHODIMP GuestFile::QueryInfo(I GuestFsObjInfo **aInfo)236 STDMETHODIMP GuestFile::QueryInfo(IFsObjInfo **aInfo) 147 237 { 148 238 #ifndef VBOX_WITH_GUEST_CONTROL -
trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
r42551 r42611 104 104 ///////////////////////////////////////////////////////////////////////////// 105 105 106 int GuestProcess::init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcess Info &aProcInfo)106 int GuestProcess::init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcessStartupInfo &aProcInfo) 107 107 { 108 108 LogFlowThisFunc(("aConsole=%p, aSession=%p, aProcessID=%RU32\n", … … 178 178 collection.detachTo(ComSafeArrayOutArg(aArguments)); 179 179 180 LogFlowFuncLeaveRC(S_OK);181 180 return S_OK; 182 181 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 205 204 arguments.detachTo(ComSafeArrayOutArg(aEnvironment)); 206 205 207 LogFlowFuncLeaveRC(S_OK);208 206 return S_OK; 209 207 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 226 224 mData.mProcess.mCommand.cloneTo(aExecutablePath); 227 225 228 LogFlowFuncLeaveRC(S_OK);229 226 return S_OK; 230 227 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 247 244 *aExitCode = mData.mExitCode; 248 245 249 LogFlowFuncLeaveRC(S_OK);250 246 return S_OK; 251 247 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 268 264 mData.mProcess.mName.cloneTo(aName); 269 265 270 LogFlowFuncLeaveRC(S_OK);271 266 return S_OK; 272 267 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 289 284 *aPID = mData.mPID; 290 285 291 LogFlowFuncLeaveRC(S_OK);292 286 return S_OK; 293 287 #endif /* VBOX_WITH_GUEST_CONTROL */ … … 308 302 *aStatus = mData.mStatus; 309 303 310 LogFlowFuncLeaveRC(S_OK);311 304 return S_OK; 312 305 #endif /* VBOX_WITH_GUEST_CONTROL */ -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r42573 r42611 143 143 int rc; 144 144 145 /** @todo Make use of exception (+ finally block) here! */145 /** @todo Make use of exceptions (+ finally block) here! */ 146 146 147 147 try … … 152 152 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 153 153 Utf8StrFmt(GuestSession::tr("Source file \"%s\" does not exist or is not a file"), 154 mSource.c_str()));154 mSource.c_str())); 155 155 } 156 156 else … … 163 163 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 164 164 Utf8StrFmt(GuestSession::tr("Could not open source file \"%s\" for reading (%Rrc)"), 165 mSource.c_str(), rc));165 mSource.c_str(), rc)); 166 166 } 167 167 else … … 172 172 { 173 173 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 174 Utf8StrFmt(GuestSession::tr("Could not query file size of \"%s\" (%Rrc)"),175 mSource.c_str(), rc));174 Utf8StrFmt(GuestSession::tr("Could not query file size of \"%s\": %Rrc"), 175 mSource.c_str(), rc)); 176 176 } 177 177 else 178 178 { 179 GuestProcess Info procInfo;179 GuestProcessStartupInfo procInfo; 180 180 procInfo.mName = Utf8StrFmt(GuestSession::tr("Copying file \"%s\" to the guest to \"%s\" (%RU64 bytes)"), 181 181 mSource.c_str(), mDest.c_str(), cbFileSize); 182 182 procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_CAT); 183 183 procInfo.mFlags = ProcessCreateFlag_None; … … 190 190 int rc = pSession->processCreateExInteral(procInfo, pProcess); 191 191 if (RT_SUCCESS(rc)) 192 rc = pProcess->startProcess(); 193 if (RT_FAILURE(rc)) 194 { 195 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 196 Utf8StrFmt(GuestSession::tr("Unable to start guest process: %Rrc"), rc)); 197 } 198 else 192 199 { 193 200 GuestProcessWaitResult waitRes; … … 227 234 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 228 235 Utf8StrFmt(GuestSession::tr("Could not read from file \"%s\" (%Rrc)"), 229 mSource.c_str(), rc));236 mSource.c_str(), rc)); 230 237 break; 231 238 } … … 235 242 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 236 243 Utf8StrFmt(GuestSession::tr("Seeking file \"%s\" offset %RU64 failed: %Rrc"), 237 mSource.c_str(), cbWrittenTotal, rc));244 mSource.c_str(), cbWrittenTotal, rc)); 238 245 break; 239 246 } … … 262 269 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 263 270 Utf8StrFmt(GuestSession::tr("Writing to file \"%s\" (offset %RU64) failed: %Rrc"), 264 mSource.c_str(), cbWrittenTotal, rc));271 mSource.c_str(), cbWrittenTotal, rc)); 265 272 break; 266 273 } 267 274 268 /* Safety first. */269 Assert(cbRead <= cbToRead);270 Assert(cbToRead >= cbRead);271 272 275 /* Only subtract bytes reported written by the guest. */ 276 Assert(cbToRead >= cbWritten); 273 277 cbToRead -= cbWritten; 274 278 … … 282 286 283 287 /* Update the progress. */ 288 Assert(!mProgress.isNull()); 284 289 HRESULT hr = mProgress->SetCurrentOperationProgress((ULONG)(cbWrittenTotal * 100 / cbFileSize)); 285 290 if (FAILED(hr)) 286 291 { 287 292 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 288 Utf8StrFmt(GuestSession::tr("Error updating the progress of copying file s\"%s\" to \"%s\""),289 mSource.c_str(), mDest.c_str()));293 Utf8StrFmt(GuestSession::tr("Error updating the progress of copying file \"%s\" to \"%s\""), 294 mSource.c_str(), mDest.c_str())); 290 295 break; 291 296 } … … 310 315 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 311 316 Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to \"%s\""), 312 mSource.c_str(), mDest.c_str()));317 mSource.c_str(), mDest.c_str())); 313 318 } 314 319 else if (cbWrittenTotal < cbFileSize) … … 317 322 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 318 323 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed (%RU64/%RU64 bytes transfered)"), 319 mSource.c_str(), cbWrittenTotal, cbFileSize));324 mSource.c_str(), cbWrittenTotal, cbFileSize)); 320 325 } 321 else /* Yay, all went fine! */ 322 rc = setProgressSuccess(); 326 else 327 { 328 ProcessStatus_T procStatus; 329 LONG exitCode; 330 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 331 && procStatus != ProcessStatus_TerminatedNormally) 332 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 333 && exitCode != 0) 334 ) 335 { 336 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 337 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed with status %ld, exit code %d"), 338 mSource.c_str(), procStatus, exitCode)); /**@todo Add stringify methods! */ 339 } 340 else /* Yay, success! */ 341 rc = setProgressSuccess(); 342 } 323 343 } 344 345 pSession->processClose(pProcess); 324 346 } /* processCreateExInteral */ 325 347 } /* RTFileGetSize */ … … 379 401 int SessionTaskCopyFrom::Run(void) 380 402 { 381 return 0; 403 LogFlowThisFuncEnter(); 404 405 ComObjPtr<GuestSession> pSession = mSession; 406 Assert(!pSession.isNull()); 407 408 AutoCaller autoCaller(pSession); 409 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 410 411 int rc; 412 413 /** @todo Make use of exceptions (+ finally block) here! */ 414 415 try 416 { 417 /* 418 * Note: There will be races between querying file size + reading the guest file's 419 * content because we currently *do not* lock down the guest file when doing the 420 * actual operations. 421 ** @todo Implement guest file locking! 422 */ 423 GuestFsObjData objData; 424 rc = pSession->fileQueryInfoInternal(Utf8Str(mSource), objData); 425 if (RT_FAILURE(rc)) 426 { 427 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 428 Utf8StrFmt(GuestSession::tr("Querying guest file information for \"%s\" failed: %Rrc"), 429 mSource.c_str(), rc)); 430 } 431 else if (objData.mType != FsObjType_File) /* Only single files are supported at the moment. */ 432 { 433 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 434 Utf8StrFmt(GuestSession::tr("Guest file \"%s\" is not a file"), mSource.c_str())); 435 } 436 437 if (RT_SUCCESS(rc)) 438 { 439 RTFILE fileDest; 440 rc = RTFileOpen(&fileDest, mDest.c_str(), 441 RTFILE_O_WRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE); /** @todo Use the correct open modes! */ 442 if (RT_FAILURE(rc)) 443 { 444 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 445 Utf8StrFmt(GuestSession::tr("Error opening destination file \"%s\": %Rrc"), 446 mDest.c_str(), rc)); 447 } 448 else 449 { 450 GuestProcessStartupInfo procInfo; 451 procInfo.mName = Utf8StrFmt(GuestSession::tr("Copying file \"%s\" to the host to \"%s\" (%RI64 bytes)"), 452 mSource.c_str(), mDest.c_str(), objData.mObjectSize); 453 procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_CAT); 454 procInfo.mFlags = ProcessCreateFlag_WaitForStdOut; 455 456 /* Set arguments.*/ 457 procInfo.mArguments.push_back(mSource); /* Which file to output? */ 458 459 /* Startup process. */ 460 ComObjPtr<GuestProcess> pProcess; 461 int rc = pSession->processCreateExInteral(procInfo, pProcess); 462 if (RT_SUCCESS(rc)) 463 rc = pProcess->startProcess(); 464 if (RT_FAILURE(rc)) 465 { 466 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 467 Utf8StrFmt(GuestSession::tr("Unable to start guest process: %Rrc"), rc)); 468 } 469 else 470 { 471 GuestProcessWaitResult waitRes; 472 BYTE byBuf[_64K]; 473 474 BOOL fCanceled = FALSE; 475 uint64_t cbWrittenTotal = 0; 476 uint64_t cbToRead = objData.mObjectSize; 477 478 for (;;) 479 { 480 rc = pProcess->waitFor(ProcessWaitForFlag_StdOut, 481 30 * 1000 /* Timeout */, waitRes); 482 if ( RT_FAILURE(rc) 483 || waitRes.mResult != ProcessWaitResult_StdOut) 484 { 485 break; 486 } 487 488 size_t cbRead; 489 rc = pProcess->readData(OUTPUT_HANDLE_ID_STDOUT, sizeof(byBuf), 490 30 * 1000 /* Timeout */, byBuf, sizeof(byBuf), 491 &cbRead); 492 if (RT_FAILURE(rc)) 493 { 494 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 495 Utf8StrFmt(GuestSession::tr("Reading from file \"%s\" (offset %RU64) failed: %Rrc"), 496 mSource.c_str(), cbWrittenTotal, rc)); 497 break; 498 } 499 500 if (cbRead) 501 { 502 rc = RTFileWrite(fileDest, byBuf, cbRead, NULL /* No partial writes */); 503 if (RT_FAILURE(rc)) 504 { 505 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 506 Utf8StrFmt(GuestSession::tr("Error writing to file \"%s\" (%RU64 bytes left): %Rrc"), 507 mDest.c_str(), cbToRead, rc)); 508 break; 509 } 510 511 /* Only subtract bytes reported written by the guest. */ 512 Assert(cbToRead >= cbRead); 513 cbToRead -= cbRead; 514 515 /* Update total bytes written to the guest. */ 516 cbWrittenTotal += cbRead; 517 Assert(cbWrittenTotal <= (uint64_t)objData.mObjectSize); 518 519 /* Did the user cancel the operation above? */ 520 if ( SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled))) 521 && fCanceled) 522 break; 523 524 Assert(!mProgress.isNull()); 525 HRESULT hr = mProgress->SetCurrentOperationProgress(cbWrittenTotal / ((uint64_t)objData.mObjectSize / 100.0)); 526 if (FAILED(hr)) 527 { 528 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 529 Utf8StrFmt(GuestSession::tr("Error updating the progress of copying file \"%s\" to \"%s\""), 530 mSource.c_str(), mDest.c_str())); 531 break; 532 } 533 534 /* End of file reached? */ 535 if (cbToRead == 0) 536 break; 537 } 538 } /* for */ 539 540 if ( !fCanceled 541 || RT_SUCCESS(rc)) 542 { 543 /* 544 * Even if we succeeded until here make sure to check whether we really transfered 545 * everything. 546 */ 547 if ( objData.mObjectSize > 0 548 && cbWrittenTotal == 0) 549 { 550 /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write 551 * to the destination -> access denied. */ 552 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 553 Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to \"%s\""), 554 mSource.c_str(), mDest.c_str())); 555 } 556 else if (cbWrittenTotal < (uint64_t)objData.mObjectSize) 557 { 558 /* If we did not copy all let the user know. */ 559 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 560 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed (%RU64/%RU64 bytes transfered)"), 561 mSource.c_str(), cbWrittenTotal, objData.mObjectSize)); 562 } 563 else 564 { 565 ProcessStatus_T procStatus; 566 LONG exitCode; 567 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 568 && procStatus != ProcessStatus_TerminatedNormally) 569 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 570 && exitCode != 0) 571 ) 572 { 573 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 574 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed with status %ld, exit code %d"), 575 mSource.c_str(), procStatus, exitCode)); /**@todo Add stringify methods! */ 576 } 577 else /* Yay, success! */ 578 rc = setProgressSuccess(); 579 } 580 } 581 582 pSession->processClose(pProcess); 583 } 584 585 RTFileClose(fileDest); 586 } 587 } 588 } 589 catch (int rc2) 590 { 591 rc = rc2; 592 } 593 594 LogFlowFuncLeaveRC(rc); 595 return rc; 382 596 } 383 597 … … 764 978 strPath.c_str(), uMode, uFlags)); 765 979 766 GuestProcess Info procInfo;767 procInfo.mName = Utf8StrFmt(tr("Creating directory \"%s\"", strPath.c_str()));768 procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_MKDIR);980 GuestProcessStartupInfo procInfo; 981 procInfo.mName = Utf8StrFmt(tr("Creating directory \"%s\"", strPath.c_str())); 982 procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_MKDIR); 769 983 770 984 int rc = VINF_SUCCESS; … … 789 1003 ComObjPtr<GuestProcess> pProcess; 790 1004 rc = processCreateExInteral(procInfo, pProcess); 1005 if (RT_SUCCESS(rc)) 1006 rc = pProcess->startProcess(); 791 1007 if (RT_SUCCESS(rc)) 792 1008 { … … 815 1031 try 816 1032 { 1033 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1034 817 1035 /* Create the directory object. */ 818 1036 HRESULT hr = pDirectory.createObject(); … … 827 1045 mData.mDirectories.push_back(pDirectory); 828 1046 829 LogFlowFunc(("Added new directory (Session: %RU32) with process ID=%RU32\n",830 mData.mId, mData.mNextProcessID));1047 LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n", 1048 strPath.c_str(), mData.mId)); 831 1049 } 832 1050 catch (int rc2) … … 885 1103 } 886 1104 1105 int GuestSession::fileOpenInternal(const Utf8Str &strPath, const Utf8Str &strOpenMode, const Utf8Str &strDisposition, 1106 uint32_t uCreationMode, int64_t iOffset, ComObjPtr<GuestFile> &pFile) 1107 { 1108 LogFlowThisFunc(("strPath=%s, strOpenMode=%s, strDisposition=%s, uCreationMode=%x, iOffset=%RI64\n", 1109 strPath.c_str(), strOpenMode.c_str(), strDisposition.c_str(), uCreationMode, iOffset)); 1110 int rc; 1111 1112 try 1113 { 1114 /* Create the directory object. */ 1115 HRESULT hr = pFile.createObject(); 1116 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 1117 1118 /* Note: There will be a race between creating and getting/initing the directory 1119 object here. */ 1120 rc = pFile->init(this /* Parent */, 1121 strPath, strOpenMode, strDisposition, uCreationMode, iOffset); 1122 if (RT_FAILURE(rc)) throw rc; 1123 1124 /* Add the created directory to our vector. */ 1125 mData.mFiles.push_back(pFile); 1126 1127 LogFlowFunc(("Added new file \"%s\" (Session: %RU32\n", 1128 strPath.c_str(), mData.mId)); 1129 } 1130 catch (int rc2) 1131 { 1132 rc = rc2; 1133 } 1134 1135 LogFlowFuncLeaveRC(rc); 1136 return rc; 1137 } 1138 887 1139 /* Note: Will work on directories and others, too. */ 888 1140 int GuestSession::fileQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData) … … 890 1142 LogFlowThisFunc(("strPath=%s\n", strPath.c_str())); 891 1143 892 GuestProcess Info procInfo;893 procInfo.mName = Utf8StrFmt(tr("Querying info for \"%s\"" , strPath.c_str()));1144 GuestProcessStartupInfo procInfo; 1145 procInfo.mName = Utf8StrFmt(tr("Querying info for \"%s\""), strPath.c_str()); 894 1146 procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_STAT); 895 1147 procInfo.mFlags = ProcessCreateFlag_WaitForStdOut; … … 904 1156 int rc = processCreateExInteral(procInfo, pProcess); 905 1157 if (RT_SUCCESS(rc)) 1158 rc = pProcess->startProcess(); 1159 if (RT_SUCCESS(rc)) 906 1160 { 907 1161 GuestProcessWaitResult waitRes; 908 1162 BYTE byBuf[_64K]; 909 size_t cbRead ;1163 size_t cbRead = 0; 910 1164 911 1165 for (;;) … … 914 1168 30 * 1000 /* Timeout */, waitRes); 915 1169 if ( RT_FAILURE(rc) 916 || waitRes.mResult != ProcessWaitResult_StdOut) 1170 || waitRes.mResult == ProcessWaitResult_Terminate 1171 || waitRes.mResult == ProcessWaitResult_Error 1172 || waitRes.mResult == ProcessWaitResult_Timeout) 917 1173 { 918 1174 break; … … 925 1181 break; 926 1182 927 rc = streamOut.AddData(byBuf, cbRead); 928 if (RT_FAILURE(rc)) 929 break; 930 } 931 932 LogFlowThisFunc(("rc=%Rrc, cbRead=%RU32, cbStreamOut=%RU32\n", 1183 if (cbRead) 1184 { 1185 rc = streamOut.AddData(byBuf, cbRead); 1186 if (RT_FAILURE(rc)) 1187 break; 1188 } 1189 } 1190 1191 LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64, cbStreamOut=%RU32\n", 933 1192 rc, cbRead, streamOut.GetSize())); 934 1193 } … … 999 1258 } 1000 1259 1001 int GuestSession::processCreateExInteral(GuestProcessInfo &procInfo, ComObjPtr<GuestProcess> &pProcess) 1260 /** 1261 * Creates but does *not* start the process yet. See GuestProcess::startProcess() or 1262 * GuestProcess::startProcessAsync() for that. 1263 * 1264 * @return IPRT status code. 1265 * @param procInfo 1266 * @param pProcess 1267 */ 1268 int GuestSession::processCreateExInteral(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProcess) 1002 1269 { 1003 1270 LogFlowFunc(("mCmd=%s, mFlags=%x, mTimeoutMS=%RU32\n", 1004 1271 procInfo.mCommand.c_str(), procInfo.mFlags, procInfo.mTimeoutMS)); 1272 #ifdef DEBUG 1273 if (procInfo.mArguments.size()) 1274 { 1275 LogFlowFunc(("Arguments:")); 1276 ProcessArguments::const_iterator it = procInfo.mArguments.begin(); 1277 while (it != procInfo.mArguments.end()) 1278 { 1279 LogFlow((" %s", (*it).c_str())); 1280 it++; 1281 } 1282 LogFlow(("\n")); 1283 } 1284 #endif 1005 1285 1006 1286 /* Validate flags. */ … … 1323 1603 fFlags |= flags[i]; 1324 1604 1325 if (!(fFlags & DirectoryCreateFlag_Parents)) 1326 return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), fFlags); 1605 if (fFlags) 1606 { 1607 if (!(fFlags & DirectoryCreateFlag_Parents)) 1608 return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), fFlags); 1609 } 1327 1610 } 1328 1611 … … 1330 1613 1331 1614 ComObjPtr <GuestDirectory> pDirectory; 1332 int rc = directoryCreateInternal(Utf8Str(aPath), (uint32_t)aMode, (uint32_t)aFlags, pDirectory);1615 int rc = directoryCreateInternal(Utf8Str(aPath), (uint32_t)aMode, fFlags, pDirectory); 1333 1616 if (RT_SUCCESS(rc)) 1334 1617 { … … 1652 1935 LogFlowThisFuncEnter(); 1653 1936 1654 AutoCaller autoCaller(this); 1655 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1656 1657 ReturnComNotImplemented(); 1937 if (RT_UNLIKELY((aPath) == NULL || *(aPath) == '\0')) 1938 return setError(E_INVALIDARG, tr("No file to open specified")); 1939 if (RT_UNLIKELY((aOpenMode) == NULL || *(aOpenMode) == '\0')) 1940 return setError(E_INVALIDARG, tr("No open mode specified")); 1941 if (RT_UNLIKELY((aDisposition) == NULL || *(aDisposition) == '\0')) 1942 return setError(E_INVALIDARG, tr("No disposition mode specified")); 1943 1944 CheckComArgOutPointerValid(aFile); 1945 1946 AutoCaller autoCaller(this); 1947 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1948 1949 /** @todo Validate open mode. */ 1950 /** @todo Validate disposition mode. */ 1951 1952 /** @todo Validate creation mode. */ 1953 uint32_t uCreationMode = 0; 1954 1955 HRESULT hr = S_OK; 1956 1957 ComObjPtr <GuestFile> pFile; 1958 int rc = fileOpenInternal(Utf8Str(aPath), Utf8Str(aOpenMode), Utf8Str(aDisposition), 1959 aCreationMode, aOffset, pFile); 1960 if (RT_SUCCESS(rc)) 1961 { 1962 /* Return directory object to the caller. */ 1963 hr = pFile.queryInterfaceTo(aFile); 1964 } 1965 else 1966 { 1967 switch (rc) 1968 { 1969 /** @todo Add more error info! */ 1970 1971 default: 1972 hr = setError(VBOX_E_IPRT_ERROR, tr("Directory creation failed: %Rrc"), rc); 1973 break; 1974 } 1975 } 1976 1977 return hr; 1658 1978 #endif /* VBOX_WITH_GUEST_CONTROL */ 1659 1979 } … … 1786 2106 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1787 2107 1788 GuestProcessInfo procInfo; 1789 2108 GuestProcessStartupInfo procInfo; 1790 2109 procInfo.mCommand = Utf8Str(aCommand); 1791 procInfo.mFlags = ProcessCreateFlag_None;1792 2110 1793 2111 if (aArguments)
Note:
See TracChangeset
for help on using the changeset viewer.