Skip to content

Instantly share code, notes, and snippets.

@CodeCouturiers
Last active February 3, 2025 18:59
Show Gist options
  • Save CodeCouturiers/137fc11f5425f98f287e82219ab5d1f2 to your computer and use it in GitHub Desktop.
Save CodeCouturiers/137fc11f5425f98f287e82219ab5d1f2 to your computer and use it in GitHub Desktop.
/*
* This demonstrates how to interact with a VMware virtual machine using VIX API.
* It performs various guest operations on a Linux VM including:
* - Getting system information using 'uname'
* - Getting current directory using 'pwd'
* - Handling file operations and command execution
*/
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include "vix.h"
/*
* Guest OS credentials
*/
#define GUEST_USERNAME "user"
#define GUEST_PASSWORD "user"
/*
* Connection settings for VMware Workstation
*/
#define CONNTYPE VIX_SERVICEPROVIDER_VMWARE_WORKSTATION
#define HOSTNAME ""
#define HOSTPORT 0
#define USERNAME ""
#define PASSWORD ""
#define VMPOWEROPTIONS VIX_VMPOWEROP_LAUNCH_GUI
#define TOOLS_TIMEOUT 60
#define VMX_PATH "C:\\Users\\user\\Documents\\Virtual Machines\\Ubuntu 64-bit Server\\Ubuntu 64-bit Server.vmx"
/*
* Error handling function
*/
static void handleVixError(VixError err, const char* operation) {
if (VIX_FAILED(err)) {
const char* errorText = Vix_GetErrorText(err, NULL);
fprintf(stderr, "%s failed: %s\n", operation, errorText);
Vix_FreeBuffer((void*)errorText);
}
}
/*
* Function to execute command and get output via temporary file
*/
static char* runCommandAndGetOutput(VixHandle vmHandle, const char* command, const char* args) {
VixError err;
VixHandle jobHandle;
char* result = NULL;
const char* tempGuestFile = "/tmp/command_output.txt";
const char* tempHostFile = "command_output.txt";
FILE* file = NULL;
errno_t fileErr;
// Execute command with output redirection
jobHandle = VixVM_RunProgramInGuest(vmHandle,
command,
args,
0,
VIX_INVALID_HANDLE,
NULL,
NULL);
err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE);
Vix_ReleaseHandle(jobHandle);
if (VIX_FAILED(err)) {
handleVixError(err, "Running command");
goto cleanup;
}
// Copy the file from guest to host
jobHandle = VixVM_CopyFileFromGuestToHost(vmHandle,
tempGuestFile,
tempHostFile,
0,
VIX_INVALID_HANDLE,
NULL,
NULL);
err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE);
Vix_ReleaseHandle(jobHandle);
if (VIX_FAILED(err)) {
handleVixError(err, "Copying file from guest");
goto cleanup;
}
// Read the local file using secure file operations
fileErr = fopen_s(&file, tempHostFile, "r");
if (fileErr == 0 && file != NULL) {
// Get file size
if (fseek(file, 0, SEEK_END) == 0) {
long fileSize = ftell(file);
if (fileSize != -1 && fseek(file, 0, SEEK_SET) == 0) {
// Allocate memory for the content
result = (char*)malloc(fileSize + 1);
if (result) {
size_t bytesRead = fread(result, 1, fileSize, file);
result[bytesRead] = '\0';
}
}
}
fclose(file);
remove(tempHostFile); // Delete the temporary host file
}
cleanup:
// Cleanup temporary file in guest
jobHandle = VixVM_RunProgramInGuest(vmHandle,
"rm",
tempGuestFile,
0,
VIX_INVALID_HANDLE,
NULL,
NULL);
Vix_ReleaseHandle(jobHandle);
return result;
}
/*
* Helper function to execute sudo commands
*/
static char* executeSudoCommand(VixHandle vmHandle, const char* command) {
char commandBuffer[1024];
char checkBuffer[1024];
// Выполняем команду и сохраняем код возврата
snprintf(checkBuffer, sizeof(checkBuffer),
"-c 'echo %s | /usr/bin/sudo -S %s 2>&1 | tee /tmp/command_output.txt; echo $? > /tmp/exit_code.txt'",
GUEST_PASSWORD,
command);
char* output = runCommandAndGetOutput(vmHandle, "/bin/bash", checkBuffer);
// Проверяем код возврата
char* exitCode = runCommandAndGetOutput(vmHandle, "/bin/cat", "/tmp/exit_code.txt");
if (exitCode) {
int status = atoi(exitCode);
free(exitCode);
if (status != 0) {
printf("Command failed with status: %d\n", status);
if (output) {
free(output);
output = NULL;
}
}
}
return output;
}
/*
* Function to update system and log the process
*/
static bool updateSystem(VixHandle vmHandle) {
VixError err;
VixHandle jobHandle;
char* result = NULL;
bool success = true;
printf("Starting system update process...\n");
// Update package lists
result = executeSudoCommand(vmHandle, "DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get update -y");
if (result) {
printf("Package lists update output:\n%s\n", result);
free(result);
} else {
printf("Failed to update package lists\n");
success = false;
}
// Upgrade packages
if (success) {
result = executeSudoCommand(vmHandle, "DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get upgrade -y");
if (result) {
printf("System upgrade output:\n%s\n", result);
free(result);
} else {
printf("Failed to upgrade system\n");
success = false;
}
}
// Clean up
if (success) {
result = executeSudoCommand(vmHandle, "DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get clean");
if (result) {
printf("Cleanup output:\n%s\n", result);
free(result);
}
}
// Print current system status
result = executeSudoCommand(vmHandle, "DEBIAN_FRONTEND=noninteractive /usr/bin/apt-get update -qq");
if (result) {
printf("Final system status:\n%s\n", result);
free(result);
}
return success;
}
/*
* Function to check system prerequisites
*/
static bool checkPrerequisites(VixHandle vmHandle) {
char* result = NULL;
bool success = true;
printf("Checking system prerequisites...\n");
// Check sudo access
result = runCommandAndGetOutput(vmHandle,
"/bin/bash",
"-c '/usr/bin/sudo -n true | tee /tmp/command_output.txt 2>&1'");
if (result) {
printf("Sudo access check: %s\n", result);
free(result);
}
// Check apt-get exists
result = runCommandAndGetOutput(vmHandle,
"/bin/bash",
"-c '/bin/ls -l /usr/bin/apt-get | tee /tmp/command_output.txt'");
if (result) {
printf("apt-get check: %s\n", result);
free(result);
}
// Check network connectivity
result = runCommandAndGetOutput(vmHandle,
"/bin/bash",
"-c '/bin/ping -c 1 8.8.8.8 | tee /tmp/command_output.txt'");
if (result) {
printf("Network check: %s\n", result);
free(result);
}
return success;
}
int main(int argc, char** argv) {
VixError err;
VixHandle hostHandle = VIX_INVALID_HANDLE;
VixHandle jobHandle = VIX_INVALID_HANDLE;
VixHandle vmHandle = VIX_INVALID_HANDLE;
char* sysInfo = NULL;
char* currentDir = NULL;
// Connect to VMware
jobHandle = VixHost_Connect(VIX_API_VERSION,
CONNTYPE,
HOSTNAME,
HOSTPORT,
USERNAME,
PASSWORD,
0,
VIX_INVALID_HANDLE,
NULL,
NULL);
err = VixJob_Wait(jobHandle,
VIX_PROPERTY_JOB_RESULT_HANDLE,
&hostHandle,
VIX_PROPERTY_NONE);
Vix_ReleaseHandle(jobHandle);
if (VIX_FAILED(err)) {
handleVixError(err, "Connecting to host");
goto abort;
}
printf("Connected to VMware host\n");
// Open VM
jobHandle = VixHost_OpenVM(hostHandle,
VMX_PATH,
VIX_VMOPEN_NORMAL,
VIX_INVALID_HANDLE,
NULL,
NULL);
err = VixJob_Wait(jobHandle,
VIX_PROPERTY_JOB_RESULT_HANDLE,
&vmHandle,
VIX_PROPERTY_NONE);
Vix_ReleaseHandle(jobHandle);
if (VIX_FAILED(err)) {
handleVixError(err, "Opening VM");
goto abort;
}
printf("Opened VM: %s\n", VMX_PATH);
// Wait for Tools
jobHandle = VixVM_WaitForToolsInGuest(vmHandle,
TOOLS_TIMEOUT,
NULL,
NULL);
err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE);
Vix_ReleaseHandle(jobHandle);
if (VIX_FAILED(err)) {
handleVixError(err, "Waiting for VMware Tools");
goto abort;
}
printf("VMware Tools are running\n");
// Login to guest
jobHandle = VixVM_LoginInGuest(vmHandle,
GUEST_USERNAME,
GUEST_PASSWORD,
0,
NULL,
NULL);
err = VixJob_Wait(jobHandle, VIX_PROPERTY_NONE);
Vix_ReleaseHandle(jobHandle);
if (VIX_FAILED(err)) {
handleVixError(err, "Login to guest");
goto abort;
}
printf("Logged in to guest\n");
// Check prerequisites first
if (checkPrerequisites(vmHandle)) {
// Update system
if (updateSystem(vmHandle)) {
printf("System update completed successfully\n");
} else {
printf("System update failed\n");
}
} else {
printf("Prerequisites check failed\n");
}
// Get system information
sysInfo = runCommandAndGetOutput(vmHandle,
"/bin/uname",
"-a > /tmp/command_output.txt");
if (sysInfo) {
printf("System information: %s", sysInfo);
} else {
printf("Failed to get system information\n");
}
// Get current directory
currentDir = runCommandAndGetOutput(vmHandle,
"/usr/bin/pwd",
"> /tmp/command_output.txt");
if (currentDir) {
printf("Current directory: %s", currentDir);
} else {
printf("Failed to get current directory\n");
}
abort:
if (vmHandle != VIX_INVALID_HANDLE) {
Vix_ReleaseHandle(vmHandle);
}
if (hostHandle != VIX_INVALID_HANDLE) {
VixHost_Disconnect(hostHandle);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment