VBoxManageGuestCtrl.cpp revision dc31047bffe0f7c2dda50da6efe001e0cbf9a0a7
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * VBoxManage - Implementation of guestcontrol command.
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2010-2012 Oracle Corporation
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * available from http://www.virtualbox.org. This file is free software;
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * you can redistribute it and/or modify it under the terms of the GNU
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * General Public License (GPL) as published by the Free Software
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync/*******************************************************************************
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync* Header Files *
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync*******************************************************************************/
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsyncusing namespace com;
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync * IVirtualBoxCallback implementation for handling the GuestControlCallback in
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync * relation to the "guestcontrol * wait" command.
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync/** @todo */
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync/** Set by the signal handler. */
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsyncstatic volatile bool g_fGuestCtrlCanceled = false;
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsynctypedef struct COPYCONTEXT
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync COPYCONTEXT() : fVerbose(false), fDryRun(false), fHostToGuest(false)
230bd8589bba39933ac5ec21482d6186d675e604vboxsync * An entry for a source element, including an optional DOS-like wildcard (*,?).
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync SOURCEFILEENTRY(const char *pszSource, const char *pszFilter)
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync const char* GetSource() const
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync const char* GetFilter() const
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync /* No file and no directory -- maybe a filter? */
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync /* Yep, get the actual filter part. */
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync /* Remove the filter from actual sourcec directory name. */
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsynctypedef std::vector<SOURCEFILEENTRY> SOURCEVEC, *PSOURCEVEC;
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * An entry for an element which needs to be copied/created to/on the guest.
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync DESTFILEENTRY(Utf8Str strFileName) : mFileName(strFileName) {}
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync * Map for holding destination entires, whereas the key is the destination
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync * directory and the mapped value is a vector holding all elements for this directoy.
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsynctypedef std::map< Utf8Str, std::vector<DESTFILEENTRY> > DESTDIRMAP, *PDESTDIRMAP;
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsynctypedef std::map< Utf8Str, std::vector<DESTFILEENTRY> >::iterator DESTDIRMAPITER, *PDESTDIRMAPITER;
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync * Special exit codes for returning errors/information of a
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync * started guest process to the command line VBoxManage was started from.
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync * Useful for e.g. scripting.
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync * @note These are frozen as of 4.1.0.
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync /* Process exited normally but with an exit code <> 0. */
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync * RTGetOpt-IDs for the guest execution control command line.
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsyncstatic int ctrlCopyDirExists(PCOPYCONTEXT pContext, bool bGuest, const char *pszDir, bool *fExists);
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync#endif /* VBOX_ONLY_DOCS */
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsyncvoid usageGuestControl(PRTSTREAM pStrm, const char *pcszSep1, const char *pcszSep2)
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync "%s guestcontrol %s <vmname>|<uuid>\n"
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync " exec[ute]\n"
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync " --image <path to program> --username <name>\n"
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync " [--passwordfile <file> | --password <password>]\n"
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync " [--domain <domain>] [--verbose] [--timeout <msec>]\n"
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync " [--environment \"<NAME>=<VALUE> [<NAME>=<VALUE>]\"]\n"
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync " [--wait-exit] [--wait-stdout] [--wait-stderr]\n"
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync " [--dos2unix] [--unix2dos]\n"
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync " [-- [<argument1>] ... [<argumentN>]]\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync /** @todo Add a "--" parameter (has to be last parameter) to directly execute
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync * stuff, e.g. "VBoxManage guestcontrol execute <VMName> --username <> ... -- /bin/rm -Rf /foo". */
b72d3233df38e3122eda39b39a27b35c27209615vboxsync " copyfrom\n"
b72d3233df38e3122eda39b39a27b35c27209615vboxsync " <guest source> <host dest> --username <name>\n"
5981e6935987b08737b730b63a41acc1dd696377vboxsync " [--passwordfile <file> | --password <password>]\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " [--domain <domain>] [--verbose]\n"
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync " [--dryrun] [--follow] [--recursive]\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " copyto|cp\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " <host source> <guest dest> --username <name>\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " [--passwordfile <file> | --password <password>]\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " [--domain <domain>] [--verbose]\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " [--dryrun] [--follow] [--recursive]\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " createdir[ectory]|mkdir|md\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " <guest directory>... --username <name>\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " [--passwordfile <file> | --password <password>]\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " [--domain <domain>] [--verbose]\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " [--parents] [--mode <mode>]\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " <file>... --username <name>\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " [--passwordfile <file> | --password <password>]\n"
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync " [--domain <domain>] [--verbose]\n"
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync " updateadditions\n"
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync " [--source <guest additions .ISO>] [--verbose]\n"
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync " [--wait-start]\n"
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync * Signal handler that sets g_fGuestCtrlCanceled.
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync * This can be executed on any thread in the process, on Windows it may even be
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync * a thread dedicated to delivering this signal. Do not doing anything
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync * unnecessary here.
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync * Installs a custom signal handler to get notified
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync * whenever the user wants to intercept the program.
683eff3070b1b86fe71b71af7fda82766ea19d17vboxsync * Uninstalls a previously installed signal handler.
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * Translates a process status to a human readable
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsyncstatic const char *ctrlExecProcessStatusToText(ProcessStatus_T enmStatus)
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync return "starting";
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync return "started";
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync return "paused";
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync return "terminating";
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync return "successfully terminated";
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync return "terminated by signal";
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync return "abnormally aborted";
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync return "timed out";
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync return "timed out, hanging";
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync return "killed";
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync return "error";
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync return "unknown";
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsyncstatic int ctrlExecProcessStatusToExitCode(ProcessStatus_T enmStatus, ULONG uExitCode)
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync vrc = !uExitCode ? EXITCODEEXEC_SUCCESS : EXITCODEEXEC_CODE;
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync /* Service/OS is stopping, process was killed, so
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * not exactly an error of the started process ... */
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync AssertMsgFailed(("Unknown exit code (%u) from guest process returned!\n", enmStatus));
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsyncstatic int ctrlPrintError(com::ErrorInfo &errorInfo)
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * because it contains more accurate info about what went wrong. */
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync if (errorInfo.getResultCode() == VBOX_E_IPRT_ERROR)
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync AssertMsgFailedReturn(("Object has indicated no error (%Rhrc)!?\n", errorInfo.getResultCode()),
b72d3233df38e3122eda39b39a27b35c27209615vboxsyncstatic int ctrlPrintError(IUnknown *pObj, const GUID &aIID)
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsyncstatic int ctrlPrintProgressError(ComPtr<IProgress> pProgress)
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync CHECK_ERROR_BREAK(pProgress, COMGETTER(Canceled)(&fCanceled));
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync CHECK_ERROR_BREAK(pProgress, COMGETTER(ResultCode)(&rcProc));
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync } while(0);
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync AssertMsgStmt(NULL, ("Could not lookup progress information\n"), vrc = VERR_COM_UNEXPECTED);
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * Un-initializes the VM after guest control usage.
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * Initializes the VM for IGuest operations.
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * That is, checks whether it's up and running, if it can be locked (shared
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * only) and returns a valid IGuest pointer on success.
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * @return IPRT status code.
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * @param pArg Our command line argument structure.
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * @param pszNameOrId The VM's name or UUID.
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * @param pGuest Where to return the IGuest interface pointer.
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsyncstatic int ctrlInitVM(HandlerArg *pArg, const char *pszNameOrId, ComPtr<IGuest> *pGuest)
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync AssertPtrReturn(pszNameOrId, VERR_INVALID_PARAMETER);
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync /* Lookup VM. */
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync /* Assume it's an UUID. */
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync CHECK_ERROR(pArg->virtualBox, FindMachine(Bstr(pszNameOrId).raw(),
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync /* Machine is running? */
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1);
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync RTMsgError("Machine \"%s\" is not running (currently %s)!\n",
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync pszNameOrId, machineStateToName(machineState, false));
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync /* Open a session for the VM. */
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync CHECK_ERROR_BREAK(machine, LockMachine(pArg->session, LockType_Shared));
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync /* Get the associated console. */
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync CHECK_ERROR_BREAK(pArg->session, COMGETTER(Console)(console.asOutParam()));
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync /* ... and session machine. */
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync CHECK_ERROR_BREAK(pArg->session, COMGETTER(Machine)(sessionMachine.asOutParam()));
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync /* Get IGuest interface. */
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync CHECK_ERROR_BREAK(console, COMGETTER(Guest)(pGuest->asOutParam()));
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync } while (0);
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync return SUCCEEDED(rc) ? VINF_SUCCESS : VERR_GENERAL_FAILURE;
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * Prints the desired guest output to a stream.
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * @return IPRT status code.
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * @param pProcess Pointer to appropriate process object.
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * @param pStrmOutput Where to write the data.
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * @param hStream Where to read the data from.
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsyncstatic int ctrlExecPrintOutput(IProcess *pProcess, PRTSTREAM pStrmOutput,
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync AssertPtrReturn(pStrmOutput, VERR_INVALID_POINTER);
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync HRESULT rc = pProcess->Read(uHandle, _64K, 30 * 1000 /* 30s timeout. */,
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync vrc = ctrlPrintError(pProcess, COM_IIDOF(IProcess));
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync /** @todo implement the dos2unix/unix2dos conversions */
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync vrc = RTStrmWrite(pStrmOutput, aOutputData.raw(), aOutputData.size());
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync RTMsgError("Unable to write output, rc=%Rrc\n", vrc);
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * Returns the remaining time (in ms) based on the start time and a set
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * timeout value. Returns RT_INDEFINITE_WAIT if no timeout was specified.
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * @return RTMSINTERVAL Time left (in ms).
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * @param u64StartMs Start time (in ms).
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * @param cMsTimeout Timeout value (in ms).
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsyncinline RTMSINTERVAL ctrlExecGetRemainingTime(uint64_t u64StartMs, RTMSINTERVAL cMsTimeout)
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync if (!cMsTimeout || cMsTimeout == RT_INDEFINITE_WAIT) /* If no timeout specified, wait forever. */
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync uint32_t u64ElapsedMs = RTTimeMilliTS() - u64StartMs;
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync/* <Missing documentation> */
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsyncstatic int handleCtrlExecProgram(ComPtr<IGuest> pGuest, HandlerArg *pArg)
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync * Parse arguments.
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync { "--dos2unix", GETOPTDEF_EXEC_DOS2UNIX, RTGETOPT_REQ_NOTHING },
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync { "--ignore-operhaned-processes", GETOPTDEF_EXEC_IGNOREORPHANEDPROCESSES, RTGETOPT_REQ_NOTHING },
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync { "--no-profile", GETOPTDEF_EXEC_NO_PROFILE, RTGETOPT_REQ_NOTHING },
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync { "--password", GETOPTDEF_EXEC_PASSWORD, RTGETOPT_REQ_STRING },
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync { "--unix2dos", GETOPTDEF_EXEC_UNIX2DOS, RTGETOPT_REQ_NOTHING },
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync { "--wait-exit", GETOPTDEF_EXEC_WAITFOREXIT, RTGETOPT_REQ_NOTHING },
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync { "--wait-stdout", GETOPTDEF_EXEC_WAITFORSTDOUT, RTGETOPT_REQ_NOTHING },
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync { "--wait-stderr", GETOPTDEF_EXEC_WAITFORSTDERR, RTGETOPT_REQ_NOTHING }
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync RTGetOptInit(&GetState, pArg->argc, pArg->argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, 0);
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync bool fWaitForExit = false;
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync bool fVerbose = false;
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync /* Wait for process start in any case. This is useful for scripting VBoxManage
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync * when relying on its overall exit code. */
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync /* For options that require an argument, ValueUnion has received the value. */
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync return errorSyntax(USAGE_GUESTCONTROL, "More than one output type (dos2unix/unix2dos) specified!");
b72d3233df38e3122eda39b39a27b35c27209615vboxsync vrc = RTGetOptArgvFromString(&papszArg, &cArgs, ValueUnion.psz, NULL);
9b456547aefb8a2e8f5600eba9ec377dbc9b4475vboxsync return errorSyntax(USAGE_GUESTCONTROL, "Failed to parse environment value, rc=%Rrc", vrc);
6d41476175401a18893ea8cb8a40d125eefa04f3vboxsync for (int j = 0; j < cArgs; j++)
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync aCreateFlags.push_back(ProcessCreateFlag_IgnoreOrphanedProcesses);
return rcExit;
case GETOPTDEF_EXEC_UNIX2DOS:
fVerbose = true;
fWaitForExit = true;
fWaitForExit = true;
fWaitForExit = true;
case VINF_GETOPT_NOT_OPTION:
if (fVerbose)
if (cMsTimeout == 0)
return RTEXITCODE_FAILURE;
return RTEXITCODE_FAILURE;
if (fWaitForExit)
if (fVerbose)
bool fCompleted = false;
return RTEXITCODE_FAILURE;
switch (waitResult)
case ProcessWaitResult_Start:
if (fVerbose)
return RTEXITCODE_FAILURE;
case ProcessWaitResult_StdOut:
fReadStdOut = true;
case ProcessWaitResult_StdErr:
fReadStdErr = true;
fCompleted = true;
fReadStdOut = false;
fReadStdErr = false;
if (fCompleted)
return RTEXITCODE_FAILURE;
return RTEXITCODE_FAILURE;
if (fVerbose)
if (fVerbose)
return EXITCODEEXEC_TERM_ABEND;
return VINF_SUCCESS;
if (pContext)
delete pContext;
#if 0 /** @todo r=bird: It does not make sense to apply host path parsing semantics onto guest paths. I hope this code isn't mixing host/guest paths in the same way anywhere else... @bugref{6344} */
int vrc;
if (pszDestFileName)
return vrc;
#ifdef DEBUG_andy
static int tstTranslatePath()
const char *pszSourceRoot;
const char *pszSource;
const char *pszDest;
const char *pszTranslated;
int iResult;
} aTests[] =
#ifdef RT_OS_WINDOWS
{ "/home/test/foo", "/home/test/foo/baz/bar.txt", "/opt/test", "/opt/test/baz/bar.txt", VINF_SUCCESS },
{ NULL }
else if ( pszTranslated
if (pszTranslated)
bool fDirExists;
&& fDirExists)
return VINF_SUCCESS;
return vrc;
return VINF_SUCCESS;
return vrc;
if (bGuest)
return vrc;
bool *fExists)
bool *fExists)
if (bOnGuest)
return vrc;
bool *fExists)
bool *fExists)
return VINF_SUCCESS;
return vrc;
bool fDirCreated = false;
case RTDIRENTRYTYPE_DIRECTORY:
if (pszSubDir)
if (pszNewSub)
case RTDIRENTRYTYPE_SYMLINK:
case RTDIRENTRYTYPE_FILE:
if ( pszFilter
if (!fDirCreated)
char *pszDestDir;
fDirCreated = true;
if (pszFileSource)
char *pszFileDest;
return vrc;
return vrc;
bool fDirCreated = false;
switch (enmType)
case FsObjType_Directory:
if (pszSubDir)
if (pszNewSub)
case FsObjType_Symlink:
case FsObjType_File:
if ( pszFilter
if (!fDirCreated)
char *pszDestDir;
fDirCreated = true;
if (pszFileSource)
char *pszFileDest;
enmType);
switch (rc)
szCurDir);
return vrc;
if ( lenRoot
return VINF_SUCCESS;
bool fHostToGuest)
* what and how to implement the file enumeration/recursive lookup, like VBoxManage
int ch;
bool fVerbose = false;
bool fCopyRecursive = false;
bool fDryRun = false;
switch (ch)
case GETOPTDEF_COPY_DRYRUN:
fDryRun = true;
case GETOPTDEF_COPY_FOLLOW:
return rcExit;
case GETOPTDEF_COPY_TARGETDIR:
fVerbose = true;
case VINF_GETOPT_NOT_OPTION:
if (fVerbose)
if (fHostToGuest)
if (fDryRun)
return RTEXITCODE_FAILURE;
* copyto myfile.txt 'C:\guestfile.txt'
* copyto myfile.txt 'D:guestfile.txt'
char *pszSourceRoot;
if (fVerbose)
bool fSourceIsFile = false;
bool fSourceExists;
if (fSourceExists)
&& fSourceExists)
fSourceIsFile = true;
&& fSourceExists)
if (fSourceIsFile)
char *pszDestFile;
&& !fSourceExists)
int ch;
bool fVerbose = false;
switch (ch)
return rcExit;
fVerbose = true;
case VINF_GETOPT_NOT_OPTION:
if (!cDirs)
if (fVerbose)
hrc = pGuestSession->DirectoryCreate(Bstr(it->first).raw(), fDirMode, ComSafeArrayAsInParam(dirCreateFlags));
it++;
int ch;
bool fDirectory = false;
bool fSecure = false;
bool fVerbose = false;
switch (ch)
fDirectory = true;
fSecure = true;
return rcExit;
fVerbose = true;
case VINF_GETOPT_NOT_OPTION:
if (!fDirectory)
if (fVerbose)
else if (fDirectory)
else if (!fDirectory)
if (fDirectory)
int ch;
bool fVerbose = false;
switch (ch)
return rcExit;
fVerbose = true;
case VINF_GETOPT_NOT_OPTION:
if (!cObjs)
if (fVerbose)
if (fVerbose)
switch (objType)
case FsObjType_File:
case FsObjType_Directory:
case FsObjType_Symlink:
it++;
return rcExit;
bool fVerbose = false;
bool fWaitStartOnly = false;
int ch;
switch (ch)
fVerbose = true;
fWaitStartOnly = true;
if (fVerbose)
if (fVerbose)
if (fWaitStartOnly)
if (fVerbose)
if (fVerbose)
&& fVerbose)
#ifdef DEBUG_andy_disabled
return RTEXITCODE_FAILURE;
int rcExit;
return rcExit;
return RTEXITCODE_FAILURE;