Changeset 33924 in vbox
- Timestamp:
- Nov 10, 2010 8:53:54 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
r33901 r33924 63 63 64 64 /** Set by the signal handler. */ 65 static volatile bool g_fExecCanceled = false; 66 static volatile bool g_fCopyCanceled = false; 65 static volatile bool g_fGuestCtrlCanceled = false; 67 66 68 67 /* … … 109 108 110 109 /** 111 * Signal handler that sets g_f Canceled.110 * Signal handler that sets g_fGuestCtrlCanceled. 112 111 * 113 112 * This can be executed on any thread in the process, on Windows it may even be … … 115 114 * unnecessary here. 116 115 */ 117 static void ctrlExecProcessSignalHandler(int iSignal)116 static void guestCtrlSignalHandler(int iSignal) 118 117 { 119 118 NOREF(iSignal); 120 ASMAtomicWriteBool(&g_fExecCanceled, true); 121 } 122 119 ASMAtomicWriteBool(&g_fGuestCtrlCanceled, true); 120 } 121 122 /** 123 * Installs a custom signal handler to get notified 124 * whenever the user wants to intercept the program. 125 */ 126 static void ctrlSignalHandlerInstall() 127 { 128 signal(SIGINT, guestCtrlSignalHandler); 129 #ifdef SIGBREAK 130 signal(SIGBREAK, guestCtrlSignalHandler); 131 #endif 132 } 133 134 /** 135 * Uninstalls a previously installed signal handler. 136 */ 137 static void ctrlSignalHandlerUninstall() 138 { 139 signal(SIGINT, SIG_DFL); 140 #ifdef SIGBREAK 141 signal(SIGBREAK, SIG_DFL); 142 #endif 143 } 144 145 /** 146 * Translates a process status to a human readable 147 * string. 148 */ 123 149 static const char *ctrlExecGetStatus(ULONG uStatus) 124 150 { … … 146 172 } 147 173 174 static int ctrlPrintError(ComPtr<IUnknown> object, const GUID &aIID) 175 { 176 com::ErrorInfo info(object, aIID); 177 if ( info.isFullAvailable() 178 || info.isBasicAvailable()) 179 { 180 /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way 181 * because it contains more accurate info about what went wrong. */ 182 if (info.getResultCode() == VBOX_E_IPRT_ERROR) 183 RTMsgError("%ls.", info.getText().raw()); 184 else 185 { 186 RTMsgError("Error details:"); 187 GluePrintErrorInfo(info); 188 } 189 return VERR_GENERAL_FAILURE; /** @todo */ 190 } 191 AssertMsgFailedReturn(("Object has indicated no error!?\n"), 192 VERR_INVALID_PARAMETER); 193 } 194 195 /** 196 * Un-initializes the VM after guest control usage. 197 */ 198 static void ctrlUninitVM(HandlerArg *pArg) 199 { 200 AssertPtrReturnVoid(pArg); 201 if (pArg->session) 202 pArg->session->UnlockMachine(); 203 } 204 205 /** 206 * Initializes the VM, that is checks whether it's up and 207 * running, if it can be locked (shared only) and returns a 208 * valid IGuest pointer on success. 209 * 210 * @return IPRT status code. 211 * @param pArg Our command line argument structure. 212 * @param pszNameOrId The VM's name or UUID to use. 213 * @param pGuest Pointer where to store the IGuest interface. 214 */ 215 static int ctrlInitVM(HandlerArg *pArg, const char *pszNameOrId, ComPtr<IGuest> *pGuest) 216 { 217 AssertPtrReturn(pArg, VERR_INVALID_PARAMETER); 218 AssertPtrReturn(pszNameOrId, VERR_INVALID_PARAMETER); 219 220 /* Lookup VM. */ 221 ComPtr<IMachine> machine; 222 /* Assume it's an UUID. */ 223 HRESULT rc; 224 CHECK_ERROR(pArg->virtualBox, FindMachine(Bstr(pszNameOrId).raw(), 225 machine.asOutParam())); 226 if (FAILED(rc)) 227 return VERR_NOT_FOUND; 228 229 /* Machine is running? */ 230 MachineState_T machineState; 231 CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1); 232 if (machineState != MachineState_Running) 233 { 234 RTMsgError("Machine \"%s\" is not running!\n", pszNameOrId); 235 return VERR_VM_INVALID_VM_STATE; 236 } 237 238 do 239 { 240 /* Open a session for the VM. */ 241 CHECK_ERROR_BREAK(machine, LockMachine(pArg->session, LockType_Shared)); 242 /* Get the associated console. */ 243 ComPtr<IConsole> console; 244 CHECK_ERROR_BREAK(pArg->session, COMGETTER(Console)(console.asOutParam())); 245 /* ... and session machine. */ 246 ComPtr<IMachine> sessionMachine; 247 CHECK_ERROR_BREAK(pArg->session, COMGETTER(Machine)(sessionMachine.asOutParam())); 248 /* Get IGuest interface. */ 249 CHECK_ERROR_BREAK(console, COMGETTER(Guest)(pGuest->asOutParam())); 250 } while (0); 251 252 if (FAILED(rc)) 253 ctrlUninitVM(pArg); 254 return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE; 255 } 256 148 257 static int handleCtrlExecProgram(HandlerArg *a) 149 258 { … … 307 416 "No user name specified!"); 308 417 309 /* Lookup VM. */ 310 ComPtr<IMachine> machine; 311 /* Assume it's an UUID. */ 312 HRESULT rc; 313 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), 314 machine.asOutParam())); 315 if (FAILED(rc)) 316 return 1; 317 318 /* Machine is running? */ 319 MachineState_T machineState; 320 CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1); 321 if (machineState != MachineState_Running) 322 { 323 RTMsgError("Machine \"%s\" is not running!\n", a->argv[0]); 324 return 1; 325 } 326 327 /* Open a session for the VM. */ 328 CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1); 329 330 do 331 { 332 /* Get the associated console. */ 333 ComPtr<IConsole> console; 334 CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam())); 335 /* ... and session machine */ 336 ComPtr<IMachine> sessionMachine; 337 CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam())); 338 339 ComPtr<IGuest> guest; 340 CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam())); 341 418 HRESULT rc = S_OK; 419 ComPtr<IGuest> guest; 420 int vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest); 421 if (RT_SUCCESS(vrc)) 422 { 342 423 ComPtr<IProgress> progress; 343 424 ULONG uPID = 0; … … 363 444 if (FAILED(rc)) 364 445 { 365 /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way 366 * because it contains more accurate info about what went wrong. */ 367 ErrorInfo info(guest, COM_IIDOF(IGuest)); 368 if (info.isFullAvailable()) 369 { 370 if (rc == VBOX_E_IPRT_ERROR) 371 RTMsgError("%ls.", info.getText().raw()); 372 else 373 RTMsgError("%ls (%Rhrc).", info.getText().raw(), info.getResultCode()); 374 } 375 break; 376 } 377 if (fVerbose) 378 RTPrintf("Process '%s' (PID: %u) started\n", Utf8Cmd.c_str(), uPID); 379 if (fWaitForExit) 380 { 381 if (fTimeout) 382 { 383 /* Calculate timeout value left after process has been started. */ 384 uint64_t u64Elapsed = RTTimeMilliTS() - u64StartMS; 385 /* Is timeout still bigger than current difference? */ 386 if (u32TimeoutMS > u64Elapsed) 387 { 388 u32TimeoutMS -= (uint32_t)u64Elapsed; 389 if (fVerbose) 390 RTPrintf("Waiting for process to exit (%ums left) ...\n", u32TimeoutMS); 391 } 392 else 393 { 394 if (fVerbose) 395 RTPrintf("No time left to wait for process!\n"); 396 } 397 } 398 else if (fVerbose) 399 RTPrintf("Waiting for process to exit ...\n"); 400 401 /* Setup signal handling if cancelable. */ 402 ASSERT(progress); 403 bool fCanceledAlready = false; 404 BOOL fCancelable; 405 HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable); 406 if (FAILED(hrc)) 407 fCancelable = FALSE; 408 if (fCancelable) 409 { 410 signal(SIGINT, ctrlExecProcessSignalHandler); 411 #ifdef SIGBREAK 412 signal(SIGBREAK, ctrlExecProcessSignalHandler); 413 #endif 414 } 415 416 /* Wait for process to exit ... */ 417 BOOL fCompleted = FALSE; 418 BOOL fCanceled = FALSE; 419 while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted)))) 420 { 421 SafeArray<BYTE> aOutputData; 422 ULONG cbOutputData = 0; 423 424 /* 425 * Some data left to output? 426 */ 427 if ( fWaitForStdOut 428 || fWaitForStdErr) 429 { 430 rc = guest->GetProcessOutput(uPID, 0 /* aFlags */, 431 u32TimeoutMS, _64K, ComSafeArrayAsOutParam(aOutputData)); 432 if (FAILED(rc)) 446 vrc = ctrlPrintError(guest, COM_IIDOF(IGuest)); 447 } 448 else 449 { 450 if (fVerbose) 451 RTPrintf("Process '%s' (PID: %u) started\n", Utf8Cmd.c_str(), uPID); 452 if (fWaitForExit) 453 { 454 if (fTimeout) 455 { 456 /* Calculate timeout value left after process has been started. */ 457 uint64_t u64Elapsed = RTTimeMilliTS() - u64StartMS; 458 /* Is timeout still bigger than current difference? */ 459 if (u32TimeoutMS > u64Elapsed) 433 460 { 434 /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way 435 * because it contains more accurate info about what went wrong. */ 436 ErrorInfo info(guest, COM_IIDOF(IGuest)); 437 if (info.isFullAvailable()) 438 { 439 if (rc == VBOX_E_IPRT_ERROR) 440 RTMsgError("%ls.", info.getText().raw()); 441 else 442 RTMsgError("%ls (%Rhrc).", info.getText().raw(), info.getResultCode()); 443 } 444 cbOutputData = 0; 445 fCompleted = true; /* rc contains a failure, so we'll go into aborted state down below. */ 461 u32TimeoutMS -= (uint32_t)u64Elapsed; 462 if (fVerbose) 463 RTPrintf("Waiting for process to exit (%ums left) ...\n", u32TimeoutMS); 446 464 } 447 465 else 448 466 { 449 cbOutputData = aOutputData.size(); 450 if (cbOutputData > 0) 467 if (fVerbose) 468 RTPrintf("No time left to wait for process!\n"); 469 } 470 } 471 else if (fVerbose) 472 RTPrintf("Waiting for process to exit ...\n"); 473 474 /* Setup signal handling if cancelable. */ 475 ASSERT(progress); 476 bool fCanceledAlready = false; 477 BOOL fCancelable; 478 HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable); 479 if (FAILED(hrc)) 480 fCancelable = FALSE; 481 if (fCancelable) 482 ctrlSignalHandlerInstall(); 483 484 /* Wait for process to exit ... */ 485 BOOL fCompleted = FALSE; 486 BOOL fCanceled = FALSE; 487 while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted)))) 488 { 489 SafeArray<BYTE> aOutputData; 490 ULONG cbOutputData = 0; 491 492 /* 493 * Some data left to output? 494 */ 495 if ( fWaitForStdOut 496 || fWaitForStdErr) 497 { 498 rc = guest->GetProcessOutput(uPID, 0 /* aFlags */, 499 u32TimeoutMS, _64K, ComSafeArrayAsOutParam(aOutputData)); 500 if (FAILED(rc)) 451 501 { 452 /* aOutputData has a platform dependent line ending, standardize on 453 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on 454 * Windows. Otherwise we end up with CR/CR/LF on Windows. */ 455 ULONG cbOutputDataPrint = cbOutputData; 456 for (BYTE *s = aOutputData.raw(), *d = s; 457 s - aOutputData.raw() < (ssize_t)cbOutputData; 458 s++, d++) 502 vrc = ctrlPrintError(guest, COM_IIDOF(IGuest)); 503 504 cbOutputData = 0; 505 fCompleted = true; /* rc contains a failure, so we'll go into aborted state down below. */ 506 } 507 else 508 { 509 cbOutputData = aOutputData.size(); 510 if (cbOutputData > 0) 459 511 { 460 if (*s == '\r') 512 /* aOutputData has a platform dependent line ending, standardize on 513 * Unix style, as RTStrmWrite does the LF -> CR/LF replacement on 514 * Windows. Otherwise we end up with CR/CR/LF on Windows. */ 515 ULONG cbOutputDataPrint = cbOutputData; 516 for (BYTE *s = aOutputData.raw(), *d = s; 517 s - aOutputData.raw() < (ssize_t)cbOutputData; 518 s++, d++) 461 519 { 462 /* skip over CR, adjust destination */ 463 d--; 464 cbOutputDataPrint--; 520 if (*s == '\r') 521 { 522 /* skip over CR, adjust destination */ 523 d--; 524 cbOutputDataPrint--; 525 } 526 else if (s != d) 527 *d = *s; 465 528 } 466 else if (s != d) 467 *d = *s; 529 RTStrmWrite(g_pStdOut, aOutputData.raw(), cbOutputDataPrint); 468 530 } 469 RTStrmWrite(g_pStdOut, aOutputData.raw(), cbOutputDataPrint);470 531 } 471 532 } 472 } 473 if (cbOutputData <= 0) /* No more output data left? */ 474 { 475 if (fCompleted) 476 break; 477 478 if ( fTimeout 479 && RTTimeMilliTS() - u64StartMS > u32TimeoutMS + 5000) 533 if (cbOutputData <= 0) /* No more output data left? */ 480 534 { 481 progress->Cancel(); 535 if (fCompleted) 536 break; 537 538 if ( fTimeout 539 && RTTimeMilliTS() - u64StartMS > u32TimeoutMS + 5000) 540 { 541 progress->Cancel(); 542 break; 543 } 544 } 545 546 /* Process async cancelation */ 547 if (g_fGuestCtrlCanceled && !fCanceledAlready) 548 { 549 hrc = progress->Cancel(); 550 if (SUCCEEDED(hrc)) 551 fCanceledAlready = TRUE; 552 else 553 g_fGuestCtrlCanceled = false; 554 } 555 556 /* Progress canceled by Main API? */ 557 if ( SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled))) 558 && fCanceled) 559 { 482 560 break; 483 561 } 484 562 } 485 563 486 /* Process async cancelation */ 487 if (g_fExecCanceled && !fCanceledAlready) 488 { 489 hrc = progress->Cancel(); 490 if (SUCCEEDED(hrc)) 491 fCanceledAlready = TRUE; 492 else 493 g_fExecCanceled = false; 494 } 495 496 /* Progress canceled by Main API? */ 497 if ( SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled))) 498 && fCanceled) 499 { 500 break; 501 } 502 } 503 504 /* Undo signal handling */ 505 if (fCancelable) 506 { 507 signal(SIGINT, SIG_DFL); 508 #ifdef SIGBREAK 509 signal(SIGBREAK, SIG_DFL); 510 #endif 511 } 512 513 if (fCanceled) 514 { 515 if (fVerbose) 516 RTPrintf("Process execution canceled!\n"); 517 } 518 else if ( fCompleted 519 && SUCCEEDED(rc)) 520 { 521 LONG iRc = false; 522 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc); 523 if (FAILED(iRc)) 524 { 525 com::ProgressErrorInfo info(progress); 526 if ( info.isFullAvailable() 527 || info.isBasicAvailable()) 564 /* Undo signal handling */ 565 if (fCancelable) 566 ctrlSignalHandlerUninstall(); 567 568 if (fCanceled) 569 { 570 if (fVerbose) 571 RTPrintf("Process execution canceled!\n"); 572 } 573 else if ( fCompleted 574 && SUCCEEDED(rc)) 575 { 576 LONG iRc = false; 577 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc); 578 if (FAILED(iRc)) 528 579 { 529 /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way 530 * because it contains more accurate info about what went wrong. */ 531 if (info.getResultCode() == VBOX_E_IPRT_ERROR) 532 RTMsgError("%ls.", info.getText().raw()); 533 else 534 { 535 RTMsgError("Process error details:"); 536 GluePrintErrorInfo(info); 537 } 580 vrc = ctrlPrintError(progress, COM_IIDOF(IProgress)); 538 581 } 539 else 540 com::GluePrintRCMessage(iRc); 541 } 542 else if (fVerbose) 543 { 544 ULONG uRetStatus, uRetExitCode, uRetFlags; 545 rc = guest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus); 546 if (SUCCEEDED(rc)) 547 RTPrintf("Exit code=%u (Status=%u [%s], Flags=%u)\n", uRetExitCode, uRetStatus, ctrlExecGetStatus(uRetStatus), uRetFlags); 548 } 549 } 550 else 551 { 552 if (fVerbose) 553 RTPrintf("Process execution aborted!\n"); 554 } 555 } 556 a->session->UnlockMachine(); 557 } while (0); 582 else if (fVerbose) 583 { 584 ULONG uRetStatus, uRetExitCode, uRetFlags; 585 rc = guest->GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus); 586 if (SUCCEEDED(rc)) 587 RTPrintf("Exit code=%u (Status=%u [%s], Flags=%u)\n", uRetExitCode, uRetStatus, ctrlExecGetStatus(uRetStatus), uRetFlags); 588 } 589 } 590 else 591 { 592 if (fVerbose) 593 RTPrintf("Process execution aborted!\n"); 594 } 595 } 596 } 597 ctrlUninitVM(a); 598 } 599 600 if (RT_FAILURE(vrc)) 601 rc = VBOX_E_IPRT_ERROR; 558 602 return SUCCEEDED(rc) ? 0 : 1; 559 }560 561 /**562 * Signal handler that sets g_fCopyCanceled.563 *564 * This can be executed on any thread in the process, on Windows it may even be565 * a thread dedicated to delivering this signal. Do not doing anything566 * unnecessary here.567 */568 static void ctrlCopySignalHandler(int iSignal)569 {570 NOREF(iSignal);571 ASMAtomicWriteBool(&g_fCopyCanceled, true);572 603 } 573 604 … … 940 971 if (FAILED(rc)) 941 972 { 942 /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way 943 * because it contains more accurate info about what went wrong. */ 944 ErrorInfo info(pGuest, COM_IIDOF(IGuest)); 945 if (info.isFullAvailable()) 946 { 947 if (rc == VBOX_E_IPRT_ERROR) 948 RTMsgError("%ls.", info.getText().raw()); 949 else 950 RTMsgError("%ls (%Rhrc).", info.getText().raw(), info.getResultCode()); 951 } 952 vrc = VERR_GENERAL_FAILURE; 973 vrc = ctrlPrintError(pGuest, COM_IIDOF(IGuest)); 953 974 } 954 975 else … … 957 978 ASSERT(progress); 958 979 bool fCanceledAlready = false; 959 BOOL fCancelable ;980 BOOL fCancelable = FALSE; 960 981 HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable); 961 if (FAILED(hrc))962 fCancelable = FALSE;963 982 if (fCancelable) 964 { 965 signal(SIGINT, ctrlCopySignalHandler); 966 #ifdef SIGBREAK 967 signal(SIGBREAK, ctrlCopySignalHandler); 968 #endif 969 } 983 ctrlSignalHandlerInstall(); 970 984 971 985 /* Wait for process to exit ... */ … … 976 990 { 977 991 /* Process async cancelation */ 978 if (g_f CopyCanceled && !fCanceledAlready)992 if (g_fGuestCtrlCanceled && !fCanceledAlready) 979 993 { 980 994 hrc = progress->Cancel(); … … 982 996 fCanceledAlready = TRUE; 983 997 else 984 g_f CopyCanceled = false;998 g_fGuestCtrlCanceled = false; 985 999 } 986 1000 … … 993 1007 } 994 1008 995 /* Undo signal handling */1009 /* Undo signal handling. */ 996 1010 if (fCancelable) 997 { 998 signal(SIGINT, SIG_DFL); 999 #ifdef SIGBREAK 1000 signal(SIGBREAK, SIG_DFL); 1001 #endif 1002 } 1011 ctrlSignalHandlerUninstall(); 1003 1012 1004 1013 if (fCanceled) 1005 1014 { 1006 / /RTPrintf("Copy operation canceled!\n");1015 /* Nothing to do here right now. */ 1007 1016 } 1008 1017 else if ( fCompleted … … 1012 1021 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc); 1013 1022 if (FAILED(iRc)) 1014 { 1015 com::ProgressErrorInfo info(progress); 1016 if ( info.isFullAvailable() 1017 || info.isBasicAvailable()) 1018 { 1019 /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way 1020 * because it contains more accurate info about what went wrong. */ 1021 if (info.getResultCode() == VBOX_E_IPRT_ERROR) 1022 RTMsgError("%ls.", info.getText().raw()); 1023 else 1024 { 1025 RTMsgError("Copy operation error details:"); 1026 GluePrintErrorInfo(info); 1027 } 1028 } 1029 else 1030 { 1031 if (RT_FAILURE(vrc)) 1032 RTMsgError("Error while looking up error code, rc=%Rrc\n", vrc); 1033 else 1034 com::GluePrintRCMessage(iRc); 1035 } 1036 vrc = VERR_GENERAL_FAILURE; 1037 } 1023 vrc = ctrlPrintError(progress, COM_IIDOF(IProgress)); 1038 1024 } 1039 1025 } … … 1137 1123 "No user name specified!"); 1138 1124 1139 /* Lookup VM. */ 1140 ComPtr<IMachine> machine; 1141 /* Assume it's an UUID. */ 1142 HRESULT rc; 1143 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), 1144 machine.asOutParam())); 1145 if (FAILED(rc)) 1146 return 1; 1147 1148 /* Machine is running? */ 1149 MachineState_T machineState; 1150 CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1); 1151 if (machineState != MachineState_Running) 1152 { 1153 RTMsgError("Machine \"%s\" is not running!\n", a->argv[0]); 1154 return 1; 1155 } 1156 1157 /* Open a session for the VM. */ 1158 CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1); 1159 1160 do 1161 { 1162 /* Get the associated console. */ 1163 ComPtr<IConsole> console; 1164 CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam())); 1165 /* ... and session machine */ 1166 ComPtr<IMachine> sessionMachine; 1167 CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam())); 1168 1169 ComPtr<IGuest> guest; 1170 CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam())); 1171 1125 HRESULT rc = S_OK; 1126 ComPtr<IGuest> guest; 1127 int vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest); 1128 if (RT_SUCCESS(vrc)) 1129 { 1172 1130 if (fVerbose) 1173 1131 { … … 1179 1137 RTLISTNODE listToCopy; 1180 1138 uint32_t cObjects = 0; 1181 intvrc = ctrlCopyInit(Utf8Source.c_str(), Utf8Dest.c_str(), uFlags,1182 1139 vrc = ctrlCopyInit(Utf8Source.c_str(), Utf8Dest.c_str(), uFlags, 1140 &cObjects, &listToCopy); 1183 1141 if (RT_FAILURE(vrc)) 1184 1142 { … … 1237 1195 ctrlCopyDestroy(&listToCopy); 1238 1196 } 1239 a->session->UnlockMachine(); 1240 } while (0); 1197 ctrlUninitVM(a); 1198 } 1199 1200 if (RT_FAILURE(vrc)) 1201 rc = VBOX_E_IPRT_ERROR; 1241 1202 return SUCCEEDED(rc) ? 0 : 1; 1242 1203 } … … 1310 1271 } 1311 1272 } 1312 /** @todo Add force flag for overwriting existing stuff. */1313 1273 else if (!strcmp(a->argv[i], "--verbose")) 1314 1274 fVerbose = true; … … 1329 1289 "No user name specified!"); 1330 1290 1331 /* Lookup VM. */ 1332 ComPtr<IMachine> machine; 1333 /* Assume it's an UUID. */ 1334 HRESULT rc; 1335 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), 1336 machine.asOutParam())); 1337 if (FAILED(rc)) 1338 return 1; 1339 1340 /* Machine is running? */ 1341 MachineState_T machineState; 1342 CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1); 1343 if (machineState != MachineState_Running) 1344 { 1345 RTMsgError("Machine \"%s\" is not running!\n", a->argv[0]); 1346 return 1; 1347 } 1348 1349 /* Open a session for the VM. */ 1350 CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1); 1351 1352 do 1353 { 1354 /* Get the associated console. */ 1355 ComPtr<IConsole> console; 1356 CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam())); 1357 /* ... and session machine */ 1358 ComPtr<IMachine> sessionMachine; 1359 CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam())); 1360 1361 ComPtr<IGuest> guest; 1362 CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam())); 1363 1291 HRESULT rc = S_OK; 1292 ComPtr<IGuest> guest; 1293 int vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest); 1294 if (RT_SUCCESS(vrc)) 1295 { 1364 1296 ComPtr<IProgress> progress; 1365 1297 rc = guest->CreateDirectory(Bstr(Utf8Directory).raw(), … … 1385 1317 bool fCanceledAlready = false; 1386 1318 BOOL fCancelable; 1387 HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable);1388 if (FAILED( hrc))1319 rc = progress->COMGETTER(Cancelable)(&fCancelable); 1320 if (FAILED(rc)) 1389 1321 fCancelable = FALSE; 1390 1322 if (fCancelable) 1391 { 1392 signal(SIGINT, ctrlCopySignalHandler); 1393 #ifdef SIGBREAK 1394 signal(SIGBREAK, ctrlCopySignalHandler); 1395 #endif 1396 } 1323 ctrlSignalHandlerInstall(); 1397 1324 1398 1325 /* Wait for process to exit ... */ … … 1403 1330 { 1404 1331 /* Process async cancelation */ 1405 if (g_f CopyCanceled && !fCanceledAlready)1406 { 1407 hrc = progress->Cancel();1408 if (SUCCEEDED( hrc))1332 if (g_fGuestCtrlCanceled && !fCanceledAlready) 1333 { 1334 rc = progress->Cancel(); 1335 if (SUCCEEDED(rc)) 1409 1336 fCanceledAlready = TRUE; 1410 1337 else 1411 g_f CopyCanceled = false;1338 g_fGuestCtrlCanceled = false; 1412 1339 } 1413 1340 … … 1420 1347 } 1421 1348 1422 /* Undo signal handling */1349 /* Undo signal handling. */ 1423 1350 if (fCancelable) 1424 { 1425 signal(SIGINT, SIG_DFL); 1426 #ifdef SIGBREAK 1427 signal(SIGBREAK, SIG_DFL); 1428 #endif 1429 } 1351 ctrlSignalHandlerUninstall(); 1430 1352 1431 1353 if (fCanceled) … … 1439 1361 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc); 1440 1362 if (FAILED(iRc)) 1441 { 1442 com::ProgressErrorInfo info(progress); 1443 if ( info.isFullAvailable() 1444 || info.isBasicAvailable()) 1445 { 1446 /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way 1447 * because it contains more accurate info about what went wrong. */ 1448 if (info.getResultCode() == VBOX_E_IPRT_ERROR) 1449 RTMsgError("%ls.", info.getText().raw()); 1450 else 1451 { 1452 RTMsgError("Copy operation error details:"); 1453 GluePrintErrorInfo(info); 1454 } 1455 } 1456 } 1457 } 1458 } 1459 1460 a->session->UnlockMachine(); 1461 } while (0); 1363 vrc = ctrlPrintError(progress, COM_IIDOF(IProgress)); 1364 } 1365 } 1366 ctrlUninitVM(a); 1367 } 1368 1369 if (RT_FAILURE(vrc)) 1370 rc = VBOX_E_IPRT_ERROR; 1462 1371 return SUCCEEDED(rc) ? 0 : 1; 1463 1372 } … … 1499 1408 return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters"); 1500 1409 1501 /* Lookup VM. */ 1502 ComPtr<IMachine> machine; 1503 /* Assume it's an UUID. */ 1504 HRESULT rc; 1505 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), 1506 machine.asOutParam())); 1507 if (FAILED(rc)) 1508 return 1; 1509 1510 /* Machine is running? */ 1511 MachineState_T machineState; 1512 CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1); 1513 if (machineState != MachineState_Running) 1514 { 1515 RTMsgError("Machine \"%s\" is not running!\n", a->argv[0]); 1516 return 1; 1517 } 1518 1519 /* Open a session for the VM. */ 1520 CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1); 1521 1522 do 1523 { 1524 /* Get the associated console. */ 1525 ComPtr<IConsole> console; 1526 CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam())); 1527 /* ... and session machine */ 1528 ComPtr<IMachine> sessionMachine; 1529 CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam())); 1530 1531 ComPtr<IGuest> guest; 1532 CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam())); 1533 1410 HRESULT rc = S_OK; 1411 ComPtr<IGuest> guest; 1412 int vrc = ctrlInitVM(a, a->argv[0] /* VM Name */, &guest); 1413 if (RT_SUCCESS(vrc)) 1414 { 1534 1415 if (fVerbose) 1535 1416 RTPrintf("Updating Guest Additions of machine \"%s\" ...\n", a->argv[0]); … … 1543 1424 { 1544 1425 char strTemp[RTPATH_MAX]; 1545 int vrc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp));1546 AssertRC( vrc);1426 rc = RTPathAppPrivateNoArch(strTemp, sizeof(strTemp)); 1427 AssertRC(rc); 1547 1428 Utf8Str Utf8Src1 = Utf8Str(strTemp).append("/VBoxGuestAdditions.iso"); 1548 1429 1549 vrc = RTPathExecDir(strTemp, sizeof(strTemp));1550 AssertRC( vrc);1430 rc = RTPathExecDir(strTemp, sizeof(strTemp)); 1431 AssertRC(rc); 1551 1432 Utf8Str Utf8Src2 = Utf8Str(strTemp).append("/additions/VBoxGuestAdditions.iso"); 1552 1433 … … 1559 1440 { 1560 1441 RTMsgError("Source could not be determined! Please use --source to specify a valid source.\n"); 1561 break;1442 rc = VERR_FILE_NOT_FOUND; 1562 1443 } 1563 1444 } … … 1565 1446 { 1566 1447 RTMsgError("Source \"%s\" does not exist!\n", Utf8Source.c_str()); 1567 break; 1568 } 1569 if (fVerbose) 1570 RTPrintf("Using source: %s\n", Utf8Source.c_str()); 1571 1572 ComPtr<IProgress> progress; 1573 CHECK_ERROR_BREAK(guest, UpdateGuestAdditions(Bstr(Utf8Source).raw(), 1574 0 /* Flags, not used. */, 1575 progress.asOutParam())); 1576 rc = showProgress(progress); 1577 if (FAILED(rc)) 1578 { 1579 com::ProgressErrorInfo info(progress); 1580 if (info.isBasicAvailable()) 1581 RTMsgError("Failed to start Guest Additions update. Error message: %lS\n", info.getText().raw()); 1582 else 1583 RTMsgError("Failed to start Guest Additions update. No error message available!\n"); 1584 } 1585 else 1448 rc = VERR_FILE_NOT_FOUND; 1449 } 1450 1451 if (RT_SUCCESS(rc)) 1586 1452 { 1587 1453 if (fVerbose) 1454 RTPrintf("Using source: %s\n", Utf8Source.c_str()); 1455 1456 ComPtr<IProgress> progress; 1457 CHECK_ERROR(guest, UpdateGuestAdditions(Bstr(Utf8Source).raw(), 1458 0 /* Flags, not used. */, 1459 progress.asOutParam())); 1460 rc = showProgress(progress); 1461 if (FAILED(rc)) 1462 vrc = ctrlPrintError(progress, COM_IIDOF(IProgress)); 1463 else if (fVerbose) 1588 1464 RTPrintf("Guest Additions installer successfully copied and started.\n"); 1589 1465 } 1590 a->session->UnlockMachine(); 1591 } while (0); 1466 ctrlUninitVM(a); 1467 } 1468 1469 if (RT_FAILURE(vrc)) 1470 rc = VBOX_E_IPRT_ERROR; 1592 1471 return SUCCEEDED(rc) ? 0 : 1; 1593 1472 }
Note:
See TracChangeset
for help on using the changeset viewer.