/** * List machine groups. * * @returns See produceList. * @param pVirtualBox Reference to the IVirtualBox smart pointer. */ static HRESULT listGroups(const ComPtr<IVirtualBox> &pVirtualBox) { SafeArray<BSTR> groups; CHECK_ERROR2_RET(pVirtualBox, COMGETTER(MachineGroups)(ComSafeArrayAsOutParam(groups)), hrcCheck); for (size_t i = 0; i < groups.size(); i++) { RTPrintf("\"%ls\"\n", groups[i]); } return S_OK; }
int handleGetExtraData(HandlerArg *a) { HRESULT rc = S_OK; if (a->argc != 2) return errorSyntax(USAGE_GETEXTRADATA, "Incorrect number of parameters"); /* global data? */ if (!strcmp(a->argv[0], "global")) { /* enumeration? */ if (!strcmp(a->argv[1], "enumerate")) { SafeArray<BSTR> aKeys; CHECK_ERROR(a->virtualBox, GetExtraDataKeys(ComSafeArrayAsOutParam(aKeys))); for (size_t i = 0; i < aKeys.size(); ++i) { Bstr bstrKey(aKeys[i]); Bstr bstrValue; CHECK_ERROR(a->virtualBox, GetExtraData(bstrKey.raw(), bstrValue.asOutParam())); RTPrintf("Key: %ls, Value: %ls\n", bstrKey.raw(), bstrValue.raw()); } } else { Bstr value; CHECK_ERROR(a->virtualBox, GetExtraData(Bstr(a->argv[1]).raw(), value.asOutParam())); if (!value.isEmpty()) RTPrintf("Value: %ls\n", value.raw()); else RTPrintf("No value set!\n"); } } else { ComPtr<IMachine> machine; CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), machine.asOutParam())); if (machine) { /* enumeration? */ if (!strcmp(a->argv[1], "enumerate")) { SafeArray<BSTR> aKeys; CHECK_ERROR(machine, GetExtraDataKeys(ComSafeArrayAsOutParam(aKeys))); for (size_t i = 0; i < aKeys.size(); ++i) { Bstr bstrKey(aKeys[i]); Bstr bstrValue; CHECK_ERROR(machine, GetExtraData(bstrKey.raw(), bstrValue.asOutParam())); RTPrintf("Key: %ls, Value: %ls\n", bstrKey.raw(), bstrValue.raw()); } } else { Bstr value; CHECK_ERROR(machine, GetExtraData(Bstr(a->argv[1]).raw(), value.asOutParam())); if (!value.isEmpty()) RTPrintf("Value: %ls\n", value.raw()); else RTPrintf("No value set!\n"); } } } return SUCCEEDED(rc) ? 0 : 1; }
HRESULT Guest::taskCopyFileFromGuest(GuestTask *aTask) { LogFlowFuncEnter(); AutoCaller autoCaller(this); if (FAILED(autoCaller.rc())) return autoCaller.rc(); /* * Do *not* take a write lock here since we don't (and won't) * touch any class-specific data (of IGuest) here - only the member functions * which get called here can do that. */ HRESULT rc = S_OK; try { ComObjPtr<Guest> pGuest = aTask->pGuest; /* Does our source file exist? */ BOOL fFileExists; rc = pGuest->FileExists(Bstr(aTask->strSource).raw(), Bstr(aTask->strUserName).raw(), Bstr(aTask->strPassword).raw(), &fFileExists); if (SUCCEEDED(rc)) { if (!fFileExists) rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress, Guest::tr("Source file \"%s\" does not exist, or is not a file"), aTask->strSource.c_str()); } else rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest); /* Query file size to make an estimate for our progress object. */ if (SUCCEEDED(rc)) { LONG64 lFileSize; rc = pGuest->FileQuerySize(Bstr(aTask->strSource).raw(), Bstr(aTask->strUserName).raw(), Bstr(aTask->strPassword).raw(), &lFileSize); if (FAILED(rc)) rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest); com::SafeArray<IN_BSTR> args; com::SafeArray<IN_BSTR> env; if (SUCCEEDED(rc)) { /* * Prepare tool command line. */ char szSource[RTPATH_MAX]; if (RTStrPrintf(szSource, sizeof(szSource), "%s", aTask->strSource.c_str()) <= sizeof(szSource) - 1) { /* * Normalize path slashes, based on the detected guest. */ Utf8Str osType = mData.mOSTypeId; if ( osType.contains("Microsoft", Utf8Str::CaseInsensitive) || osType.contains("Windows", Utf8Str::CaseInsensitive)) { /* We have a Windows guest. */ RTPathChangeToDosSlashes(szSource, true /* Force conversion. */); } else /* ... or something which isn't from Redmond ... */ { RTPathChangeToUnixSlashes(szSource, true /* Force conversion. */); } args.push_back(Bstr(szSource).raw()); /* Tell our cat tool which file to output. */ } else rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress, Guest::tr("Error preparing command line")); } ComPtr<IProgress> execProgress; ULONG uPID; if (SUCCEEDED(rc)) { LogRel(("Copying file \"%s\" to host \"%s\" (%u bytes) ...\n", aTask->strSource.c_str(), aTask->strDest.c_str(), lFileSize)); /* * Okay, since we gathered all stuff we need until now to start the * actual copying, start the guest part now. */ rc = pGuest->executeAndWaitForTool(Bstr(VBOXSERVICE_TOOL_CAT).raw(), Bstr("Copying file to host").raw(), ComSafeArrayAsInParam(args), ComSafeArrayAsInParam(env), Bstr(aTask->strUserName).raw(), Bstr(aTask->strPassword).raw(), ExecuteProcessFlag_WaitForProcessStartOnly | ExecuteProcessFlag_WaitForStdOut, NULL, NULL, execProgress.asOutParam(), &uPID); if (FAILED(rc)) rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest); } if (SUCCEEDED(rc)) { BOOL fCompleted = FALSE; BOOL fCanceled = FALSE; RTFILE hFileDest; int vrc = RTFileOpen(&hFileDest, aTask->strDest.c_str(), RTFILE_O_WRITE | RTFILE_O_OPEN_CREATE | RTFILE_O_DENY_WRITE); if (RT_FAILURE(vrc)) rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress, Guest::tr("Unable to create/open destination file \"%s\", rc=%Rrc"), aTask->strDest.c_str(), vrc); else { size_t cbToRead = lFileSize; size_t cbTransfered = 0; while ( SUCCEEDED(execProgress->COMGETTER(Completed(&fCompleted))) && !fCompleted) { SafeArray<BYTE> aOutputData; rc = pGuest->GetProcessOutput(uPID, ProcessOutputFlag_None /* StdOut */, 0 /* No timeout. */, _64K, ComSafeArrayAsOutParam(aOutputData)); if (SUCCEEDED(rc)) { if (aOutputData.size()) { vrc = RTFileWrite(hFileDest, aOutputData.raw(), aOutputData.size(), NULL /* No partial writes */); if (RT_FAILURE(vrc)) { rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress, Guest::tr("Error writing to file \"%s\" (%u bytes left), rc=%Rrc"), aTask->strSource.c_str(), cbToRead, vrc); break; } Assert(cbToRead >= aOutputData.size()); cbToRead -= aOutputData.size(); cbTransfered += aOutputData.size(); aTask->pProgress->SetCurrentOperationProgress(cbTransfered / (lFileSize / 100.0)); } /* Nothing read this time; try next round. */ } else { rc = GuestTask::setProgressErrorInfo(rc, aTask->pProgress, pGuest); break; } } RTFileClose(hFileDest); if (SUCCEEDED(rc)) { if ( cbTransfered && (cbTransfered != lFileSize)) { /* * Only bitch about an unexpected end of a file when there already * was data read from that file. If this was the very first read we can * be (almost) sure that this file is not meant to be read by the specified user. */ rc = GuestTask::setProgressErrorInfo(VBOX_E_IPRT_ERROR, aTask->pProgress, Guest::tr("Unexpected end of file \"%s\" (%u bytes total, %u bytes transferred)"), aTask->strSource.c_str(), lFileSize, cbTransfered); } if (SUCCEEDED(rc)) aTask->pProgress->notifyComplete(S_OK); } } } } } catch (HRESULT aRC) { rc = aRC; } /* Clean up */ aTask->rc = rc; LogFlowFunc(("rc=%Rhrc\n", rc)); LogFlowFuncLeave(); return VINF_SUCCESS; }