Changeset 28206 in vbox for trunk/src/VBox/Main
- Timestamp:
- Apr 12, 2010 1:48:49 PM (15 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/GuestImpl.cpp
r28132 r28206 36 36 # include <VBox/HostServices/GuestControlSvc.h> 37 37 # include <VBox/com/array.h> 38 # include <hgcm/HGCM.h> 38 39 #endif 39 40 #include <iprt/cpp/utils.h> … … 435 436 return rc; 436 437 } 438 439 // static 440 DECLCALLBACK(int) Guest::doGuestCtrlNotification(void *pvExtension, 441 uint32_t u32Function, 442 void *pvParms, 443 uint32_t cbParms) 444 { 445 using namespace guestControl; 446 447 /* 448 * No locking, as this is purely a notification which does not make any 449 * changes to the object state. 450 */ 451 PHOSTCALLBACKDATA pCBData = reinterpret_cast<PHOSTCALLBACKDATA>(pvParms); 452 AssertReturn(sizeof(HOSTCALLBACKDATA) == cbParms, VERR_INVALID_PARAMETER); 453 AssertReturn(HOSTCALLBACKMAGIC == pCBData->u32Magic, VERR_INVALID_PARAMETER); 454 LogFlowFunc(("pvExtension = %p, u32Function = %d, pvParms = %p, cbParms = %d\n", 455 pvExtension, u32Function, pvParms, cbParms)); 456 457 int rc = VINF_SUCCESS; 458 Guest *pGuest = static_cast <Guest *>(pvExtension); 459 460 switch (u32Function) 461 { 462 default: 463 rc = VERR_NOT_SUPPORTED; 464 break; 465 } 466 467 ASMAtomicWriteBool(&pGuest->mSignalled, true); 468 return rc; 469 } 437 470 #endif /* VBOX_WITH_GUEST_CONTROL */ 438 471 … … 477 510 478 511 /* 479 * Prepare process execution.512 * Register the host notification callback 480 513 */ 481 int vrc = VINF_SUCCESS; 482 Utf8Str Utf8Command(aCommand); 483 484 /* Prepare arguments. */ 485 com::SafeArray<IN_BSTR> args(ComSafeArrayInArg(aArguments)); 486 uint32_t uNumArgs = args.size(); 487 char **papszArgv = NULL; 488 if(uNumArgs > 0) 489 { 490 papszArgv = (char**)RTMemAlloc(sizeof(char*) * (uNumArgs + 1)); 491 AssertPtr(papszArgv); 492 for (unsigned i = 0; RT_SUCCESS(vrc) && i < uNumArgs; i++) 493 vrc = RTStrAPrintf(&papszArgv[i], "%s", Utf8Str(args[i]).raw()); 494 papszArgv[uNumArgs] = NULL; 495 } 496 514 HGCMSVCEXTHANDLE hExt; 515 int vrc = HGCMHostRegisterServiceExtension(&hExt, "VBoxGuestCtrlSvc", 516 &Guest::doGuestCtrlNotification, 517 this); 497 518 if (RT_SUCCESS(vrc)) 498 519 { 499 char *pszArgs = NULL; 500 if (uNumArgs > 0) 501 vrc = RTGetOptArgvToString(&pszArgs, papszArgv, 0); 520 /* 521 * Prepare process execution. 522 */ 523 Utf8Str Utf8Command(aCommand); 524 525 /* Prepare arguments. */ 526 com::SafeArray<IN_BSTR> args(ComSafeArrayInArg(aArguments)); 527 uint32_t uNumArgs = args.size(); 528 char **papszArgv = NULL; 529 if(uNumArgs > 0) 530 { 531 papszArgv = (char**)RTMemAlloc(sizeof(char*) * (uNumArgs + 1)); 532 AssertPtr(papszArgv); 533 for (unsigned i = 0; RT_SUCCESS(vrc) && i < uNumArgs; i++) 534 vrc = RTStrAPrintf(&papszArgv[i], "%s", Utf8Str(args[i]).raw()); 535 papszArgv[uNumArgs] = NULL; 536 } 537 502 538 if (RT_SUCCESS(vrc)) 503 539 { 504 uint32_t cbArgs = pszArgs ? strlen(pszArgs) + 1 : 0; /* Include terminating zero. */ 505 506 /* Prepare environment. */ 507 com::SafeArray<IN_BSTR> env(ComSafeArrayInArg(aEnvironment)); 508 509 void *pvEnv = NULL; 510 uint32_t uNumEnv = 0; 511 uint32_t cbEnv = 0; 512 513 for (unsigned i = 0; i < env.size(); i++) 514 { 515 vrc = prepareExecuteEnv(Utf8Str(env[i]).raw(), &pvEnv, &cbEnv, &uNumEnv); 516 if (RT_FAILURE(vrc)) 517 break; 518 } 519 540 char *pszArgs = NULL; 541 if (uNumArgs > 0) 542 vrc = RTGetOptArgvToString(&pszArgs, papszArgv, 0); 520 543 if (RT_SUCCESS(vrc)) 521 544 { 522 Utf8Str Utf8StdIn(aStdIn); 523 Utf8Str Utf8StdOut(aStdOut); 524 Utf8Str Utf8StdErr(aStdErr); 525 Utf8Str Utf8UserName(aUserName); 526 Utf8Str Utf8Password(aPassword); 527 528 VBOXHGCMSVCPARM paParms[14]; 529 int i = 0; 530 paParms[i++].setPointer((void*)Utf8Command.raw(), (uint32_t)strlen(Utf8Command.raw()) + 1); 531 paParms[i++].setUInt32(aFlags); 532 paParms[i++].setUInt32(uNumArgs); 533 paParms[i++].setPointer((void*)pszArgs, cbArgs); 534 paParms[i++].setUInt32(uNumEnv); 535 paParms[i++].setUInt32(cbEnv); 536 paParms[i++].setPointer((void*)pvEnv, cbEnv); 537 paParms[i++].setPointer((void*)Utf8StdIn.raw(), (uint32_t)strlen(Utf8StdIn.raw()) + 1); 538 paParms[i++].setPointer((void*)Utf8StdOut.raw(), (uint32_t)strlen(Utf8StdOut.raw()) + 1); 539 paParms[i++].setPointer((void*)Utf8StdErr.raw(), (uint32_t)strlen(Utf8StdErr.raw()) + 1); 540 paParms[i++].setPointer((void*)Utf8UserName.raw(), (uint32_t)strlen(Utf8UserName.raw()) + 1); 541 paParms[i++].setPointer((void*)Utf8Password.raw(), (uint32_t)strlen(Utf8Password.raw()) + 1); 542 paParms[i++].setUInt32(aTimeoutMS); 545 uint32_t cbArgs = pszArgs ? strlen(pszArgs) + 1 : 0; /* Include terminating zero. */ 543 546 544 /* Forward the information to the VMM device. */ 545 AssertPtr(mParent); 546 VMMDev *vmmDev = mParent->getVMMDev(); 547 if (vmmDev) 547 /* Prepare environment. */ 548 com::SafeArray<IN_BSTR> env(ComSafeArrayInArg(aEnvironment)); 549 550 void *pvEnv = NULL; 551 uint32_t uNumEnv = 0; 552 uint32_t cbEnv = 0; 553 554 for (unsigned i = 0; i < env.size(); i++) 548 555 { 549 LogFlow(("Guest::ExecuteProgram: numParms=%d\n", i)); 550 vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD, 551 i, paParms); 552 /** @todo Get the PID. */ 556 vrc = prepareExecuteEnv(Utf8Str(env[i]).raw(), &pvEnv, &cbEnv, &uNumEnv); 557 if (RT_FAILURE(vrc)) 558 break; 553 559 } 554 RTMemFree(pvEnv); 560 561 if (RT_SUCCESS(vrc)) 562 { 563 Utf8Str Utf8StdIn(aStdIn); 564 Utf8Str Utf8StdOut(aStdOut); 565 Utf8Str Utf8StdErr(aStdErr); 566 Utf8Str Utf8UserName(aUserName); 567 Utf8Str Utf8Password(aPassword); 568 569 VBOXHGCMSVCPARM paParms[14]; 570 int i = 0; 571 paParms[i++].setPointer((void*)Utf8Command.raw(), (uint32_t)strlen(Utf8Command.raw()) + 1); 572 paParms[i++].setUInt32(aFlags); 573 paParms[i++].setUInt32(uNumArgs); 574 paParms[i++].setPointer((void*)pszArgs, cbArgs); 575 paParms[i++].setUInt32(uNumEnv); 576 paParms[i++].setUInt32(cbEnv); 577 paParms[i++].setPointer((void*)pvEnv, cbEnv); 578 paParms[i++].setPointer((void*)Utf8StdIn.raw(), (uint32_t)strlen(Utf8StdIn.raw()) + 1); 579 paParms[i++].setPointer((void*)Utf8StdOut.raw(), (uint32_t)strlen(Utf8StdOut.raw()) + 1); 580 paParms[i++].setPointer((void*)Utf8StdErr.raw(), (uint32_t)strlen(Utf8StdErr.raw()) + 1); 581 paParms[i++].setPointer((void*)Utf8UserName.raw(), (uint32_t)strlen(Utf8UserName.raw()) + 1); 582 paParms[i++].setPointer((void*)Utf8Password.raw(), (uint32_t)strlen(Utf8Password.raw()) + 1); 583 paParms[i++].setUInt32(aTimeoutMS); 584 585 /* Forward the information to the VMM device. */ 586 AssertPtr(mParent); 587 VMMDev *vmmDev = mParent->getVMMDev(); 588 if (vmmDev) 589 { 590 LogFlow(("Guest::ExecuteProgram: numParms=%d\n", i)); 591 vrc = vmmDev->hgcmHostCall("VBoxGuestControlSvc", HOST_EXEC_CMD, 592 i, paParms); 593 /** @todo Get the PID. */ 594 } 595 RTMemFree(pvEnv); 596 } 597 RTStrFree(pszArgs); 555 598 } 556 RTStrFree(pszArgs); 599 if (RT_SUCCESS(vrc)) 600 { 601 /* Wait for the HGCM low level callback */ 602 mSignalled = false; 603 uint64_t u64Started = RTTimeMilliTS(); 604 do 605 { 606 unsigned cMsWait; 607 if (aTimeoutMS == RT_INDEFINITE_WAIT) 608 cMsWait = 1000; 609 else 610 { 611 uint64_t cMsElapsed = RTTimeMilliTS() - u64Started; 612 if (cMsElapsed >= aTimeoutMS) 613 break; /* timed out */ 614 cMsWait = RT_MIN(1000, aTimeoutMS - (uint32_t)cMsElapsed); 615 } 616 } while (!mSignalled); 617 #if 0 618 progress.queryInterfaceTo(aProgress); 619 #endif 620 } 621 else 622 rc = setError(E_UNEXPECTED, 623 tr("The service call failed with the error %Rrc"), 624 vrc); 625 626 for (unsigned i = 0; i < uNumArgs; i++) 627 RTMemFree(papszArgv[i]); 628 RTMemFree(papszArgv); 557 629 } 558 if (RT_SUCCESS(vrc)) 559 { 560 #if 0 561 progress.queryInterfaceTo(aProgress); 562 #endif 563 rc = S_OK; 564 } 565 else 566 rc = setError(E_UNEXPECTED, 567 tr("The service call failed with the error %Rrc"), 568 vrc); 569 570 for (unsigned i = 0; i < uNumArgs; i++) 571 RTMemFree(papszArgv[i]); 572 RTMemFree(papszArgv); 630 /* Unregister HGCM extension */ 631 HGCMHostUnregisterServiceExtension(hExt); 573 632 } 574 633 } … … 576 635 { 577 636 rc = E_OUTOFMEMORY; 578 }; 579 637 } 580 638 return rc; 581 639 #endif /* VBOX_WITH_GUEST_CONTROL */ -
trunk/src/VBox/Main/include/GuestImpl.h
r28036 r28206 107 107 108 108 # ifdef VBOX_WITH_GUEST_CONTROL 109 int prepareExecuteArgs(const char *pszArgs, void **ppvList, 110 uint32_t *pcbList, uint32_t *pcArgs); 111 112 int prepareExecuteEnv(const char *pszEnv, void **ppvList, 113 uint32_t *pcbList, uint32_t *pcEnv); 109 int prepareExecuteArgs(const char *pszArgs, void **ppvList, uint32_t *pcbList, uint32_t *pcArgs); 110 int prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnv); 111 /** Static callback for handling guest notifications. */ 112 static DECLCALLBACK(int) doGuestCtrlNotification(void *pvExtension, uint32_t u32Function, void *pvParms, uint32_t cbParms); 114 113 # endif 115 114 … … 132 131 Console *mParent; 133 132 Data mData; 133 bool mSignalled; 134 134 }; 135 135
Note:
See TracChangeset
for help on using the changeset viewer.