/* $Id: gctrl.cpp 62489 2016-07-22 18:41:09Z vboxsync $ */ /** @file * Guest Control Service: Internal function used by service, Main and testcase. */ /* * Copyright (C) 2010-2016 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. */ /********************************************************************************************************************************* * Header Files * *********************************************************************************************************************************/ #define LOG_GROUP LOG_GROUP_HGCM #include /** @todo Remove unused header files below! */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gctrl.h" namespace guestControl { /** * Creates the argument list as an array used for executing a program. * * @returns VBox status code. * * @todo * * @todo Respect spaces when quoting for arguments, e.g. "c:\\program files\\". * @todo Handle empty ("") arguments. */ int gctrlPrepareExecArgv(char *pszArgs, void **ppvList, uint32_t *pcbList, uint32_t *pcArgs) { char **ppaArg; int iArgs; int rc = RTGetOptArgvFromString(&ppaArg, &iArgs, pszArgs, RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL); if (RT_SUCCESS(rc)) { char *pszTemp = NULL; *pcbList = 0; for (int i=0; i 0) /* Insert space as delimiter. */ rc = RTStrAAppendN(&pszTemp, " ", 1); if (RT_FAILURE(rc)) break; else { rc = RTStrAAppendN(&pszTemp, ppaArg[i], strlen(ppaArg[i])); if (RT_FAILURE(rc)) break; } } RTGetOptArgvFree(ppaArg); if (RT_SUCCESS(rc)) { *ppvList = pszTemp; *pcArgs = iArgs; *pcbList = strlen(pszTemp) + 1; /* Include zero termination. */ } else RTStrFree(pszTemp); } return rc; } /** * Appends environment variables to the environment block. Each var=value pair is separated * by NULL (\0) sequence. The whole block will be stored in one blob and disassembled on the * guest side later to fit into the HGCM param structure. * * @returns VBox status code. * * @todo * */ int gctrlAddToExecEnvv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnv) { int rc = VINF_SUCCESS; uint32_t cbLen = strlen(pszEnv); if (*ppvList) { uint32_t cbNewLen = *pcbList + cbLen + 1; /* Include zero termination. */ char *pvTmp = (char*)RTMemRealloc(*ppvList, cbNewLen); if (NULL == pvTmp) { rc = VERR_NO_MEMORY; } else { memcpy(pvTmp + *pcbList, pszEnv, cbLen); pvTmp[cbNewLen - 1] = '\0'; /* Add zero termination. */ *ppvList = (void**)pvTmp; } } else { char *pcTmp; if (RTStrAPrintf(&pcTmp, "%s", pszEnv) > 0) { *ppvList = (void**)pcTmp; /* Reset counters. */ *pcEnv = 0; *pcbList = 0; } } if (RT_SUCCESS(rc)) { *pcbList += cbLen + 1; /* Include zero termination. */ *pcEnv += 1; /* Increase env pairs count. */ } return rc; } /* int gctrlAllocateExecBlock(PVBOXGUESTCTRLEXECBLOCK *ppBlock, const char *pszCmd, uint32_t fFlags, uint32_t cArgs, const char * const *papszArgs, uint32_t cEnvVars, const char * const *papszEnv, const char *pszStdIn, const char *pszStdOut, const char *pszStdErr, const char *pszUsername, const char *pszPassword, RTMSINTERVAL cMillies) { PVBOXGUESTCTRLEXECBLOCK pNewBlock = (VBOXGUESTCTRLEXECBLOCK*)RTMemAlloc(sizeof(VBOXGUESTCTRLEXECBLOCK)); int rc; if (pNewBlock) { *ppBlock = pNewBlock; rc = VINF_SUCCESS; } else rc = VERR_NO_MEMORY; return rc; } int gctrlFreeExecBlock(PVBOXGUESTCTRLEXECBLOCK pBlock) { AssertPtr(pBlock); RTStrFree(pBlock->pszCmd); RTMemFree(pBlock->pvArgs); RTMemFree(pBlock->pvEnv); RTStrFree(pBlock->pszStdIn); RTStrFree(pBlock->pszStdOut); RTStrFree(pBlock->pszStdErr); RTStrFree(pBlock->pszUsername); RTStrFree(pBlock->pszPassword); RT_ZERO(*pBlock); return VINF_SUCCESS; } int gctrlPrepareHostCmdExec(PVBOXHGCMSVCPARM *ppaParms, uint32_t *pcParms, PVBOXGUESTCTRLEXECBLOCK pBlock) { AssertPtr(ppaParms); AssertPtr(pBlock); PVBOXHGCMSVCPARM pNewParms = (VBOXHGCMSVCPARM*)RTMemAlloc(sizeof(VBOXHGCMSVCPARM) * 13); int rc; if (pNewParms) { pNewParms[0].setUInt32(HOST_EXEC_CMD); pNewParms[1].setUInt32(pBlock->u32Flags); pNewParms[2].setPointer((void*)pBlock->pszCmd, (uint32_t)strlen(pBlock->pszCmd) + 1); pNewParms[3].setUInt32(pBlock->u32Args); pNewParms[4].setPointer((void*)pBlock->pvArgs, pBlock->cbArgs); pNewParms[5].setUInt32(pBlock->u32EnvVars); pNewParms[6].setPointer((void*)pBlock->pvEnv, pBlock->cbEnv); pNewParms[7].setPointer((void*)pBlock->pszStdIn, (uint32_t)strlen(pBlock->pszStdIn) + 1); pNewParms[8].setPointer((void*)pBlock->pszStdOut, (uint32_t)strlen(pBlock->pszStdOut) + 1); pNewParms[9].setPointer((void*)pBlock->pszStdErr, (uint32_t)strlen(pBlock->pszStdErr) + 1); pNewParms[10].setPointer((void*)pBlock->pszUsername, (uint32_t)strlen(pBlock->pszUsername) + 1); pNewParms[11].setPointer((void*)pBlock->pszPassword, (uint32_t)strlen(pBlock->pszPassword) + 1); pNewParms[12].setUInt32(pBlock->cMillies); *ppaParms = pNewParms; rc = VINF_SUCCESS; } else rc = VERR_NO_MEMORY; if (pcParms) *pcParms = 13; return rc; } void gctrlFreeHostCmd(PVBOXHGCMSVCPARM paParms) { RTMemFree(paParms); } */ }