Changeset 42693 in vbox for trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp
- Timestamp:
- Aug 8, 2012 10:37:51 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.