Last active
February 3, 2025 18:59
-
-
Save CodeCouturiers/137fc11f5425f98f287e82219ab5d1f2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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