gboolean RpcChannel_Dispatch(RpcInData *data) { char *name = NULL; unsigned int index = 0; size_t nameLen; Bool status; RpcChannelCallback *rpc = NULL; RpcChannelInt *chan = data->clientData; name = StrUtil_GetNextToken(&index, data->args, " "); if (name == NULL) { Debug(LGPFX "Bad command (null) received.\n"); status = RPCIN_SETRETVALS(data, "Bad command", FALSE); goto exit; } if (chan->rpcs != NULL) { rpc = g_hash_table_lookup(chan->rpcs, name); } if (rpc == NULL) { Debug(LGPFX "Unknown Command '%s': Handler not registered.\n", name); status = RPCIN_SETRETVALS(data, "Unknown Command", FALSE); goto exit; } /* Adjust the RPC arguments. */ nameLen = strlen(name); data->name = name; data->args = data->args + nameLen; data->argsSize -= nameLen; data->appCtx = chan->appCtx; data->clientData = rpc->clientData; if (rpc->xdrIn != NULL || rpc->xdrOut != NULL) { status = RpcChannelXdrWrapper(data, rpc); } else { status = rpc->callback(data); } ASSERT(data->result != NULL); exit: data->name = NULL; free(name); return status; }
gboolean ToolsDaemonTcloSyncDriverThaw(RpcInData *data) // IN { static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH]; VixError err = VIX_OK; DECLARE_SYNCDRIVER_ERROR(sysError); Debug(">ToolsDaemonTcloSyncDriverThaw\n"); /* * This function has no arguments that we care about. */ Debug("SYNCDRIVE: Got request to thaw\n"); if (gSyncDriverHandle == SYNCDRIVER_INVALID_HANDLE) { err = VIX_E_GUEST_VOLUMES_NOT_FROZEN; sysError = SYNCDRIVERERROR; Debug("ToolsDaemonTcloSyncDriverThaw: No drives are frozen.\n"); } else if (!SyncDriver_Thaw(gSyncDriverHandle)) { err = VIX_E_FAIL; sysError = SYNCDRIVERERROR; Debug("ToolsDaemonTcloSyncDriverThaw: Failed to Thaw drives\n"); } SyncDriver_CloseHandle(&gSyncDriverHandle); /* * All Foundry tools commands return results that start with a * foundry error and a guest-OS-specific error. */ Str_Sprintf(resultBuffer, sizeof resultBuffer, "%"FMT64"d %d", err, sysError); Debug("<ToolsDaemonTcloSyncDriverThaw\n"); return RPCIN_SETRETVALS(data, resultBuffer, TRUE); }
static gboolean ToolsCoreRpcCapReg(RpcInData *data) { char *confPath = GuestApp_GetConfPath(); gchar *msg; GArray *pcaps = NULL; ToolsServiceState *state = data->clientData; g_signal_emit_by_name(state->ctx.serviceObj, TOOLS_CORE_SIG_CAPABILITIES, &state->ctx, TRUE, &pcaps); if (pcaps != NULL) { ToolsCore_SetCapabilities(state->ctx.rpc, pcaps, TRUE); g_array_free(pcaps, TRUE); } /* Tell the host the location of the conf directory. */ msg = g_strdup_printf("tools.capability.guest_conf_directory %s", confPath); if (!RpcChannel_Send(state->ctx.rpc, msg, strlen(msg) + 1, NULL, NULL)) { g_debug("Unable to register guest conf directory capability.\n"); } g_free(msg); msg = NULL; /* Send the tools version to the VMX. */ if (state->mainService) { uint32 version; char *result = NULL; size_t resultLen; gchar *toolsVersion; #if defined(OPEN_VM_TOOLS) version = TOOLS_VERSION_UNMANAGED; #else gboolean disableVersion; disableVersion = g_key_file_get_boolean(state->ctx.config, "vmtools", CONFNAME_DISABLETOOLSVERSION, NULL); version = disableVersion ? TOOLS_VERSION_UNMANAGED : TOOLS_VERSION_CURRENT; #endif toolsVersion = g_strdup_printf("tools.set.version %u", version); if (!RpcChannel_Send(state->ctx.rpc, toolsVersion, strlen(toolsVersion) + 1, &result, &resultLen)) { g_debug("Error setting tools version: %s.\n", result); } vm_free(result); g_free(toolsVersion); } state->capsRegistered = TRUE; free(confPath); return RPCIN_SETRETVALS(data, "", TRUE); }
static gboolean ToolsCoreRpcSetOption(RpcInData *data) { gboolean retVal = FALSE; char *option; char *value; unsigned int index = 0; ToolsServiceState *state = data->clientData; /* Parse the option & value string. */ option = StrUtil_GetNextToken(&index, data->args, " "); /* Ignore leading space before value. */ index++; value = StrUtil_GetNextToken(&index, data->args, ""); if (option != NULL && value != NULL && strlen(value) != 0) { g_debug("Setting option '%s' to '%s'.\n", option, value); g_signal_emit_by_name(state->ctx.serviceObj, TOOLS_CORE_SIG_SET_OPTION, &state->ctx, option, value, &retVal); } vm_free(option); vm_free(value); RPCIN_SETRETVALS(data, retVal ? "" : "Unknown or invalid option", retVal); return retVal; }
static gboolean VmBackupStart(RpcInData *data) { g_debug("*** %s\n", __FUNCTION__); if (gBackupState != NULL) { return RPCIN_SETRETVALS(data, "Quiesce operation already in progress.", FALSE); } gBackupState = g_new0(VmBackupState, 1); if (data->argsSize > 0) { int generateManifests = 0; uint32 index = 0; if (StrUtil_GetNextIntToken(&generateManifests, &index, data->args, " ")) { gBackupState->generateManifests = generateManifests; } gBackupState->quiesceApps = TRUE; gBackupState->quiesceFS = TRUE; gBackupState->allowHWProvider = TRUE; gBackupState->execScripts = TRUE; gBackupState->scriptArg = NULL; gBackupState->timeout = 0; /* get volume uuids if provided */ if (data->args[index] != '\0') { gBackupState->volumes = g_strndup(data->args + index, data->argsSize - index); } } return VmBackupStartCommon(data, FALSE); }
gboolean ToolsDaemonTcloMountHGFS(RpcInData *data) // IN { VixError err = VIX_OK; static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH]; #if defined(linux) /* * Look for a vmhgfs mount at /mnt/hgfs. If one exists, nothing * else needs to be done. If one doesn't exist, then mount at * that location. */ FILE *mtab; struct mntent *mnt; if ((mtab = setmntent(_PATH_MOUNTED, "r")) == NULL) { err = VIX_E_FAIL; } else { Bool vmhgfsMntFound = FALSE; while ((mnt = getmntent(mtab)) != NULL) { if ((strcmp(mnt->mnt_fsname, ".host:/") == 0) && (strcmp(mnt->mnt_type, HGFS_NAME) == 0) && (strcmp(mnt->mnt_dir, "/mnt/hgfs") == 0)) { vmhgfsMntFound = TRUE; break; } } endmntent(mtab); if (!vmhgfsMntFound) { /* * We need to call the mount program, not the mount system call. The * mount program does several additional things, like compute the mount * options from the contents of /etc/fstab, and invoke custom mount * programs like the one needed for HGFS. */ int ret = system("mount -t vmhgfs .host:/ /mnt/hgfs"); if (ret == -1 || WIFSIGNALED(ret) || (WIFEXITED(ret) && WEXITSTATUS(ret) != 0)) { err = VIX_E_HGFS_MOUNT_FAIL; } } } #endif /* * All tools commands return results that start with an error * and a guest-OS-specific error. */ Str_Sprintf(resultBuffer, sizeof(resultBuffer), "%"FMT64"d %d", err, Err_Errno()); RPCIN_SETRETVALS(data, resultBuffer, TRUE); return TRUE; } // ToolsDaemonTcloMountHGFS
static gboolean ResolutionChangeHost3DAvailabilityHintCB(RpcInData *data) { unsigned int set; gboolean success = FALSE; unsigned int index = 0; g_debug("%s: enter\n", __FUNCTION__); if (!StrUtil_GetNextUintToken(&set, &index, data->args, " ")) { g_debug("%s: invalid arguments\n", __FUNCTION__); return RPCIN_SETRETVALS(data, "Invalid arguments. Expected \"set\"", FALSE); } success = ResolutionChangeHost3DAvailabilityHint(set?TRUE:FALSE); RPCIN_SETRETVALS(data, success ? "" : "ResolutionChangeHost3DAvailabilityHint failed", success); g_debug("%s: leave\n", __FUNCTION__); return success; }
static gboolean HgfsServerRpcDispatch(RpcInData *data) { HgfsServerMgrData *mgrData; size_t replySize; static char reply[HGFS_LARGE_PACKET_MAX]; ASSERT(data->clientData != NULL); mgrData = data->clientData; if (data->argsSize == 0) { return RPCIN_SETRETVALS(data, "1 argument required", FALSE); } replySize = sizeof reply; HgfsServerManager_ProcessPacket(mgrData, data->args + 1, data->argsSize - 1, reply, &replySize); data->result = reply; data->resultLen = replySize; return TRUE; }
static gboolean GuestInfoVMSupport(RpcInData *data) { #if defined(_WIN32) char vmSupportCmd[] = "vm-support.vbs"; char *vmSupportPath = NULL; gchar *vmSupport = NULL; SECURITY_ATTRIBUTES saProcess = {0}, saThread = {0}; ProcMgr_AsyncProc *vmSupportProc = NULL; ProcMgr_ProcArgs vmSupportProcArgs = {0}; /* * Construct the commandline to be passed during execution * This will be the path of our vm-support.vbs */ vmSupportPath = GuestApp_GetInstallPath(); if (vmSupportPath == NULL) { return RPCIN_SETRETVALS(data, "GuestApp_GetInstallPath failed", FALSE); } /* Put together absolute vm-support filename. */ vmSupport = g_strdup_printf("cscript \"%s%s%s\" -u", vmSupportPath, DIRSEPS, vmSupportCmd); vm_free(vmSupportPath); saProcess.nLength = sizeof saProcess; saProcess.bInheritHandle = TRUE; saThread.nLength = sizeof saThread; vmSupportProcArgs.lpProcessAttributes = &saProcess; vmSupportProcArgs.lpThreadAttributes = &saThread; vmSupportProcArgs.dwCreationFlags = CREATE_NO_WINDOW; g_message("Starting vm-support script - %s\n", vmSupport); vmSupportProc = ProcMgr_ExecAsync(vmSupport, &vmSupportProcArgs); g_free(vmSupport); if (vmSupportProc == NULL) { g_warning("Error starting vm-support script\n"); return RPCIN_SETRETVALS(data, "Error starting vm-support script", FALSE); } ProcMgr_Free(vmSupportProc); return RPCIN_SETRETVALS(data, "", TRUE); #else gchar *vmSupportCmdArgv[] = {"vm-support", "-u", NULL}; g_message("Starting vm-support script - %s\n", vmSupportCmdArgv[0]); if (!g_spawn_async(NULL, vmSupportCmdArgv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, NULL, NULL)) { g_warning("Error starting vm-support script\n"); return RPCIN_SETRETVALS(data, "Error starting vm-support script", FALSE); } return RPCIN_SETRETVALS(data, "", TRUE); #endif }
gboolean FoundryToolsDaemonRunProgram(RpcInData *data) // IN { VixError err = VIX_OK; char *requestName = NULL; char *commandLine = NULL; char *commandLineArgs = NULL; char *credentialTypeStr = NULL; char *obfuscatedNamePassword = NULL; char *directoryPath = NULL; char *environmentVariables = NULL; static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH]; Bool impersonatingVMWareUser = FALSE; void *userToken = NULL; ProcMgr_Pid pid; GMainLoop *eventQueue = ((ToolsAppCtx *)data->appCtx)->mainLoop; /* * Parse the arguments. Some of these are optional, so they * may be NULL. */ requestName = ToolsDaemonTcloGetQuotedString(data->args, &data->args); err = ToolsDaemonTcloGetEncodedQuotedString(data->args, &data->args, &commandLine); if (err != VIX_OK) { goto abort; } err = ToolsDaemonTcloGetEncodedQuotedString(data->args, &data->args, &commandLineArgs); if (err != VIX_OK) { goto abort; } credentialTypeStr = ToolsDaemonTcloGetQuotedString(data->args, &data->args); obfuscatedNamePassword = ToolsDaemonTcloGetQuotedString(data->args, &data->args); directoryPath = ToolsDaemonTcloGetQuotedString(data->args, &data->args); environmentVariables = ToolsDaemonTcloGetQuotedString(data->args, &data->args); /* * Make sure we are passed the correct arguments. * Some of these arguments (like credentialTypeStr and obfuscatedNamePassword) are optional, * so they may be NULL. */ if ((NULL == requestName) || (NULL == commandLine)) { err = VIX_E_INVALID_ARG; goto abort; } if ((NULL != credentialTypeStr) && (*credentialTypeStr) && (thisProcessRunsAsRoot)) { impersonatingVMWareUser = VixToolsImpersonateUserImpl(credentialTypeStr, VIX_USER_CREDENTIAL_NONE, obfuscatedNamePassword, &userToken); if (!impersonatingVMWareUser) { err = VIX_E_GUEST_USER_PERMISSIONS; goto abort; } } err = VixToolsRunProgramImpl(requestName, commandLine, commandLineArgs, 0, userToken, eventQueue, (int64 *) &pid); abort: if (impersonatingVMWareUser) { VixToolsUnimpersonateUser(userToken); } VixToolsLogoutUser(userToken); /* * All VMXI tools commands return results that start with a VMXI error * and a guest-OS-specific error. */ Str_Sprintf(resultBuffer, sizeof(resultBuffer), "%"FMT64"d %d %"FMT64"d", err, Err_Errno(), (int64) pid); RPCIN_SETRETVALS(data, resultBuffer, TRUE); /* * These were allocated by ToolsDaemonTcloGetQuotedString. */ free(requestName); free(commandLine); free(credentialTypeStr); free(obfuscatedNamePassword); free(directoryPath); free(environmentVariables); free(commandLineArgs); return TRUE; } // FoundryToolsDaemonRunProgram
static gboolean VmBackupStartCommon(RpcInData *data, gboolean forceVss) { GError *err = NULL; ToolsAppCtx *ctx = data->appCtx; VmBackupSyncProvider *provider = NULL; size_t i; /* List of available providers, in order of preference for loading. */ struct SyncProvider { VmBackupSyncProvider *(*ctor)(void); const gchar *cfgEntry; } providers[] = { #if defined(_WIN32) { VmBackup_NewVssProvider, "enableVSS" }, #endif { VmBackup_NewSyncDriverProvider, "enableSyncDriver" }, { VmBackup_NewNullProvider, NULL }, }; if (forceVss) { if (gBackupState->quiesceApps || gBackupState->quiesceFS) { /* If quiescing is requested, only allow VSS provider */ #if defined(_WIN32) if (VmBackupConfigGetBoolean(ctx->config, "enableVSS", TRUE)) { provider = VmBackup_NewVssProvider(); } #endif } else { /* If no quiescing is requested only allow null provider */ provider = VmBackup_NewNullProvider(); } if (provider == NULL) { g_warning("Requested quiescing cannot be initialized."); goto error; } } else { /* Instantiate the sync provider. */ for (i = 0; i < ARRAYSIZE(providers); i++) { struct SyncProvider *sp = &providers[i]; if (VmBackupConfigGetBoolean(ctx->config, sp->cfgEntry, TRUE)) { provider = sp->ctor(); if (provider != NULL) { break; } } } } ASSERT(provider != NULL); /* Instantiate the backup state and start the operation. */ gBackupState->ctx = data->appCtx; gBackupState->pollPeriod = 1000; gBackupState->machineState = VMBACKUP_MSTATE_IDLE; gBackupState->provider = provider; g_debug("Using quiesceApps = %d, quiesceFS = %d, allowHWProvider = %d," "execScripts = %d, scriptArg = %s, timeout = %u\n", gBackupState->quiesceApps, gBackupState->quiesceFS, gBackupState->allowHWProvider, gBackupState->execScripts, (gBackupState->scriptArg != NULL) ? gBackupState->scriptArg : "", gBackupState->timeout); g_debug("Quiescing volumes: %s", (gBackupState->volumes) ? gBackupState->volumes : "(null)"); gBackupState->configDir = GuestApp_GetConfPath(); if (gBackupState->configDir == NULL) { g_warning("Error getting configuration directory."); goto error; } VmBackup_SendEvent(VMBACKUP_EVENT_RESET, VMBACKUP_SUCCESS, ""); if (!VmBackupStartScripts(VMBACKUP_SCRIPT_FREEZE)) { goto error; } /* * VC has a 15 minute timeout for quiesced snapshots. After that timeout, * it just discards the operation and sends an error to the caller. But * Tools can still keep running, blocking any new quiesced snapshot * requests. So we set up our own timer (which is configurable, in case * anyone wants to play with it), so that we abort any ongoing operation * if we also hit that timeout. * * First check if the timeout is specified by the RPC command, if not, * check the tools.conf file, otherwise use the default. * * See bug 506106. */ if (gBackupState->timeout == 0) { gBackupState->timeout = (guint) g_key_file_get_integer( gBackupState->ctx->config, "vmbackup", "timeout", &err); if (err != NULL) { g_clear_error(&err); gBackupState->timeout = 15 * 60; } } /* Treat "0" as no timeout. */ if (gBackupState->timeout != 0) { gBackupState->abortTimer = g_timeout_source_new_seconds(gBackupState->timeout); VMTOOLSAPP_ATTACH_SOURCE(gBackupState->ctx, gBackupState->abortTimer, VmBackupAbortTimer, NULL, NULL); } VMBACKUP_ENQUEUE_EVENT(); return RPCIN_SETRETVALS(data, "", TRUE); error: if (gBackupState->provider) { gBackupState->provider->release(gBackupState->provider); } g_free(gBackupState->scriptArg); g_free(gBackupState->volumes); g_free(gBackupState); gBackupState = NULL; return RPCIN_SETRETVALS(data, "Error initializing quiesce operation.", FALSE); }
static gboolean ResolutionDisplayTopologySetCB(RpcInData *data) { DisplayTopologyInfo *displays = NULL; unsigned int count, i; gboolean success = FALSE; const char *p; ResolutionInfoType *resInfo = &resolutionInfo; if (!resInfo->initialized) { g_debug("%s: FAIL! Request for topology set but plugin is not initialized\n", __FUNCTION__); RPCIN_SETRETVALS(data, "Invalid guest state: topology set not initialized", FALSE); goto out; } /* * The argument string will look something like: * <count> [ , <x> <y> <w> <h> ] * count. * * e.g. * 3 , 0 0 640 480 , 640 0 800 600 , 0 480 640 480 */ if (sscanf(data->args, "%u", &count) != 1) { return RPCIN_SETRETVALS(data, "Invalid arguments. Expected \"count\"", FALSE); } displays = malloc(sizeof *displays * count); if (!displays) { RPCIN_SETRETVALS(data, "Failed to alloc buffer for display info", FALSE); goto out; } for (p = data->args, i = 0; i < count; i++) { p = strchr(p, ','); if (!p) { RPCIN_SETRETVALS(data, "Expected comma separated display list", FALSE); goto out; } p++; /* Skip past the , */ if (sscanf(p, " %d %d %d %d ", &displays[i].x, &displays[i].y, &displays[i].width, &displays[i].height) != 4) { RPCIN_SETRETVALS(data, "Expected x, y, w, h in display entry", FALSE); goto out; } } success = ResolutionSetTopology(count, displays); RPCIN_SETRETVALS(data, success ? "" : "ResolutionSetTopology failed", success); out: free(displays); return success; }
static gboolean PowerOpsStateChange(RpcInData *data) { size_t i; PowerOpState *state = data->clientData; if (state->pid != INVALID_PID) { g_debug("State change already in progress.\n"); return RPCIN_SETRETVALS(data, "State change already in progress", FALSE); } g_debug("State change: %s\n", data->name); for (i = 0; i < ARRAYSIZE(stateChangeCmdTable); i++) { if (strcmp(data->name, stateChangeCmdTable[i].tcloCmd) == 0) { gchar *script; const char *result; const char *confName; Bool ret; state->stateChgInProgress = stateChangeCmdTable[i].id; /* Check for the toolScripts option. */ if (!state->scriptEnabled[stateChangeCmdTable[i].id]) { PowerOpsStateChangeDone(state, TRUE); g_debug("Script for %s not configured to run\n", stateChangeCmdTable[i].tcloCmd); return RPCIN_SETRETVALS(data, "", TRUE); } confName = stateChgConfNames[stateChangeCmdTable[i].id]; script = g_key_file_get_string(state->ctx->config, "powerops", confName, NULL); if (script == NULL) { /* Use default script if not set in config file. */ const char *dfltScript = GuestApp_GetDefaultScript(confName); if (dfltScript == NULL) { g_debug("No default script to run for state change %s.\n", stateChangeCmdTable[i].name); PowerOpsStateChangeDone(state, TRUE); return RPCIN_SETRETVALS(data, "", TRUE); } script = g_strdup(dfltScript); } else if (strlen(script) == 0) { g_debug("No script to run for state change %s.\n", stateChangeCmdTable[i].name); g_free(script); PowerOpsStateChangeDone(state, TRUE); return RPCIN_SETRETVALS(data, "", TRUE); } /* If script path is not absolute, assume the Tools install path. */ if (!g_path_is_absolute(script)) { char *dfltPath; char *tmp; dfltPath = GuestApp_GetInstallPath(); ASSERT(dfltPath != NULL); /* * Before the switch to vmtoolsd, the config file was saved with * quotes around the script path to make the old VMware dict code * happy. Now we need to undo that when modifying the script path. * * PowerOpsRunScript will "re-quote" the script path. */ if (script[0] == '"') { script[strlen(script) - 1] = '\0'; tmp = g_strdup_printf("%s%c%s", dfltPath, DIRSEPC, script + 1); } else { tmp = g_strdup_printf("%s%c%s", dfltPath, DIRSEPC, script); } g_free(script); vm_free(dfltPath); script = tmp; } if (PowerOpsRunScript(state, script)) { result = ""; ret = TRUE; } else { PowerOpsStateChangeDone(state, FALSE); result = "Error starting script"; ret = FALSE; } g_free(script); return RPCIN_SETRETVALS(data, (char *) result, ret); } } g_warning("Invalid state change command.\n"); return RPCIN_SETRETVALS(data, "Invalid state change command", FALSE); }
static gboolean RecvMsgCB(RpcInData *data) // IN/OUT { LOG(4, ("%s: receiving\n", __FUNCTION__)); const uint8 *packet = (const uint8 *)(data->args + 1); size_t packetSize = data->argsSize - 1; /* '- 1' is to ignore empty space between command and args. */ if ((data->argsSize - 1) <= 0) { Debug("%s: invalid argsSize\n", __FUNCTION__); return RPCIN_SETRETVALS(data, "invalid arg size", FALSE); } GuestRpcCBCtx *ctx = (GuestRpcCBCtx *)data->clientData; #else /** * Received a message from guestRpc. Forward the message to transport class. * * @param[in] clientData callback client data. * @param[ignored] channelId * @param[in] args argument list. * @param[in] argsSize argument list size in byte. * @param[out] result reply string. * @param[out] resultSize reply string length in byte. * * @return TRUE if success, FALSE otherwise. */ static Bool RecvMsgCB(void *clientData, GuestRpcChannel *chan, const unsigned char *args, uint32 argsSize, unsigned char **result, uint32 *resultSize) { const uint8 *packet = args; size_t packetSize = argsSize; GuestRpcCBCtx *ctx = (GuestRpcCBCtx *)clientData; #endif ASSERT(ctx); ASSERT(ctx->transport); ctx->transport->OnRecvPacket(ctx->type, packet, packetSize); #ifdef VMX86_TOOLS return RPCIN_SETRETVALS(data, "", TRUE); #else return GuestRpc_SetRetVals(result, resultSize, (char *)"", TRUE); #endif } /** * Constructor. */ TransportGuestRpcTables::TransportGuestRpcTables(void) { for (int i = 0; i < TRANSPORT_INTERFACE_MAX; i++) { mRpcList[i] = NULL; mCmdStrTable[i] = NULL; mDisableStrTable[i] = NULL; #ifdef VMX86_TOOLS } #else mCmdTable[i] = GUESTRPC_CMD_MAX; } mCmdTable[TRANSPORT_GUEST_CONTROLLER_DND] = GUESTRPC_CMD_DND_TRANSPORT; mCmdTable[TRANSPORT_GUEST_CONTROLLER_CP] = GUESTRPC_CMD_COPYPASTE_TRANSPORT; #endif mCmdStrTable[TRANSPORT_GUEST_CONTROLLER_DND] = (char *)GUEST_RPC_CMD_STR_DND; mCmdStrTable[TRANSPORT_GUEST_CONTROLLER_CP] = (char *)GUEST_RPC_CMD_STR_CP; mDisableStrTable[TRANSPORT_GUEST_CONTROLLER_DND] = (char *)GUEST_RPC_DND_DISABLE; mDisableStrTable[TRANSPORT_GUEST_CONTROLLER_CP] = (char *)GUEST_RPC_CP_DISABLE; }
static Bool RpcChannelXdrWrapper(RpcInData *data, RpcChannelCallback *rpc) { Bool ret; RpcInData copy; void *xdrData = NULL; if (rpc->xdrIn != NULL) { xdrData = malloc(rpc->xdrInSize); if (xdrData == NULL) { ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE); goto exit; } memset(xdrData, 0, rpc->xdrInSize); if (!XdrUtil_Deserialize(data->args + 1, data->argsSize - 1, rpc->xdrIn, xdrData)) { ret = RPCIN_SETRETVALS(data, "XDR deserialization failed.", FALSE); free(xdrData); goto exit; } copy.name = data->name; copy.args = xdrData; copy.argsSize = rpc->xdrInSize; copy.result = data->result; copy.resultLen = data->resultLen; copy.freeResult = data->freeResult; copy.appCtx = data->appCtx; copy.clientData = rpc->clientData; } else { memcpy(©, data, sizeof copy); } ret = rpc->callback(©); if (rpc->xdrIn != NULL) { VMX_XDR_FREE(rpc->xdrIn, xdrData); free(xdrData); copy.args = NULL; data->result = copy.result; data->resultLen = copy.resultLen; data->freeResult = copy.freeResult; } if (rpc->xdrOut != NULL && copy.result != NULL) { XDR xdrs; xdrproc_t xdrProc = rpc->xdrOut; if (DynXdr_Create(&xdrs) == NULL) { ret = RPCIN_SETRETVALS(data, "Out of memory.", FALSE); goto exit; } if (!xdrProc(&xdrs, copy.result)) { ret = RPCIN_SETRETVALS(data, "XDR serialization failed.", FALSE); DynXdr_Destroy(&xdrs, TRUE); goto exit; } if (copy.freeResult) { VMX_XDR_FREE(rpc->xdrOut, copy.result); } data->result = DynXdr_Get(&xdrs); data->resultLen = XDR_GETPOS(&xdrs); data->freeResult = TRUE; DynXdr_Destroy(&xdrs, FALSE); } exit: if (copy.freeResult && copy.result != NULL) { g_free(copy.result); } return ret; }
gboolean ToolsDaemonTcloSyncDriverFreeze(RpcInData *data) { static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH]; VixError err = VIX_OK; char *driveList = NULL; char *timeout = NULL; int timeoutVal; DECLARE_SYNCDRIVER_ERROR(sysError); ToolsAppCtx *ctx = data->appCtx; GSource *timer; Debug(">ToolsDaemonTcloSyncDriverFreeze\n"); /* * Parse the arguments */ driveList = ToolsDaemonTcloGetQuotedString(data->args, &data->args); timeout = ToolsDaemonTcloGetQuotedString(data->args, &data->args); /* * Validate the arguments. */ if (NULL == driveList || NULL == timeout) { err = VIX_E_INVALID_ARG; Debug("ToolsDaemonTcloSyncDriverFreeze: Failed to get string args\n"); goto abort; } if (!StrUtil_StrToInt(&timeoutVal, timeout) || timeoutVal < 0) { Debug("ToolsDaemonTcloSyncDriverFreeze: Bad args, timeout '%s'\n", timeout); err = VIX_E_INVALID_ARG; goto abort; } Debug("SYNCDRIVE: Got request to freeze '%s', timeout %d\n", driveList, timeoutVal); /* Disallow multiple freeze calls. */ if (gSyncDriverHandle != SYNCDRIVER_INVALID_HANDLE) { err = VIX_E_OBJECT_IS_BUSY; goto abort; } /* Perform the actual freeze. */ if (!SyncDriver_Freeze(driveList, &gSyncDriverHandle) || SyncDriver_QueryStatus(gSyncDriverHandle, INFINITE) != SYNCDRIVER_IDLE) { Debug("ToolsDaemonTcloSyncDriverFreeze: Failed to Freeze drives '%s'\n", driveList); err = VIX_E_FAIL; sysError = SYNCDRIVERERROR; if (gSyncDriverHandle != SYNCDRIVER_INVALID_HANDLE) { SyncDriver_Thaw(gSyncDriverHandle); SyncDriver_CloseHandle(&gSyncDriverHandle); } goto abort; } /* Start the timer callback to automatically thaw. */ if (0 != timeoutVal) { Debug("ToolsDaemonTcloSyncDriverFreeze: Starting timer callback %d\n", timeoutVal); timer = g_timeout_source_new(timeoutVal * 10); VMTOOLSAPP_ATTACH_SOURCE(ctx, timer, ToolsDaemonSyncDriverThawCallback, NULL, NULL); g_source_unref(timer); } abort: /* * These were allocated by ToolsDaemonTcloGetQuotedString. */ free(driveList); free(timeout); /* * All Foundry tools commands return results that start with a * foundry error and a guest-OS-specific error. */ Str_Sprintf(resultBuffer, sizeof resultBuffer, "%"FMT64"d %d", err, sysError); Debug("<ToolsDaemonTcloSyncDriverFreeze\n"); return RPCIN_SETRETVALS(data, resultBuffer, TRUE); }
gboolean FoundryToolsDaemonGetToolsProperties(RpcInData *data) // IN { VixError err = VIX_OK; int additionalError = 0; static char resultBuffer[DEFAULT_RESULT_MSG_MAX_LENGTH]; char *serializedBuffer = NULL; size_t serializedBufferLength = 0; char *base64Buffer = NULL; size_t base64BufferLength = 0; Bool success; char *returnBuffer = NULL; GKeyFile *confDictRef; /* * Collect some values about the host. */ confDictRef = data->clientData; err = VixTools_GetToolsPropertiesImpl(confDictRef, &serializedBuffer, &serializedBufferLength); if (VIX_OK == err) { base64BufferLength = Base64_EncodedLength(serializedBuffer, serializedBufferLength) + 1; base64Buffer = Util_SafeMalloc(base64BufferLength); success = Base64_Encode(serializedBuffer, serializedBufferLength, base64Buffer, base64BufferLength, &base64BufferLength); if (!success) { base64Buffer[0] = 0; err = VIX_E_FAIL; goto abort; } base64Buffer[base64BufferLength] = 0; } abort: returnBuffer = base64Buffer; if (NULL == base64Buffer) { returnBuffer = ""; } if (VIX_OK != err) { additionalError = Err_Errno(); } /* * All VMXI tools commands return results that start with a VMXI error * and a guest-OS-specific error. */ Str_Sprintf(resultBuffer, sizeof(resultBuffer), "%"FMT64"d %d %s", err, additionalError, returnBuffer); RPCIN_SETRETVALS(data, resultBuffer, TRUE); free(serializedBuffer); free(base64Buffer); return TRUE; } // FoundryToolsDaemonGetToolsProperties
static gboolean ResolutionDisplayTopologyModesSetCB(RpcInData *data) { DisplayTopologyInfo *displays = NULL; unsigned int count; unsigned int i; unsigned int cmd; unsigned int screen; gboolean success = FALSE; const char *p; g_debug("%s: enter\n", __FUNCTION__); /* * The argument string will look something like: * <count> <screen> <cmd> [ , <w> <h> ] * count. * * e.g. * 3 0 1, 640 480 , 800 600 , 1024 768 */ if (sscanf(data->args, "%u %u %u", &count, &screen, &cmd) != 3) { g_debug("%s: invalid arguments\n", __FUNCTION__); return RPCIN_SETRETVALS(data, "Invalid arguments. Expected \"count\", \"screen\", and \"cmd\"", FALSE); } displays = malloc(sizeof *displays * count); if (!displays) { g_debug("%s: alloc failed\n", __FUNCTION__); RPCIN_SETRETVALS(data, "Failed to alloc buffer for display modes", FALSE); goto out; } for (p = data->args, i = 0; i < count; i++) { p = strchr(p, ','); if (!p) { g_debug("%s: expected comma separated display modes list\n", __FUNCTION__); RPCIN_SETRETVALS(data, "Expected comma separated display modes list", FALSE); goto out; } p++; /* Skip past the , */ if (sscanf(p, " %d %d ", &displays[i].width, &displays[i].height) != 2) { g_debug("%s: expected w, h in display modes entry\n", __FUNCTION__); RPCIN_SETRETVALS(data, "Expected w, h in display modes entry", FALSE); goto out; } } success = ResolutionSetTopologyModes(screen, cmd, count, displays); RPCIN_SETRETVALS(data, success ? "" : "ResolutionSetTopologyModes failed", success); out: free(displays); g_debug("%s: leave\n", __FUNCTION__); return success; }
static gboolean RpcChannelPing(RpcInData *data) { return RPCIN_SETRETVALS(data, "", TRUE); }