Changeset 42693 in vbox for trunk/src/VBox
- Timestamp:
- Aug 8, 2012 10:37:51 PM (12 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
r42668 r42693 1659 1659 { 1660 1660 #ifndef VBOX_WITH_GUEST_CONTROL2 1661 Assert(!fFlags); 1661 1662 rc = pContext->pGuest->CopyToGuest(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(), 1662 1663 Bstr(pContext->strUsername).raw(), Bstr(pContext->strPassword).raw(), 1663 1664 fFlags, pProgress.asOutParam()); 1664 1665 #else 1665 Assert(!fFlags);1666 1666 SafeArray<CopyFileFlag_T> copyFlags; 1667 1667 rc = pContext->pGuestSession->CopyTo(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(), … … 1674 1674 { 1675 1675 #ifndef VBOX_WITH_GUEST_CONTROL2 1676 Assert(!fFlags); 1676 1677 rc = pContext->pGuest->CopyFromGuest(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(), 1677 1678 Bstr(pContext->strUsername).raw(), Bstr(pContext->strPassword).raw(), 1678 1679 fFlags, pProgress.asOutParam()); 1679 1680 #else 1680 Assert(!fFlags);1681 1681 SafeArray<CopyFileFlag_T> copyFlags; 1682 1682 rc = pContext->pGuestSession->CopyFrom(Bstr(pszFileSource).raw(), Bstr(pszFileDest).raw(), … … 2809 2809 HRESULT rc = S_OK; 2810 2810 ComPtr<IProgress> pProgress; 2811 2812 SafeArray<AdditionsUpdateFlag_T> updateFlags; 2811 2813 CHECK_ERROR(guest, UpdateGuestAdditions(Bstr(strSource).raw(), 2812 2814 /* Wait for whole update process to complete. */ 2813 AdditionsUpdateFlag_None,2815 ComSafeArrayAsInParam(updateFlags), 2814 2816 pProgress.asOutParam())); 2815 2817 if (FAILED(rc)) -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r42673 r42693 10668 10668 <interface 10669 10669 name="IGuest" extends="$unknown" 10670 uuid=" 9e0b07b1-490f-4413-8955-0a16515aac12"10670 uuid="19c32350-0618-4ede-b0c3-2b4311bf0d9b" 10671 10671 wsmap="managed" 10672 10672 > … … 11590 11590 </desc> 11591 11591 </param> 11592 <param name="flags" type=" unsigned long" dir="in">11592 <param name="flags" type="AdditionsUpdateFlag" dir="in" safearray="yes"> 11593 11593 <desc> 11594 11594 <link to="AdditionsUpdateFlag"/> flags. -
trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h
r42673 r42693 172 172 struct GuestProcessWaitResult 173 173 { 174 GuestProcessWaitResult(void) 175 : mResult(ProcessWaitResult_None), 176 mRC(VINF_SUCCESS) { } 177 174 178 /** The wait result when returning from the wait call. */ 175 179 ProcessWaitResult_T mResult; 180 /** Optional rc to this result. */ 176 181 int mRC; 177 182 }; -
trunk/src/VBox/Main/include/GuestImpl.h
r42461 r42693 132 132 ULONG *aMemTotal, ULONG *aMemFree, ULONG *aMemBalloon, ULONG *aMemShared, ULONG *aMemCache, 133 133 ULONG *aPageTotal, ULONG *aMemAllocTotal, ULONG *aMemFreeTotal, ULONG *aMemBalloonTotal, ULONG *aMemSharedTotal); 134 STDMETHOD(UpdateGuestAdditions)(IN_BSTR aSource, ULONG aFlags, IProgress **aProgress);134 STDMETHOD(UpdateGuestAdditions)(IN_BSTR aSource, ComSafeArrayIn(AdditionsUpdateFlag_T, aFlags), IProgress **aProgress); 135 135 STDMETHOD(CreateSession)(IN_BSTR aUser, IN_BSTR aPassword, IN_BSTR aDomain, IN_BSTR aSessionName, IGuestSession **aGuestSession); 136 136 STDMETHOD(FindSession)(IN_BSTR aSessionName, ComSafeArrayOut(IGuestSession *, aSessions)); … … 210 210 Console *getConsole(void) { return mParent; } 211 211 int sessionClose(ComObjPtr<GuestSession> pSession); 212 int sessionCreate(const Utf8Str &strUser, const Utf8Str & aPassword, const Utf8Str &aDomain,213 const Utf8Str & aSessionName, ComObjPtr<GuestSession> &pGuestSession);212 int sessionCreate(const Utf8Str &strUser, const Utf8Str &strPassword, const Utf8Str &strDomain, 213 const Utf8Str &strSessionName, ComObjPtr<GuestSession> &pGuestSession); 214 214 inline bool sessionExists(uint32_t uSessionID); 215 215 /** @} */ -
trunk/src/VBox/Main/include/GuestSessionImpl.h
r42691 r42693 49 49 int setProgress(ULONG uPercent); 50 50 int setProgressSuccess(void); 51 intsetProgressErrorMsg(HRESULT hr, const Utf8Str &strMsg);51 HRESULT setProgressErrorMsg(HRESULT hr, const Utf8Str &strMsg); 52 52 53 53 protected: … … 70 70 const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags); 71 71 72 SessionTaskCopyTo(GuestSession *pSession, 73 PRTFILE pSourceFile, size_t cbSourceOffset, size_t cbSourceSize, 74 const Utf8Str &strDest, uint32_t uFlags); 75 72 76 virtual ~SessionTaskCopyTo(void); 73 77 … … 81 85 82 86 Utf8Str mSource; 87 PRTFILE mSourceFile; 88 size_t mSourceOffset; 89 size_t mSourceSize; 83 90 Utf8Str mDest; 84 91 uint32_t mCopyFileFlags; … … 107 114 Utf8Str mSource; 108 115 Utf8Str mDest; 116 uint32_t mFlags; 117 }; 118 119 /** 120 * Task for automatically updating the Guest Additions on the guest. 121 */ 122 class SessionTaskUpdateAdditions : public GuestSessionTask 123 { 124 public: 125 126 SessionTaskUpdateAdditions(GuestSession *pSession, 127 const Utf8Str &strSource, uint32_t uFlags); 128 129 virtual ~SessionTaskUpdateAdditions(void); 130 131 public: 132 133 int Run(void); 134 int RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress); 135 static int taskThread(RTTHREAD Thread, void *pvUser); 136 137 protected: 138 139 /** The (optionally) specified Guest Additions .ISO on the host 140 * which will be used for the updating process. */ 141 Utf8Str mSource; 142 /** Update flags. */ 109 143 uint32_t mFlags; 110 144 }; … … 216 250 const GuestEnvironment &getEnvironment(void); 217 251 Utf8Str getName(void); 252 Guest *getParent(void) { return mData.mParent; } 218 253 uint32_t getProtocolVersion(void) { return mData.mProtocolVersion; } 219 254 int processClose(ComObjPtr<GuestProcess> pProcess); -
trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp
r42673 r42693 2649 2649 } 2650 2650 2651 STDMETHODIMP Guest::UpdateGuestAdditions(IN_BSTR aSource, ULONG aFlags, IProgress **aProgress)2651 STDMETHODIMP Guest::UpdateGuestAdditions(IN_BSTR aSource, ComSafeArrayIn(AdditionsUpdateFlag_T, aFlags), IProgress **aProgress) 2652 2652 { 2653 2653 #ifndef VBOX_WITH_GUEST_CONTROL … … 2661 2661 2662 2662 /* Validate flags. */ 2663 uint32_t fFlags = AdditionsUpdateFlag_None; 2663 2664 if (aFlags) 2664 2665 { 2665 if (!(aFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly)) 2666 com::SafeArray<CopyFileFlag_T> flags(ComSafeArrayInArg(aFlags)); 2667 for (size_t i = 0; i < flags.size(); i++) 2668 fFlags |= flags[i]; 2669 } 2670 2671 if (fFlags) 2672 { 2673 if (!(fFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly)) 2666 2674 return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags); 2667 2675 } … … 2669 2677 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS); 2670 2678 2671 HRESULT rc = S_OK; 2672 2679 HRESULT hr = S_OK; 2680 #if 1 2681 /* Create an anonymous session. This is required to run the Guest Additions 2682 * update process with administrative rights. */ 2683 ComObjPtr<GuestSession> pSession; 2684 int rc = sessionCreate("" /* User */, "" /* Password */, "" /* Domain */, 2685 "Updating Guest Additions" /* Name */, pSession); 2686 if (RT_FAILURE(rc)) 2687 { 2688 switch (rc) 2689 { 2690 case VERR_MAX_PROCS_REACHED: 2691 hr = setError(VBOX_E_IPRT_ERROR, tr("Maximum number of guest sessions (%ld) reached"), 2692 VBOX_GUESTCTRL_MAX_SESSIONS); 2693 break; 2694 2695 /** @todo Add more errors here. */ 2696 2697 default: 2698 hr = setError(VBOX_E_IPRT_ERROR, tr("Could not create guest session: %Rrc"), rc); 2699 break; 2700 } 2701 } 2702 else 2703 { 2704 AssertPtr(!pSession.isNull()); 2705 rc = pSession->queryInfo(); 2706 if (RT_FAILURE(rc)) 2707 { 2708 hr = setError(VBOX_E_IPRT_ERROR, tr("Could not query guest session information: %Rrc"), rc); 2709 } 2710 else 2711 { 2712 ComObjPtr<Progress> pProgress; 2713 SessionTaskUpdateAdditions *pTask = new SessionTaskUpdateAdditions(pSession /* GuestSession */, 2714 Utf8Str(aSource), fFlags); 2715 AssertPtrReturn(pTask, VERR_NO_MEMORY); 2716 rc = pSession->startTaskAsync(tr("Updating Guest Additions"), pTask, pProgress); 2717 if (RT_SUCCESS(rc)) 2718 { 2719 /* Return progress to the caller. */ 2720 hr = pProgress.queryInterfaceTo(aProgress); 2721 } 2722 else 2723 hr = setError(VBOX_E_IPRT_ERROR, 2724 tr("Starting task for updating Guest Additions on the guest failed: %Rrc"), rc); 2725 } 2726 } 2727 #else /* Legacy, can be removed later. */ 2673 2728 ComObjPtr<Progress> progress; 2674 2729 try … … 2709 2764 } 2710 2765 return rc; 2766 #endif 2711 2767 #endif /* VBOX_WITH_GUEST_CONTROL */ 2712 2768 } -
trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp
r42674 r42693 165 165 LogFlowThisFunc(("cbStream=%RU32\n", mData.mStream.GetSize())); 166 166 167 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 168 167 169 int rc; 168 170 do … … 209 211 Assert(!pProcess.isNull()); 210 212 211 HRESULT hr = S_OK;212 213 int rc;214 213 GuestProcessStreamBlock streamBlock; 215 216 /** @todo Make use of exceptions! */ 217 218 try 219 { 220 GuestFsObjData objData; 221 222 AutoWriteLock rlock(this COMMA_LOCKVAL_SRC_POS); 223 224 rc = parseData(streamBlock); 225 if ( RT_FAILURE(rc) 226 || streamBlock.IsEmpty()) /* More data needed. */ 227 { 228 rlock.release(); 229 230 rc = pProcess->waitForStart(30 * 1000 /* Timeout */); 214 GuestFsObjData objData; 215 216 int rc = parseData(streamBlock); 217 if ( RT_FAILURE(rc) 218 || streamBlock.IsEmpty()) /* More data needed. */ 219 { 220 rc = pProcess->waitForStart(30 * 1000 /* 30s timeout */); 221 } 222 223 if (RT_SUCCESS(rc)) 224 { 225 BYTE byBuf[_64K]; 226 size_t cbRead = 0; 227 228 /** @todo Merge with GuestSession::queryFileInfoInternal. */ 229 for (;RT_SUCCESS(rc);) 230 { 231 GuestProcessWaitResult waitRes; 232 rc = pProcess->waitFor( ProcessWaitForFlag_Terminate 233 | ProcessWaitForFlag_StdOut, 234 30 * 1000 /* Timeout */, waitRes); 235 if ( RT_FAILURE(rc) 236 || waitRes.mResult == ProcessWaitResult_Terminate 237 || waitRes.mResult == ProcessWaitResult_Error 238 || waitRes.mResult == ProcessWaitResult_Timeout) 239 { 240 rc = waitRes.mRC; 241 break; 242 } 243 244 rc = pProcess->readData(OUTPUT_HANDLE_ID_STDOUT, sizeof(byBuf), 245 30 * 1000 /* Timeout */, byBuf, sizeof(byBuf), 246 &cbRead); 231 247 if (RT_FAILURE(rc)) 232 return setError(VBOX_E_IPRT_ERROR, 233 tr("Could not start reading directory \"%s\": %Rrc"), 234 mData.mName.c_str(), rc); 235 BYTE byBuf[_64K]; 236 size_t cbRead = 0; 237 238 /** @todo Merge with GuestSession::queryFileInfoInternal. */ 239 for (;;) 248 break; 249 250 if (cbRead) 240 251 { 241 GuestProcessWaitResult waitRes; 242 rc = pProcess->waitFor( ProcessWaitForFlag_Terminate 243 | ProcessWaitForFlag_StdOut, 244 30 * 1000 /* Timeout */, waitRes); 245 if ( RT_FAILURE(rc) 246 || waitRes.mResult == ProcessWaitResult_Terminate 247 || waitRes.mResult == ProcessWaitResult_Error 248 || waitRes.mResult == ProcessWaitResult_Timeout) 252 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 253 254 rc = mData.mStream.AddData(byBuf, cbRead); 255 if (RT_FAILURE(rc)) 256 break; 257 258 LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64, cbStreamOut=%RU32\n", 259 rc, cbRead, mData.mStream.GetSize())); 260 261 rc = parseData(streamBlock); 262 if (RT_SUCCESS(rc)) 249 263 { 264 /* Parsing the current stream block succeeded so 265 * we don't need more at the moment. */ 250 266 break; 251 267 } 252 253 rc = pProcess->readData(OUTPUT_HANDLE_ID_STDOUT, sizeof(byBuf), 254 30 * 1000 /* Timeout */, byBuf, sizeof(byBuf), 255 &cbRead); 256 if (RT_FAILURE(rc)) 257 break; 258 259 if (cbRead) 268 } 269 } 270 271 LogFlowThisFunc(("Reading done with rc=%Rrc, cbRead=%RU64, cbStream=%RU32\n", 272 rc, cbRead, mData.mStream.GetSize())); 273 274 if (RT_SUCCESS(rc)) 275 { 276 rc = parseData(streamBlock); 277 if (rc == VERR_NO_DATA) /* Since this is the last parsing call, this is ok. */ 278 rc = VINF_SUCCESS; 279 } 280 281 /* 282 * Note: The guest process can still be around to serve the next 283 * upcoming stream block next time. 284 */ 285 if (RT_SUCCESS(rc)) 286 { 287 /** @todo Move into common function. */ 288 ProcessStatus_T procStatus = ProcessStatus_Undefined; 289 LONG exitCode = 0; 290 291 HRESULT hr2 = pProcess->COMGETTER(Status(&procStatus)); 292 ComAssertComRC(hr2); 293 hr2 = pProcess->COMGETTER(ExitCode(&exitCode)); 294 ComAssertComRC(hr2); 295 296 if ( ( procStatus != ProcessStatus_Started 297 && procStatus != ProcessStatus_Paused 298 && procStatus != ProcessStatus_Terminating 299 ) 300 && exitCode != 0) 301 { 302 rc = VERR_ACCESS_DENIED; 303 } 304 } 305 } 306 307 if (RT_SUCCESS(rc)) 308 { 309 if (streamBlock.GetCount()) /* Did we get content? */ 310 { 311 rc = objData.FromLs(streamBlock); 312 if (RT_FAILURE(rc)) 313 rc = VERR_PATH_NOT_FOUND; 314 315 if (RT_SUCCESS(rc)) 316 { 317 /* Create the object. */ 318 ComObjPtr<GuestFsObjInfo> pFsObjInfo; 319 HRESULT hr2 = pFsObjInfo.createObject(); 320 if (FAILED(hr2)) 321 rc = VERR_COM_UNEXPECTED; 322 323 if (RT_SUCCESS(rc)) 324 rc = pFsObjInfo->init(objData); 325 326 if (RT_SUCCESS(rc)) 260 327 { 261 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 262 263 rc = mData.mStream.AddData(byBuf, cbRead); 264 if (RT_FAILURE(rc)) 265 break; 266 267 LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64, cbStreamOut=%RU32\n", 268 rc, cbRead, mData.mStream.GetSize())); 269 270 rc = parseData(streamBlock); 271 if (RT_SUCCESS(rc)) 272 { 273 /* Parsing the current stream block succeeded so 274 * we don't need more at the moment. */ 275 break; 276 } 328 /* Return info object to the caller. */ 329 hr2 = pFsObjInfo.queryInterfaceTo(aInfo); 330 if (FAILED(hr2)) 331 rc = VERR_COM_UNEXPECTED; 277 332 } 278 333 } 279 280 LogFlowThisFunc(("Reading done with rc=%Rrc, cbRead=%RU64, cbStream=%RU32\n", 281 rc, cbRead, mData.mStream.GetSize())); 282 283 if (RT_SUCCESS(rc)) 284 { 285 rc = parseData(streamBlock); 286 if (rc == VERR_NO_DATA) /* Since this is the last parsing call, this is ok. */ 287 rc = VINF_SUCCESS; 288 } 289 290 /* 291 * Note: The guest process can still be around to serve the next 292 * upcoming stream block next time. 293 */ 294 if (RT_SUCCESS(rc)) 295 { 296 /** @todo Move into common function. */ 297 ProcessStatus_T procStatus = ProcessStatus_Undefined; 298 LONG exitCode = 0; 299 300 HRESULT hr = pProcess->COMGETTER(Status(&procStatus)); 301 ComAssertComRC(hr); 302 hr = pProcess->COMGETTER(ExitCode(&exitCode)); 303 ComAssertComRC(hr); 304 305 if ( ( procStatus != ProcessStatus_Started 306 && procStatus != ProcessStatus_Paused 307 && procStatus != ProcessStatus_Terminating 308 ) 309 && exitCode != 0) 310 { 311 return setError(VBOX_E_IPRT_ERROR, 312 tr("Reading directory \"%s\" failed: Unable to read / access denied"), 313 mData.mName.c_str(), exitCode); /**@todo Add stringify methods! */ 314 } 315 } 316 } 317 318 if (RT_SUCCESS(rc)) 319 { 320 if (streamBlock.GetCount()) /* Did we get content? */ 321 { 322 rc = objData.FromLs(streamBlock); 323 if (RT_FAILURE(rc)) 324 return setError(VBOX_E_IPRT_ERROR, 325 tr("Reading directory \"%s\" failed: Path not found"), 326 mData.mName.c_str()); 327 328 /* Create the object. */ 329 ComObjPtr<GuestFsObjInfo> pFsObjInfo; 330 hr = pFsObjInfo.createObject(); 331 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 332 333 rc = pFsObjInfo->init(objData); 334 if (RT_FAILURE(rc)) throw rc; 335 336 /* Return info object to the caller. */ 337 hr = pFsObjInfo.queryInterfaceTo(aInfo); 338 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 339 } 340 else 341 { 342 /* Nothing to read anymore. Tell the caller. */ 334 } 335 else 336 { 337 /* Nothing to read anymore. Tell the caller. */ 338 rc = VERR_NO_MORE_FILES; 339 } 340 } 341 342 HRESULT hr = S_OK; 343 344 if (RT_FAILURE(rc)) /** @todo Add more errors here. */ 345 { 346 switch (rc) 347 { 348 case VERR_ACCESS_DENIED: 349 hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Unable to read / access denied"), 350 mData.mName.c_str()); 351 break; 352 353 case VERR_PATH_NOT_FOUND: 354 hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Path not found"), 355 mData.mName.c_str()); 356 break; 357 358 case VERR_NO_MORE_FILES: 343 359 hr = setError(VBOX_E_OBJECT_NOT_FOUND, tr("No more entries for directory \"%s\""), 344 360 mData.mName.c_str()); 345 } 346 } 347 } 348 catch (int rc2) 349 { 350 rc = rc2; 351 } 352 353 if (RT_FAILURE(rc)) /** @todo Add more errors here. */ 354 hr = setError(VBOX_E_IPRT_ERROR, tr("Error while reading directory \"%s\": %Rrc\n"), 355 mData.mName.c_str(), rc); 361 break; 362 363 default: 364 hr = setError(VBOX_E_IPRT_ERROR, tr("Error while reading directory \"%s\": %Rrc\n"), 365 mData.mName.c_str(), rc); 366 break; 367 } 368 } 356 369 357 370 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
r42691 r42693 33 33 #include <iprt/env.h> 34 34 #include <iprt/file.h> /* For CopyTo/From. */ 35 #include <iprt/isofs.h> /* For UpdateAdditions. */ 35 36 36 37 #include <VBox/com/array.h> … … 109 110 } 110 111 111 intGuestSessionTask::setProgressErrorMsg(HRESULT hr, const Utf8Str &strMsg)112 HRESULT GuestSessionTask::setProgressErrorMsg(HRESULT hr, const Utf8Str &strMsg) 112 113 { 113 114 if (mProgress.isNull()) /* Progress is optional. */ 114 return VINF_SUCCESS;115 return hr; /* Return original rc. */ 115 116 116 117 BOOL fCanceled; … … 126 127 strMsg.c_str()); 127 128 if (FAILED(hr2)) 128 return VERR_COM_UNEXPECTED;129 } 130 return VINF_SUCCESS;129 return hr2; 130 } 131 return hr; /* Return original rc. */ 131 132 } 132 133 133 134 SessionTaskCopyTo::SessionTaskCopyTo(GuestSession *pSession, 134 135 const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags) 135 : GuestSessionTask(pSession) 136 : mSourceFile(NULL), 137 mSourceOffset(0), 138 mSourceSize(0), 139 GuestSessionTask(pSession) 136 140 { 137 141 mSource = strSource; … … 140 144 } 141 145 146 SessionTaskCopyTo::SessionTaskCopyTo(GuestSession *pSession, 147 PRTFILE pSourceFile, size_t cbSourceOffset, size_t cbSourceSize, 148 const Utf8Str &strDest, uint32_t uFlags) 149 : GuestSessionTask(pSession) 150 { 151 mSourceFile = pSourceFile; 152 mSourceOffset = cbSourceOffset; 153 mSourceSize = cbSourceSize; 154 mDest = strDest; 155 mCopyFileFlags = uFlags; 156 } 157 142 158 SessionTaskCopyTo::~SessionTaskCopyTo(void) 143 159 { … … 156 172 157 173 if (mCopyFileFlags) 158 return setProgressErrorMsg(VBOX_E_IPRT_ERROR, 159 Utf8StrFmt(GuestSession::tr("Copy flags (%#x) not implemented yet"), 160 mCopyFileFlags)); 174 { 175 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 176 Utf8StrFmt(GuestSession::tr("Copy flags (%#x) not implemented yet"), 177 mCopyFileFlags)); 178 return VERR_INVALID_PARAMETER; 179 } 180 161 181 int rc; 162 182 163 /** @todo Make use of exceptions (+ finally block) here! */ 164 165 try 183 RTFILE fileLocal; 184 PRTFILE pFile = &fileLocal; 185 186 if (!mSourceFile) 166 187 { 167 188 /* Does our source file exist? */ … … 174 195 else 175 196 { 176 RTFILE fileSource; 177 rc = RTFileOpen(&fileSource, mSource.c_str(), 197 rc = RTFileOpen(pFile, mSource.c_str(), 178 198 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE); 179 199 if (RT_FAILURE(rc)) 180 200 { 181 201 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 182 Utf8StrFmt(GuestSession::tr("Could not open source file \"%s\" for reading (%Rrc)"),202 Utf8StrFmt(GuestSession::tr("Could not open source file \"%s\" for reading: %Rrc"), 183 203 mSource.c_str(), rc)); 184 204 } 185 205 else 186 206 { 187 uint64_t cbFileSize; 188 rc = RTFileGetSize(fileSource, &cbFileSize); 207 rc = RTFileGetSize(*pFile, &mSourceSize); 189 208 if (RT_FAILURE(rc)) 190 209 { … … 193 212 mSource.c_str(), rc)); 194 213 } 195 else 214 } 215 } 216 } 217 else 218 { 219 pFile = mSourceFile; 220 /* Size + offset are optional. */ 221 } 222 223 GuestProcessStartupInfo procInfo; 224 procInfo.mName = Utf8StrFmt(GuestSession::tr("Copying file \"%s\" to the guest to \"%s\" (%RU64 bytes)"), 225 mSource.c_str(), mDest.c_str(), mSourceSize); 226 procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_CAT); 227 procInfo.mFlags = ProcessCreateFlag_Hidden; 228 229 /* Set arguments.*/ 230 procInfo.mArguments.push_back(Utf8StrFmt("--output=%s", mDest.c_str())); /** @todo Do we need path conversion? */ 231 232 /* Startup process. */ 233 ComObjPtr<GuestProcess> pProcess; 234 rc = pSession->processCreateExInteral(procInfo, pProcess); 235 if (RT_SUCCESS(rc)) 236 rc = pProcess->startProcess(); 237 if (RT_FAILURE(rc)) 238 { 239 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 240 Utf8StrFmt(GuestSession::tr("Unable to start guest process: %Rrc"), rc)); 241 } 242 else 243 { 244 GuestProcessWaitResult waitRes; 245 BYTE byBuf[_64K]; 246 247 BOOL fCanceled = FALSE; 248 uint64_t cbWrittenTotal = 0; 249 uint64_t cbToRead = mSourceSize; 250 251 for (;;) 252 { 253 rc = pProcess->waitFor(ProcessWaitForFlag_StdIn, 254 30 * 1000 /* Timeout */, waitRes); 255 if ( RT_FAILURE(rc) 256 || waitRes.mResult == ProcessWaitResult_Terminate 257 || waitRes.mResult == ProcessWaitResult_Error 258 || waitRes.mResult == ProcessWaitResult_Timeout) 259 { 260 break; 261 } 262 263 size_t cbRead = 0; 264 if (mSourceSize) /* If we have nothing to write, take a shortcut. */ 265 { 266 /** @todo Not very efficient, but works for now. */ 267 rc = RTFileSeek(*pFile, mSourceOffset + cbWrittenTotal, 268 RTFILE_SEEK_BEGIN, NULL /* poffActual */); 269 if (RT_SUCCESS(rc)) 196 270 { 197 GuestProcessStartupInfo procInfo; 198 procInfo.mName = Utf8StrFmt(GuestSession::tr("Copying file \"%s\" to the guest to \"%s\" (%RU64 bytes)"), 199 mSource.c_str(), mDest.c_str(), cbFileSize); 200 procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_CAT); 201 procInfo.mFlags = ProcessCreateFlag_Hidden; 202 203 /* Set arguments.*/ 204 procInfo.mArguments.push_back(Utf8StrFmt("--output=%s", mDest.c_str())); /** @todo Do we need path conversion? */ 205 206 /* Startup process. */ 207 ComObjPtr<GuestProcess> pProcess; 208 rc = pSession->processCreateExInteral(procInfo, pProcess); 209 if (RT_SUCCESS(rc)) 210 rc = pProcess->startProcess(); 271 rc = RTFileRead(*pFile, (uint8_t*)byBuf, 272 RT_MIN(cbToRead, sizeof(byBuf)), &cbRead); 273 /* 274 * Some other error occured? There might be a chance that RTFileRead 275 * could not resolve/map the native error code to an IPRT code, so just 276 * print a generic error. 277 */ 211 278 if (RT_FAILURE(rc)) 212 279 { 213 280 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 214 Utf8StrFmt(GuestSession::tr("Unable to start guest process: %Rrc"), rc)); 281 Utf8StrFmt(GuestSession::tr("Could not read from file \"%s\" (%Rrc)"), 282 mSource.c_str(), rc)); 283 break; 215 284 } 285 } 286 else 287 { 288 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 289 Utf8StrFmt(GuestSession::tr("Seeking file \"%s\" offset %RU64 failed: %Rrc"), 290 mSource.c_str(), cbWrittenTotal, rc)); 291 break; 292 } 293 } 294 295 uint32_t fFlags = ProcessInputFlag_None; 296 297 /* Did we reach the end of the content we want to transfer (last chunk)? */ 298 if ( (cbRead < sizeof(byBuf)) 299 /* Did we reach the last block which is exactly _64K? */ 300 || (cbToRead - cbRead == 0) 301 /* ... or does the user want to cancel? */ 302 || ( SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled))) 303 && fCanceled) 304 ) 305 { 306 fFlags |= ProcessInputFlag_EndOfFile; 307 } 308 309 uint32_t cbWritten; 310 Assert(sizeof(byBuf) >= cbRead); 311 rc = pProcess->writeData(0 /* StdIn */, fFlags, 312 byBuf, cbRead, 313 30 * 1000 /* Timeout */, &cbWritten); 314 if (RT_FAILURE(rc)) 315 { 316 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 317 Utf8StrFmt(GuestSession::tr("Writing to file \"%s\" (offset %RU64) failed: %Rrc"), 318 mSource.c_str(), cbWrittenTotal, rc)); 319 break; 320 } 321 #ifdef DEBUG 322 LogFlowThisFunc(("cbWritten=%RU32, cbToRead=%RU64, cbWrittenTotal=%RU64, cbFileSize=%RU64\n", 323 cbWritten, cbToRead - cbWritten, cbWrittenTotal + cbWritten, mSourceSize)); 324 #endif 325 /* Only subtract bytes reported written by the guest. */ 326 Assert(cbToRead >= cbWritten); 327 cbToRead -= cbWritten; 328 329 /* Update total bytes written to the guest. */ 330 cbWrittenTotal += cbWritten; 331 Assert(cbWrittenTotal <= mSourceSize); 332 333 /* Did the user cancel the operation above? */ 334 if (fCanceled) 335 break; 336 337 /* Update the progress. 338 * Watch out for division by zero. */ 339 mSourceSize > 0 340 ? rc = setProgress((ULONG)(cbWrittenTotal * 100 / mSourceSize)) 341 : rc = setProgress(100); 342 if (RT_FAILURE(rc)) 343 break; 344 345 /* End of file reached? */ 346 if (!cbToRead) 347 break; 348 } /* for */ 349 350 if ( !fCanceled 351 || RT_SUCCESS(rc)) 352 { 353 /* 354 * Even if we succeeded until here make sure to check whether we really transfered 355 * everything. 356 */ 357 if ( mSourceSize > 0 358 && cbWrittenTotal == 0) 359 { 360 /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write 361 * to the destination -> access denied. */ 362 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 363 Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to \"%s\""), 364 mSource.c_str(), mDest.c_str())); 365 } 366 else if (cbWrittenTotal < mSourceSize) 367 { 368 /* If we did not copy all let the user know. */ 369 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 370 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed (%RU64/%RU64 bytes transfered)"), 371 mSource.c_str(), cbWrittenTotal, mSourceSize)); 372 } 373 else 374 { 375 rc = pProcess->waitFor(ProcessWaitForFlag_Terminate, 376 30 * 1000 /* Timeout */, waitRes); 377 if ( RT_FAILURE(rc) 378 || waitRes.mResult != ProcessWaitResult_Terminate) 379 { 380 if (RT_FAILURE(rc)) 381 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 382 Utf8StrFmt(GuestSession::tr("Waiting on termination for copying file \"%s\" failed: %Rrc"), 383 mSource.c_str(), rc)); 216 384 else 385 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 386 Utf8StrFmt(GuestSession::tr("Waiting on termination for copying file \"%s\" failed with wait result %ld"), 387 mSource.c_str(), waitRes.mResult)); 388 } 389 390 if (RT_SUCCESS(rc)) 391 { 392 ProcessStatus_T procStatus; 393 LONG exitCode; 394 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 395 && procStatus != ProcessStatus_TerminatedNormally) 396 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 397 && exitCode != 0) 398 ) 217 399 { 218 GuestProcessWaitResult waitRes; 219 BYTE byBuf[_64K]; 220 221 BOOL fCanceled = FALSE; 222 uint64_t cbWrittenTotal = 0; 223 uint64_t cbToRead = cbFileSize; 224 225 for (;;) 226 { 227 rc = pProcess->waitFor(ProcessWaitForFlag_StdIn, 228 30 * 1000 /* Timeout */, waitRes); 229 if ( RT_FAILURE(rc) 230 || waitRes.mResult == ProcessWaitResult_Terminate 231 || waitRes.mResult == ProcessWaitResult_Error 232 || waitRes.mResult == ProcessWaitResult_Timeout) 233 { 234 break; 235 } 236 237 size_t cbRead = 0; 238 if (cbFileSize) /* If we have nothing to write, take a shortcut. */ 239 { 240 /** @todo Not very efficient, but works for now. */ 241 rc = RTFileSeek(fileSource, cbWrittenTotal, 242 RTFILE_SEEK_BEGIN, NULL /* poffActual */); 243 if (RT_SUCCESS(rc)) 244 { 245 rc = RTFileRead(fileSource, (uint8_t*)byBuf, 246 RT_MIN(cbToRead, sizeof(byBuf)), &cbRead); 247 /* 248 * Some other error occured? There might be a chance that RTFileRead 249 * could not resolve/map the native error code to an IPRT code, so just 250 * print a generic error. 251 */ 252 if (RT_FAILURE(rc)) 253 { 254 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 255 Utf8StrFmt(GuestSession::tr("Could not read from file \"%s\" (%Rrc)"), 256 mSource.c_str(), rc)); 257 break; 258 } 259 } 260 else 261 { 262 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 263 Utf8StrFmt(GuestSession::tr("Seeking file \"%s\" offset %RU64 failed: %Rrc"), 264 mSource.c_str(), cbWrittenTotal, rc)); 265 break; 266 } 267 } 268 269 uint32_t fFlags = ProcessInputFlag_None; 270 271 /* Did we reach the end of the content we want to transfer (last chunk)? */ 272 if ( (cbRead < sizeof(byBuf)) 273 /* Did we reach the last block which is exactly _64K? */ 274 || (cbToRead - cbRead == 0) 275 /* ... or does the user want to cancel? */ 276 || ( SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled))) 277 && fCanceled) 278 ) 279 { 280 fFlags |= ProcessInputFlag_EndOfFile; 281 } 282 283 uint32_t cbWritten; 284 Assert(sizeof(byBuf) >= cbRead); 285 rc = pProcess->writeData(0 /* StdIn */, fFlags, 286 byBuf, cbRead, 287 30 * 1000 /* Timeout */, &cbWritten); 288 if (RT_FAILURE(rc)) 289 { 290 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 291 Utf8StrFmt(GuestSession::tr("Writing to file \"%s\" (offset %RU64) failed: %Rrc"), 292 mSource.c_str(), cbWrittenTotal, rc)); 293 break; 294 } 295 #ifdef DEBUG 296 LogFlowThisFunc(("cbWritten=%RU32, cbToRead=%RU64, cbWrittenTotal=%RU64, cbFileSize=%RU64\n", 297 cbWritten, cbToRead - cbWritten, cbWrittenTotal + cbWritten, cbFileSize)); 298 #endif 299 /* Only subtract bytes reported written by the guest. */ 300 Assert(cbToRead >= cbWritten); 301 cbToRead -= cbWritten; 302 303 /* Update total bytes written to the guest. */ 304 cbWrittenTotal += cbWritten; 305 Assert(cbWrittenTotal <= cbFileSize); 306 307 /* Did the user cancel the operation above? */ 308 if (fCanceled) 309 break; 310 311 /* Update the progress. 312 * Watch out for division by zero. */ 313 cbFileSize > 0 314 ? rc = setProgress((ULONG)(cbWrittenTotal * 100 / cbFileSize)) 315 : rc = setProgress(100); 316 if (RT_FAILURE(rc)) 317 break; 318 319 /* End of file reached? */ 320 if (!cbToRead) 321 break; 322 } /* for */ 323 324 if ( !fCanceled 325 || RT_SUCCESS(rc)) 326 { 327 /* 328 * Even if we succeeded until here make sure to check whether we really transfered 329 * everything. 330 */ 331 if ( cbFileSize > 0 332 && cbWrittenTotal == 0) 333 { 334 /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write 335 * to the destination -> access denied. */ 336 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 337 Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to \"%s\""), 338 mSource.c_str(), mDest.c_str())); 339 } 340 else if (cbWrittenTotal < cbFileSize) 341 { 342 /* If we did not copy all let the user know. */ 343 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 344 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed (%RU64/%RU64 bytes transfered)"), 345 mSource.c_str(), cbWrittenTotal, cbFileSize)); 346 } 347 else 348 { 349 rc = pProcess->waitFor(ProcessWaitForFlag_Terminate, 350 30 * 1000 /* Timeout */, waitRes); 351 if ( RT_FAILURE(rc) 352 || waitRes.mResult != ProcessWaitResult_Terminate) 353 { 354 if (RT_FAILURE(rc)) 355 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 356 Utf8StrFmt(GuestSession::tr("Waiting on termination for copying file \"%s\" failed: %Rrc"), 357 mSource.c_str(), rc)); 358 else 359 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 360 Utf8StrFmt(GuestSession::tr("Waiting on termination for copying file \"%s\" failed with wait result %ld"), 361 mSource.c_str(), waitRes.mResult)); 362 } 363 364 if (RT_SUCCESS(rc)) 365 { 366 ProcessStatus_T procStatus; 367 LONG exitCode; 368 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 369 && procStatus != ProcessStatus_TerminatedNormally) 370 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 371 && exitCode != 0) 372 ) 373 { 374 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 375 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed with status %ld, exit code %ld"), 376 mSource.c_str(), procStatus, exitCode)); /**@todo Add stringify methods! */ 377 } 378 } 379 380 if (RT_SUCCESS(rc)) 381 rc = setProgressSuccess(); 382 } 383 } 384 385 pProcess->close(); 386 } /* processCreateExInteral */ 387 } /* RTFileGetSize */ 388 389 RTFileClose(fileSource); 390 391 } /* RTFileOpen */ 392 } /* RTFileExists */ 393 } 394 catch (int rc2) 395 { 396 rc = rc2; 397 } 400 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 401 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed with status %ld, exit code %ld"), 402 mSource.c_str(), procStatus, exitCode)); /**@todo Add stringify methods! */ 403 } 404 } 405 406 if (RT_SUCCESS(rc)) 407 rc = setProgressSuccess(); 408 } 409 } 410 411 pProcess->close(); 412 } /* processCreateExInteral */ 413 414 if (!mSourceFile) /* Only close locally opened files. */ 415 RTFileClose(*pFile); 398 416 399 417 LogFlowFuncLeaveRC(rc); … … 450 468 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 451 469 452 int rc; 453 454 /** @todo Make use of exceptions (+ finally block) here! */ 455 456 try 457 { 458 /* 459 * Note: There will be races between querying file size + reading the guest file's 460 * content because we currently *do not* lock down the guest file when doing the 461 * actual operations. 462 ** @todo Implement guest file locking! 463 */ 464 GuestFsObjData objData; 465 rc = pSession->fileQueryInfoInternal(Utf8Str(mSource), objData); 470 /* 471 * Note: There will be races between querying file size + reading the guest file's 472 * content because we currently *do not* lock down the guest file when doing the 473 * actual operations. 474 ** @todo Implement guest file locking! 475 */ 476 GuestFsObjData objData; 477 int rc = pSession->fileQueryInfoInternal(Utf8Str(mSource), objData); 478 if (RT_FAILURE(rc)) 479 { 480 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 481 Utf8StrFmt(GuestSession::tr("Querying guest file information for \"%s\" failed: %Rrc"), 482 mSource.c_str(), rc)); 483 } 484 else if (objData.mType != FsObjType_File) /* Only single files are supported at the moment. */ 485 { 486 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 487 Utf8StrFmt(GuestSession::tr("Guest file \"%s\" is not a file"), mSource.c_str())); 488 } 489 490 if (RT_SUCCESS(rc)) 491 { 492 RTFILE fileDest; 493 rc = RTFileOpen(&fileDest, mDest.c_str(), 494 RTFILE_O_WRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE); /** @todo Use the correct open modes! */ 466 495 if (RT_FAILURE(rc)) 467 496 { 468 497 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 469 Utf8StrFmt(GuestSession::tr("Querying guest file information for \"%s\" failed: %Rrc"), 470 mSource.c_str(), rc)); 471 } 472 else if (objData.mType != FsObjType_File) /* Only single files are supported at the moment. */ 473 { 474 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 475 Utf8StrFmt(GuestSession::tr("Guest file \"%s\" is not a file"), mSource.c_str())); 476 } 477 478 if (RT_SUCCESS(rc)) 479 { 480 RTFILE fileDest; 481 rc = RTFileOpen(&fileDest, mDest.c_str(), 482 RTFILE_O_WRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE); /** @todo Use the correct open modes! */ 498 Utf8StrFmt(GuestSession::tr("Error opening destination file \"%s\": %Rrc"), 499 mDest.c_str(), rc)); 500 } 501 else 502 { 503 GuestProcessStartupInfo procInfo; 504 procInfo.mName = Utf8StrFmt(GuestSession::tr("Copying file \"%s\" from guest to the host to \"%s\" (%RI64 bytes)"), 505 mSource.c_str(), mDest.c_str(), objData.mObjectSize); 506 procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_CAT); 507 procInfo.mFlags = ProcessCreateFlag_Hidden | ProcessCreateFlag_WaitForStdOut; 508 509 /* Set arguments.*/ 510 procInfo.mArguments.push_back(mSource); /* Which file to output? */ 511 512 /* Startup process. */ 513 ComObjPtr<GuestProcess> pProcess; 514 rc = pSession->processCreateExInteral(procInfo, pProcess); 515 if (RT_SUCCESS(rc)) 516 rc = pProcess->startProcess(); 483 517 if (RT_FAILURE(rc)) 484 518 { 485 519 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 486 Utf8StrFmt(GuestSession::tr("Error opening destination file \"%s\": %Rrc"), 487 mDest.c_str(), rc)); 520 Utf8StrFmt(GuestSession::tr("Unable to start guest process: %Rrc"), rc)); 488 521 } 489 522 else 490 523 { 491 GuestProcessStartupInfo procInfo; 492 procInfo.mName = Utf8StrFmt(GuestSession::tr("Copying file \"%s\" from guest to the host to \"%s\" (%RI64 bytes)"), 493 mSource.c_str(), mDest.c_str(), objData.mObjectSize); 494 procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_CAT); 495 procInfo.mFlags = ProcessCreateFlag_Hidden | ProcessCreateFlag_WaitForStdOut; 496 497 /* Set arguments.*/ 498 procInfo.mArguments.push_back(mSource); /* Which file to output? */ 499 500 /* Startup process. */ 501 ComObjPtr<GuestProcess> pProcess; 502 rc = pSession->processCreateExInteral(procInfo, pProcess); 503 if (RT_SUCCESS(rc)) 504 rc = pProcess->startProcess(); 505 if (RT_FAILURE(rc)) 524 GuestProcessWaitResult waitRes; 525 BYTE byBuf[_64K]; 526 527 BOOL fCanceled = FALSE; 528 uint64_t cbWrittenTotal = 0; 529 uint64_t cbToRead = objData.mObjectSize; 530 531 for (;;) 506 532 { 507 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 508 Utf8StrFmt(GuestSession::tr("Unable to start guest process: %Rrc"), rc)); 509 } 510 else 511 { 512 GuestProcessWaitResult waitRes; 513 BYTE byBuf[_64K]; 514 515 BOOL fCanceled = FALSE; 516 uint64_t cbWrittenTotal = 0; 517 uint64_t cbToRead = objData.mObjectSize; 518 519 for (;;) 533 rc = pProcess->waitFor(ProcessWaitForFlag_StdOut, 534 30 * 1000 /* Timeout */, waitRes); 535 if ( RT_FAILURE(rc) 536 || waitRes.mResult != ProcessWaitResult_StdOut) 520 537 { 521 rc = pProcess->waitFor(ProcessWaitForFlag_StdOut, 522 30 * 1000 /* Timeout */, waitRes); 523 if ( RT_FAILURE(rc) 524 || waitRes.mResult != ProcessWaitResult_StdOut) 525 { 526 break; 527 } 528 529 size_t cbRead; 530 rc = pProcess->readData(OUTPUT_HANDLE_ID_STDOUT, sizeof(byBuf), 531 30 * 1000 /* Timeout */, byBuf, sizeof(byBuf), 532 &cbRead); 538 break; 539 } 540 541 size_t cbRead; 542 rc = pProcess->readData(OUTPUT_HANDLE_ID_STDOUT, sizeof(byBuf), 543 30 * 1000 /* Timeout */, byBuf, sizeof(byBuf), 544 &cbRead); 545 if (RT_FAILURE(rc)) 546 { 547 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 548 Utf8StrFmt(GuestSession::tr("Reading from file \"%s\" (offset %RU64) failed: %Rrc"), 549 mSource.c_str(), cbWrittenTotal, rc)); 550 break; 551 } 552 553 if (cbRead) 554 { 555 rc = RTFileWrite(fileDest, byBuf, cbRead, NULL /* No partial writes */); 533 556 if (RT_FAILURE(rc)) 534 557 { 535 558 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 536 Utf8StrFmt(GuestSession::tr(" Reading from file \"%s\" (offset %RU64) failed: %Rrc"),537 m Source.c_str(), cbWrittenTotal, rc));559 Utf8StrFmt(GuestSession::tr("Error writing to file \"%s\" (%RU64 bytes left): %Rrc"), 560 mDest.c_str(), cbToRead, rc)); 538 561 break; 539 562 } 540 563 541 if (cbRead) 564 /* Only subtract bytes reported written by the guest. */ 565 Assert(cbToRead >= cbRead); 566 cbToRead -= cbRead; 567 568 /* Update total bytes written to the guest. */ 569 cbWrittenTotal += cbRead; 570 Assert(cbWrittenTotal <= (uint64_t)objData.mObjectSize); 571 572 /* Did the user cancel the operation above? */ 573 if ( SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled))) 574 && fCanceled) 575 break; 576 577 rc = setProgress((ULONG)(cbWrittenTotal / ((uint64_t)objData.mObjectSize / 100.0))); 578 if (RT_FAILURE(rc)) 579 break; 580 581 /* End of file reached? */ 582 if (cbToRead == 0) 583 break; 584 } 585 } /* for */ 586 587 if ( !fCanceled 588 || RT_SUCCESS(rc)) 589 { 590 /* 591 * Even if we succeeded until here make sure to check whether we really transfered 592 * everything. 593 */ 594 if ( objData.mObjectSize > 0 595 && cbWrittenTotal == 0) 596 { 597 /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write 598 * to the destination -> access denied. */ 599 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 600 Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to \"%s\""), 601 mSource.c_str(), mDest.c_str())); 602 } 603 else if (cbWrittenTotal < (uint64_t)objData.mObjectSize) 604 { 605 /* If we did not copy all let the user know. */ 606 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 607 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed (%RU64/%RU64 bytes transfered)"), 608 mSource.c_str(), cbWrittenTotal, objData.mObjectSize)); 609 } 610 else 611 { 612 ProcessStatus_T procStatus; 613 LONG exitCode; 614 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 615 && procStatus != ProcessStatus_TerminatedNormally) 616 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 617 && exitCode != 0) 618 ) 542 619 { 543 rc = RTFileWrite(fileDest, byBuf, cbRead, NULL /* No partial writes */); 544 if (RT_FAILURE(rc)) 545 { 546 setProgressErrorMsg(VBOX_E_IPRT_ERROR, 547 Utf8StrFmt(GuestSession::tr("Error writing to file \"%s\" (%RU64 bytes left): %Rrc"), 548 mDest.c_str(), cbToRead, rc)); 549 break; 550 } 551 552 /* Only subtract bytes reported written by the guest. */ 553 Assert(cbToRead >= cbRead); 554 cbToRead -= cbRead; 555 556 /* Update total bytes written to the guest. */ 557 cbWrittenTotal += cbRead; 558 Assert(cbWrittenTotal <= (uint64_t)objData.mObjectSize); 559 560 /* Did the user cancel the operation above? */ 561 if ( SUCCEEDED(mProgress->COMGETTER(Canceled(&fCanceled))) 562 && fCanceled) 563 break; 564 565 rc = setProgress((ULONG)(cbWrittenTotal / ((uint64_t)objData.mObjectSize / 100.0))); 566 if (RT_FAILURE(rc)) 567 break; 568 569 /* End of file reached? */ 570 if (cbToRead == 0) 571 break; 620 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 621 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed with status %ld, exit code %d"), 622 mSource.c_str(), procStatus, exitCode)); /**@todo Add stringify methods! */ 572 623 } 573 } /* for */ 574 575 if ( !fCanceled 576 || RT_SUCCESS(rc)) 577 { 578 /* 579 * Even if we succeeded until here make sure to check whether we really transfered 580 * everything. 581 */ 582 if ( objData.mObjectSize > 0 583 && cbWrittenTotal == 0) 584 { 585 /* If nothing was transfered but the file size was > 0 then "vbox_cat" wasn't able to write 586 * to the destination -> access denied. */ 587 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 588 Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to \"%s\""), 589 mSource.c_str(), mDest.c_str())); 590 } 591 else if (cbWrittenTotal < (uint64_t)objData.mObjectSize) 592 { 593 /* If we did not copy all let the user know. */ 594 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 595 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed (%RU64/%RU64 bytes transfered)"), 596 mSource.c_str(), cbWrittenTotal, objData.mObjectSize)); 597 } 598 else 599 { 600 ProcessStatus_T procStatus; 601 LONG exitCode; 602 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 603 && procStatus != ProcessStatus_TerminatedNormally) 604 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 605 && exitCode != 0) 606 ) 607 { 608 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 609 Utf8StrFmt(GuestSession::tr("Copying file \"%s\" failed with status %ld, exit code %d"), 610 mSource.c_str(), procStatus, exitCode)); /**@todo Add stringify methods! */ 611 } 612 else /* Yay, success! */ 613 rc = setProgressSuccess(); 614 } 624 else /* Yay, success! */ 625 rc = setProgressSuccess(); 615 626 } 616 617 pProcess->close();618 627 } 619 628 620 RTFileClose(fileDest);629 pProcess->close(); 621 630 } 622 } 623 } 624 catch (int rc2) 625 { 626 rc = rc2; 631 632 RTFileClose(fileDest); 633 } 627 634 } 628 635 … … 650 657 { 651 658 std::auto_ptr<SessionTaskCopyFrom> task(static_cast<SessionTaskCopyFrom*>(pvUser)); 659 AssertReturn(task.get(), VERR_GENERAL_FAILURE); 660 661 LogFlowFunc(("pTask=%p\n", task.get())); 662 return task->Run(); 663 } 664 665 SessionTaskUpdateAdditions::SessionTaskUpdateAdditions(GuestSession *pSession, 666 const Utf8Str &strSource, uint32_t uFlags) 667 : GuestSessionTask(pSession) 668 { 669 mSource = strSource; 670 mFlags = uFlags; 671 } 672 673 SessionTaskUpdateAdditions::~SessionTaskUpdateAdditions(void) 674 { 675 676 } 677 678 int SessionTaskUpdateAdditions::Run(void) 679 { 680 LogFlowThisFuncEnter(); 681 682 ComObjPtr<GuestSession> pSession = mSession; 683 Assert(!pSession.isNull()); 684 685 AutoCaller autoCaller(pSession); 686 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 687 688 int rc = setProgress(10); 689 if (RT_FAILURE(rc)) 690 return rc; 691 692 HRESULT hr = S_OK; 693 694 LogRel(("Automatic update of Guest Additions started, using \"%s\"\n", mSource.c_str())); 695 696 /* 697 * Determine guest OS type and the required installer image. 698 * At the moment only Windows guests are supported. 699 */ 700 Utf8Str strInstallerImage; 701 702 ComObjPtr<Guest> pGuest(mSession->getParent()); 703 Bstr osTypeId; 704 if ( SUCCEEDED(pGuest->COMGETTER(OSTypeId(osTypeId.asOutParam()))) 705 && !osTypeId.isEmpty()) 706 { 707 Utf8Str osTypeIdUtf8(osTypeId); /* Needed for .contains(). */ 708 if ( osTypeIdUtf8.contains("Microsoft", Utf8Str::CaseInsensitive) 709 || osTypeIdUtf8.contains("Windows", Utf8Str::CaseInsensitive)) 710 { 711 if (osTypeIdUtf8.contains("64", Utf8Str::CaseInsensitive)) 712 strInstallerImage = "VBOXWINDOWSADDITIONS_AMD64.EXE"; 713 else 714 strInstallerImage = "VBOXWINDOWSADDITIONS_X86.EXE"; 715 /* Since the installers are located in the root directory, 716 * no further path processing needs to be done (yet). */ 717 } 718 else /* Everything else is not supported (yet). */ 719 { 720 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 721 Utf8StrFmt(GuestSession::tr("Detected guest OS (%s) does not support automatic Guest Additions updating, please update manually"), 722 osTypeIdUtf8.c_str())); 723 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 724 } 725 } 726 else 727 { 728 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 729 Utf8StrFmt(GuestSession::tr("Could not detected guest OS type/version, please update manually"))); 730 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 731 } 732 733 RTISOFSFILE iso; 734 uint32_t cbOffset; 735 size_t cbSize; 736 737 if (RT_SUCCESS(rc)) 738 { 739 Assert(!strInstallerImage.isEmpty()); 740 741 /* 742 * Try to open the .ISO file and locate the specified installer. 743 */ 744 rc = RTIsoFsOpen(&iso, mSource.c_str()); 745 if (RT_FAILURE(rc)) 746 { 747 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 748 Utf8StrFmt(GuestSession::tr("Invalid installation medium \"%s\" detected: %Rrc"), 749 mSource.c_str(), rc)); 750 } 751 else 752 { 753 rc = RTIsoFsGetFileInfo(&iso, strInstallerImage.c_str(), &cbOffset, &cbSize); 754 if ( RT_SUCCESS(rc) 755 && cbOffset 756 && cbSize) 757 { 758 rc = RTFileSeek(iso.file, cbOffset, RTFILE_SEEK_BEGIN, NULL); 759 if (RT_FAILURE(rc)) 760 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 761 Utf8StrFmt(GuestSession::tr("Could not seek to setup file on installation medium \"%s\": %Rrc"), 762 mSource.c_str(), rc)); 763 } 764 else 765 { 766 switch (rc) 767 { 768 case VERR_FILE_NOT_FOUND: 769 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 770 Utf8StrFmt(GuestSession::tr("Setup file was not found on installation medium \"%s\""), 771 mSource.c_str())); 772 break; 773 774 default: 775 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 776 Utf8StrFmt(GuestSession::tr("An unknown error (%Rrc) occured while retrieving information of setup file on installation medium \"%s\""), 777 rc, mSource.c_str())); 778 break; 779 } 780 } 781 782 /* Specify the ouput path on the guest side. */ 783 /** @todo Add support for non-Windows as well! */ 784 Utf8Str strInstallerDest = "%TEMP%\\VBoxWindowsAdditions.exe"; 785 786 /* Copy over the Guest Additions installer to the guest. */ 787 if (RT_SUCCESS(rc)) 788 { 789 LogRel(("Copying Guest Additions installer \"%s\" to \"%s\" on guest ...\n", 790 strInstallerImage.c_str(), strInstallerDest.c_str())); 791 792 rc = setProgress(15); 793 if (RT_SUCCESS(rc)) 794 { 795 SessionTaskCopyTo *pTask = new SessionTaskCopyTo(pSession /* GuestSession */, 796 &iso.file, cbOffset, cbSize, 797 strInstallerDest, CopyFileFlag_None); 798 AssertPtrReturn(pTask, VERR_NO_MEMORY); 799 800 ComObjPtr<Progress> pProgressCopyTo; 801 rc = pSession->startTaskAsync(Utf8StrFmt(GuestSession::tr("Copying Guest Additions installer from \"%s\" to \"%s\" on the guest"), 802 mSource.c_str(), strInstallerDest.c_str()), 803 pTask, pProgressCopyTo); 804 if (RT_FAILURE(rc)) 805 { 806 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 807 Utf8StrFmt(GuestSession::tr("Unable to start copying Guest Additions installer \"%s\" to \"%s\": %Rrc"), 808 mSource.c_str(), strInstallerDest.c_str(), rc)); 809 } 810 else 811 { 812 BOOL fCanceled = FALSE; 813 hr = pProgressCopyTo->WaitForCompletion(-1); 814 if (SUCCEEDED(hr)) 815 { 816 rc = setProgress(20); 817 } 818 else if ( SUCCEEDED(pProgressCopyTo->COMGETTER(Canceled)(&fCanceled)) 819 && fCanceled) 820 { 821 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 822 Utf8StrFmt(GuestSession::tr("Copying Guest Additions installer \"%s\" to \"%s\" was canceled"), 823 mSource.c_str(), strInstallerDest.c_str(), hr)); 824 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 825 } 826 else 827 { 828 Assert(FAILED(hr)); 829 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 830 Utf8StrFmt(GuestSession::tr("Error while copying Guest Additions installer \"%s\" to \"%s\": %Rhrc"), 831 mSource.c_str(), strInstallerDest.c_str(), hr)); 832 rc = VERR_GENERAL_FAILURE; /* Fudge. */ 833 } 834 } 835 } 836 } 837 838 if (RT_SUCCESS(rc)) 839 { 840 /* Install needed certificates for the WHQL crap. */ 841 /** @todo Copy over VBoxCertUtil? */ 842 rc = setProgress(25); 843 } 844 845 if (RT_SUCCESS(rc)) 846 { 847 /* 848 * Installer was transferred successfully, so let's start it 849 * (with system rights). 850 */ 851 LogRel(("Starting Guest Additions installer ...\n")); 852 rc = setProgress(60); 853 } 854 855 if (RT_SUCCESS(rc)) 856 { 857 GuestProcessStartupInfo procInfo; 858 procInfo.mName = Utf8StrFmt(GuestSession::tr("Guest Additions Setup")); 859 procInfo.mCommand = Utf8Str(strInstallerDest); 860 procInfo.mFlags = ProcessCreateFlag_Hidden; 861 /* If the caller does not want to wait for out guest update process to end, 862 * complete the progress object now so that the caller can do other work. */ 863 if (mFlags & AdditionsUpdateFlag_WaitForUpdateStartOnly) 864 procInfo.mFlags |= ProcessCreateFlag_WaitForProcessStartOnly; 865 866 /* Construct arguments. */ 867 procInfo.mArguments.push_back(Utf8Str("/S")); /* We want to install in silent mode. */ 868 procInfo.mArguments.push_back(Utf8Str("/l")); /* ... and logging enabled. */ 869 /* Don't quit VBoxService during upgrade because it still is used for this 870 * piece of code we're in right now (that is, here!) ... */ 871 procInfo.mArguments.push_back(Utf8Str("/no_vboxservice_exit")); 872 /* Tell the installer to report its current installation status 873 * using a running VBoxTray instance via balloon messages in the 874 * Windows taskbar. */ 875 procInfo.mArguments.push_back(Utf8Str("/post_installstatus")); 876 877 ComObjPtr<GuestProcess> pProcess; 878 rc = pSession->processCreateExInteral(procInfo, pProcess); 879 if (RT_SUCCESS(rc)) 880 rc = pProcess->startProcess(); 881 if (RT_SUCCESS(rc)) 882 rc = setProgress(65); 883 if (RT_SUCCESS(rc)) 884 { 885 LogRel(("Updating Guest Additions in progress ...\n")); 886 887 GuestProcessWaitResult waitRes; 888 rc = pProcess->waitFor(ProcessWaitForFlag_Terminate, 889 10 * 60 * 1000 /* 10 mins Timeout */, waitRes); 890 if (waitRes.mResult == ProcessWaitResult_Terminate) 891 { 892 ProcessStatus_T procStatus; 893 LONG exitCode; 894 if ( ( SUCCEEDED(pProcess->COMGETTER(Status(&procStatus))) 895 && procStatus != ProcessStatus_TerminatedNormally) 896 || ( SUCCEEDED(pProcess->COMGETTER(ExitCode(&exitCode))) 897 && exitCode != 0) 898 ) 899 { 900 rc = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 901 Utf8StrFmt(GuestSession::tr("Updating Guest Additions failed with status %ld, exit code %d"), 902 procStatus, exitCode)); /**@todo Add stringify methods! */ 903 } 904 else /* Yay, success! */ 905 rc = setProgressSuccess(); 906 } 907 else 908 { 909 if (RT_FAILURE(rc)) 910 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 911 Utf8StrFmt(GuestSession::tr("Error while waiting for Guest Additions update: %Rrc"), rc)); 912 else 913 hr = setProgressErrorMsg(VBOX_E_IPRT_ERROR, 914 Utf8StrFmt(GuestSession::tr("Error installing Guest Additions update: %Rrc"), 915 waitRes.mRC)); 916 } 917 } 918 } 919 RTIsoFsClose(&iso); 920 } 921 } 922 923 LogFlowFuncLeaveRC(rc); 924 return rc; 925 } 926 927 int SessionTaskUpdateAdditions::RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress) 928 { 929 LogFlowThisFunc(("strDesc=%s, strSource=%s, uFlags=%x\n", 930 strDesc.c_str(), mSource.c_str(), mFlags)); 931 932 mDesc = strDesc; 933 mProgress = pProgress; 934 935 int rc = RTThreadCreate(NULL, SessionTaskUpdateAdditions::taskThread, this, 936 0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0, 937 "gctlUpGA"); 938 LogFlowFuncLeaveRC(rc); 939 return rc; 940 } 941 942 /* static */ 943 int SessionTaskUpdateAdditions::taskThread(RTTHREAD Thread, void *pvUser) 944 { 945 std::auto_ptr<SessionTaskUpdateAdditions> task(static_cast<SessionTaskUpdateAdditions*>(pvUser)); 652 946 AssertReturn(task.get(), VERR_GENERAL_FAILURE); 653 947 … … 1064 1358 return rc; 1065 1359 1066 try 1067 { 1068 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1069 1070 /* Create the directory object. */ 1071 HRESULT hr = pDirectory.createObject(); 1072 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 1073 1074 /* Note: There will be a race between creating and getting/initing the directory 1075 object here. */ 1076 rc = pDirectory->init(this /* Parent */, strPath); 1077 if (RT_FAILURE(rc)) throw rc; 1078 1079 /* Add the created directory to our vector. */ 1080 mData.mDirectories.push_back(pDirectory); 1081 1082 LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n", 1083 strPath.c_str(), mData.mId)); 1084 } 1085 catch (int rc2) 1086 { 1087 rc = rc2; 1088 } 1360 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1361 1362 /* Create the directory object. */ 1363 HRESULT hr = pDirectory.createObject(); 1364 if (FAILED(hr)) 1365 return VERR_COM_UNEXPECTED; 1366 1367 /* Note: There will be a race between creating and getting/initing the directory 1368 object here. */ 1369 rc = pDirectory->init(this /* Parent */, strPath); 1370 if (RT_FAILURE(rc)) 1371 return rc; 1372 1373 /* Add the created directory to our vector. */ 1374 mData.mDirectories.push_back(pDirectory); 1375 1376 LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n", 1377 strPath.c_str(), mData.mId)); 1089 1378 1090 1379 LogFlowFuncLeaveRC(rc); … … 1097 1386 LogFlowThisFunc(("strPath=%s, strPath=%s, uFlags=%x\n", 1098 1387 strPath.c_str(), strFilter.c_str(), uFlags)); 1099 int rc; 1100 1101 try 1102 { 1103 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1104 1105 /* Create the directory object. */ 1106 HRESULT hr = pDirectory.createObject(); 1107 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 1108 1109 rc = pDirectory->init(this /* Parent */, 1388 1389 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 1390 1391 /* Create the directory object. */ 1392 HRESULT hr = pDirectory.createObject(); 1393 if (FAILED(hr)) 1394 return VERR_COM_UNEXPECTED; 1395 1396 int rc = pDirectory->init(this /* Parent */, 1110 1397 strPath, strFilter, uFlags); 1111 if (RT_FAILURE(rc)) throw rc; 1112 1113 /* Add the created directory to our vector. */ 1114 mData.mDirectories.push_back(pDirectory); 1115 1116 LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n", 1117 strPath.c_str(), mData.mId)); 1118 } 1119 catch (int rc2) 1120 { 1121 rc = rc2; 1122 } 1398 if (RT_FAILURE(rc)) 1399 return rc; 1400 1401 /* Add the created directory to our vector. */ 1402 mData.mDirectories.push_back(pDirectory); 1403 1404 LogFlowFunc(("Added new directory \"%s\" (Session: %RU32)\n", 1405 strPath.c_str(), mData.mId)); 1123 1406 1124 1407 LogFlowFuncLeaveRC(rc); … … 1262 1545 LogFlowThisFunc(("strPath=%s, strOpenMode=%s, strDisposition=%s, uCreationMode=%x, iOffset=%RI64\n", 1263 1546 strPath.c_str(), strOpenMode.c_str(), strDisposition.c_str(), uCreationMode, iOffset)); 1264 int rc; 1265 1266 try 1267 { 1268 /* Create the directory object. */ 1269 HRESULT hr = pFile.createObject(); 1270 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 1271 1272 /* Note: There will be a race between creating and getting/initing the directory 1273 object here. */ 1274 rc = pFile->init(this /* Parent */, 1547 1548 /* Create the directory object. */ 1549 HRESULT hr = pFile.createObject(); 1550 if (FAILED(hr)) 1551 return VERR_COM_UNEXPECTED; 1552 1553 /* Note: There will be a race between creating and getting/initing the directory 1554 object here. */ 1555 int rc = pFile->init(this /* Parent */, 1275 1556 strPath, strOpenMode, strDisposition, uCreationMode, iOffset); 1276 if (RT_FAILURE(rc)) throw rc; 1277 1278 /* Add the created directory to our vector. */ 1279 mData.mFiles.push_back(pFile); 1280 1281 LogFlowFunc(("Added new file \"%s\" (Session: %RU32\n", 1282 strPath.c_str(), mData.mId)); 1283 } 1284 catch (int rc2) 1285 { 1286 rc = rc2; 1287 } 1557 if (RT_FAILURE(rc)) 1558 return rc; 1559 1560 /* Add the created directory to our vector. */ 1561 mData.mFiles.push_back(pFile); 1562 1563 LogFlowFunc(("Added new file \"%s\" (Session: %RU32\n", 1564 strPath.c_str(), mData.mId)); 1288 1565 1289 1566 LogFlowFuncLeaveRC(rc); … … 1491 1768 break; /* Don't try too hard. */ 1492 1769 } 1493 if (RT_FAILURE(rc)) return rc; 1494 1495 try 1496 { 1497 /* Create the process object. */ 1498 HRESULT hr = pProcess.createObject(); 1499 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 1500 1501 rc = pProcess->init(mData.mParent->getConsole() /* Console */, this /* Session */, 1502 uNewProcessID, procInfo); 1503 if (RT_FAILURE(rc)) throw rc; 1504 1505 /* Add the created process to our map. */ 1506 mData.mProcesses[uNewProcessID] = pProcess; 1507 1508 LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %ld processes)\n", 1509 mData.mId, uNewProcessID, mData.mProcesses.size())); 1510 } 1511 catch (int rc2) 1512 { 1513 rc = rc2; 1514 } 1770 1771 if (RT_FAILURE(rc)) 1772 return rc; 1773 1774 /* Create the process object. */ 1775 HRESULT hr = pProcess.createObject(); 1776 if (FAILED(hr)) 1777 return VERR_COM_UNEXPECTED; 1778 1779 rc = pProcess->init(mData.mParent->getConsole() /* Console */, this /* Session */, 1780 uNewProcessID, procInfo); 1781 if (RT_FAILURE(rc)) 1782 return rc; 1783 1784 /* Add the created process to our map. */ 1785 mData.mProcesses[uNewProcessID] = pProcess; 1786 1787 LogFlowFunc(("Added new process (Session: %RU32) with process ID=%RU32 (now total %ld processes)\n", 1788 mData.mId, uNewProcessID, mData.mProcesses.size())); 1515 1789 1516 1790 return rc; … … 1560 1834 AssertPtrReturn(pTask, VERR_INVALID_POINTER); 1561 1835 1562 int rc; 1563 1564 try 1565 { 1566 /* Create the progress object. */ 1567 HRESULT hr = pProgress.createObject(); 1568 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 1569 1570 hr = pProgress->init(static_cast<IGuestSession*>(this), 1571 Bstr(strTaskDesc).raw(), 1572 TRUE /* aCancelable */); 1573 if (FAILED(hr)) throw VERR_COM_UNEXPECTED; 1574 1575 /* Initialize our worker task. */ 1576 std::auto_ptr<GuestSessionTask> task(pTask); 1577 1578 rc = task->RunAsync(strTaskDesc, pProgress); 1579 if (FAILED(rc)) throw rc; 1580 1581 /* Don't destruct on success. */ 1582 task.release(); 1583 } 1584 catch (int rc2) 1585 { 1586 rc = rc2; 1587 } 1836 /* Create the progress object. */ 1837 HRESULT hr = pProgress.createObject(); 1838 if (FAILED(hr)) 1839 return VERR_COM_UNEXPECTED; 1840 1841 hr = pProgress->init(static_cast<IGuestSession*>(this), 1842 Bstr(strTaskDesc).raw(), 1843 TRUE /* aCancelable */); 1844 if (FAILED(hr)) 1845 return VERR_COM_UNEXPECTED; 1846 1847 /* Initialize our worker task. */ 1848 std::auto_ptr<GuestSessionTask> task(pTask); 1849 1850 int rc = task->RunAsync(strTaskDesc, pProgress); 1851 if (RT_FAILURE(rc)) 1852 return rc; 1853 1854 /* Don't destruct on success. */ 1855 task.release(); 1588 1856 1589 1857 LogFlowFuncLeaveRC(rc);
Note:
See TracChangeset
for help on using the changeset viewer.