mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-08-09 20:24:14 +00:00
[c-host] initial agnostic option api and parser
This commit is contained in:
@@ -74,6 +74,8 @@ CapturePointer;
|
||||
typedef struct CaptureInterface
|
||||
{
|
||||
const char * (*getName )();
|
||||
void (*initOptions )();
|
||||
|
||||
bool (*create )();
|
||||
bool (*init )(void * pointerShape, const unsigned int pointerSize);
|
||||
void (*stop )();
|
||||
|
@@ -22,6 +22,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include <stdbool.h>
|
||||
|
||||
int app_main(int argc, char * argv[]);
|
||||
bool app_init();
|
||||
void app_quit();
|
||||
|
||||
// these must be implemented for each OS
|
||||
|
@@ -19,6 +19,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#include "interface/platform.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/option.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <getopt.h>
|
||||
@@ -40,18 +41,8 @@ struct app
|
||||
void * shmMap;
|
||||
};
|
||||
|
||||
struct params
|
||||
{
|
||||
const char * shmDevice;
|
||||
};
|
||||
|
||||
static struct app app;
|
||||
|
||||
static struct params params =
|
||||
{
|
||||
.shmDevice = "uio0"
|
||||
};
|
||||
|
||||
struct osThreadHandle
|
||||
{
|
||||
const char * name;
|
||||
@@ -71,39 +62,47 @@ int main(int argc, char * argv[])
|
||||
{
|
||||
app.executable = argv[0];
|
||||
|
||||
static struct option longOptions[] =
|
||||
struct Option options[] =
|
||||
{
|
||||
{"shmDevice", required_argument, 0, 'f'},
|
||||
{0, 0, 0, 0}
|
||||
{
|
||||
.module = "os",
|
||||
.name = "shmDevice",
|
||||
.description = "The IVSHMEM device to use",
|
||||
.value = {
|
||||
.type = OPTION_TYPE_STRING,
|
||||
.v.x_string = "uio0"
|
||||
},
|
||||
.validator = NULL,
|
||||
.printHelp = NULL
|
||||
},
|
||||
{0}
|
||||
};
|
||||
|
||||
int optionIndex = 0;
|
||||
while(true)
|
||||
{
|
||||
int c = getopt_long(argc, argv, "f:", longOptions, &optionIndex);
|
||||
if (c == -1)
|
||||
break;
|
||||
option_register(options);
|
||||
|
||||
switch(c)
|
||||
{
|
||||
case 'f':
|
||||
params.shmDevice = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int result = app_main(argc, argv);
|
||||
os_shmemUnmap();
|
||||
close(app.shmFD);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool app_init()
|
||||
{
|
||||
const char * shmDevice = option_get_string("os", "shmDevice");
|
||||
|
||||
// check the deice name
|
||||
{
|
||||
char file[100] = "/sys/class/uio/";
|
||||
strncat(file, params.shmDevice, sizeof(file) - 1);
|
||||
strncat(file, "/name" , sizeof(file) - 1);
|
||||
strncat(file, shmDevice, sizeof(file) - 1);
|
||||
strncat(file, "/name" , sizeof(file) - 1);
|
||||
|
||||
int fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
DEBUG_ERROR("Failed to open: %s", file);
|
||||
DEBUG_ERROR("Did you remmeber to modprobe the kvmfr module?");
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
char name[32];
|
||||
@@ -112,7 +111,7 @@ int main(int argc, char * argv[])
|
||||
{
|
||||
DEBUG_ERROR("Failed to read: %s", file);
|
||||
close(fd);
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
name[len] = '\0';
|
||||
close(fd);
|
||||
@@ -126,21 +125,21 @@ int main(int argc, char * argv[])
|
||||
if (strcmp(name, "KVMFR") != 0)
|
||||
{
|
||||
DEBUG_ERROR("Device is not a KVMFR device \"%s\" reports as: %s", file, name);
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// get the device size
|
||||
{
|
||||
char file[100] = "/sys/class/uio/";
|
||||
strncat(file, params.shmDevice , sizeof(file) - 1);
|
||||
strncat(file, shmDevice , sizeof(file) - 1);
|
||||
strncat(file, "/maps/map0/size", sizeof(file) - 1);
|
||||
|
||||
int fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
DEBUG_ERROR("Failed to open: %s", file);
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
char size[32];
|
||||
@@ -149,7 +148,7 @@ int main(int argc, char * argv[])
|
||||
{
|
||||
DEBUG_ERROR("Failed to read: %s", file);
|
||||
close(fd);
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
size[len] = '\0';
|
||||
close(fd);
|
||||
@@ -160,13 +159,13 @@ int main(int argc, char * argv[])
|
||||
// open the device
|
||||
{
|
||||
char file[100] = "/dev/";
|
||||
strncat(file, params.shmDevice, sizeof(file) - 1);
|
||||
strncat(file, shmDevice, sizeof(file) - 1);
|
||||
app.shmFD = open(file, O_RDWR, (mode_t)0600);
|
||||
app.shmMap = MAP_FAILED;
|
||||
if (app.shmFD < 0)
|
||||
{
|
||||
DEBUG_ERROR("Failed to open: %s", file);
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_INFO("KVMFR Device : %s", file);
|
||||
@@ -174,11 +173,7 @@ int main(int argc, char * argv[])
|
||||
|
||||
signal(SIGINT, sigHandler);
|
||||
|
||||
int result = app_main(argc, argv);
|
||||
os_shmemUnmap();
|
||||
close(app.shmFD);
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char * os_getExecutable()
|
||||
@@ -198,7 +193,8 @@ bool os_shmemMmap(void **ptr)
|
||||
app.shmMap = mmap(0, app.shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, app.shmFD, 0);
|
||||
if (app.shmMap == MAP_FAILED)
|
||||
{
|
||||
DEBUG_ERROR("Failed to map the shared memory device: %s", params.shmDevice);
|
||||
const char * shmDevice = option_get_string("os", "shmDevice");
|
||||
DEBUG_ERROR("Failed to map the shared memory device: %s", shmDevice);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -110,11 +110,6 @@ static BOOL WINAPI CtrlHandler(DWORD dwCtrlType)
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
int result = 0;
|
||||
HDEVINFO deviceInfoSet;
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA infData = NULL;
|
||||
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
|
||||
|
||||
// convert the command line to the standard argc and argv
|
||||
LPWSTR * wargv = CommandLineToArgvW(GetCommandLineW(), &app.argc);
|
||||
app.argv = malloc(sizeof(char *) * app.argc);
|
||||
@@ -143,57 +138,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
// always flush stderr
|
||||
setbuf(stderr, NULL);
|
||||
|
||||
deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
|
||||
memset(&deviceInterfaceData, 0, sizeof(SP_DEVICE_INTERFACE_DATA));
|
||||
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||
|
||||
if (SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &GUID_DEVINTERFACE_IVSHMEM, 0, &deviceInterfaceData) == FALSE)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
if (error == ERROR_NO_MORE_ITEMS)
|
||||
{
|
||||
DEBUG_WINERROR("Unable to enumerate the device, is it attached?", error);
|
||||
result = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
DEBUG_WINERROR("SetupDiEnumDeviceInterfaces failed", error);
|
||||
result = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
DWORD reqSize = 0;
|
||||
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &reqSize, NULL);
|
||||
if (!reqSize)
|
||||
{
|
||||
DEBUG_WINERROR("SetupDiGetDeviceInterfaceDetail", GetLastError());
|
||||
result = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
infData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)calloc(reqSize, 1);
|
||||
infData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, infData, reqSize, NULL, NULL))
|
||||
{
|
||||
free(infData);
|
||||
DEBUG_WINERROR("SetupDiGetDeviceInterfaceDetail", GetLastError());
|
||||
result = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
app.shmemHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
|
||||
if (app.shmemHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoSet);
|
||||
free(infData);
|
||||
DEBUG_WINERROR("CreateFile returned INVALID_HANDLE_VALUE", GetLastError());
|
||||
result = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
free(infData);
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoSet);
|
||||
|
||||
// setup a handler for ctrl+c
|
||||
SetConsoleCtrlHandler(CtrlHandler, TRUE);
|
||||
|
||||
@@ -260,6 +204,62 @@ finish:
|
||||
return result;
|
||||
}
|
||||
|
||||
bool app_init()
|
||||
{
|
||||
int result = 0;
|
||||
HDEVINFO deviceInfoSet;
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA infData = NULL;
|
||||
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
|
||||
|
||||
deviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
|
||||
memset(&deviceInterfaceData, 0, sizeof(SP_DEVICE_INTERFACE_DATA));
|
||||
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||
|
||||
if (SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &GUID_DEVINTERFACE_IVSHMEM, 0, &deviceInterfaceData) == FALSE)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
if (error == ERROR_NO_MORE_ITEMS)
|
||||
{
|
||||
DEBUG_WINERROR("Unable to enumerate the device, is it attached?", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_WINERROR("SetupDiEnumDeviceInterfaces failed", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD reqSize = 0;
|
||||
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &reqSize, NULL);
|
||||
if (!reqSize)
|
||||
{
|
||||
DEBUG_WINERROR("SetupDiGetDeviceInterfaceDetail", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
infData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)calloc(reqSize, 1);
|
||||
infData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, infData, reqSize, NULL, NULL))
|
||||
{
|
||||
free(infData);
|
||||
DEBUG_WINERROR("SetupDiGetDeviceInterfaceDetail", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
app.shmemHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
|
||||
if (app.shmemHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoSet);
|
||||
free(infData);
|
||||
DEBUG_WINERROR("CreateFile returned INVALID_HANDLE_VALUE", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
free(infData);
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoSet);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char * os_getExecutable()
|
||||
{
|
||||
return app.executable;
|
||||
|
@@ -21,6 +21,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "interface/capture.h"
|
||||
#include "dynamic/capture.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/option.h"
|
||||
#include "common/locking.h"
|
||||
#include "common/KVMFR.h"
|
||||
#include "common/crash.h"
|
||||
@@ -256,11 +257,29 @@ static bool captureRestart()
|
||||
return true;
|
||||
}
|
||||
|
||||
// this is called from the platform specific startup routine
|
||||
int app_main(int argc, char * argv[])
|
||||
{
|
||||
if (!installCrashHandler(os_getExecutable()))
|
||||
DEBUG_WARN("Failed to install the crash handler");
|
||||
|
||||
// register capture interface options
|
||||
for(int i = 0; CaptureInterfaces[i]; ++i)
|
||||
if (CaptureInterfaces[i]->initOptions)
|
||||
CaptureInterfaces[i]->initOptions();
|
||||
|
||||
// parse the command line arguments
|
||||
if (!option_parse(argc, argv))
|
||||
{
|
||||
option_free();
|
||||
DEBUG_ERROR("Failure to parse the command line");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// perform platform specific initialization
|
||||
if (!app_init())
|
||||
return -1;
|
||||
|
||||
unsigned int shmemSize = os_shmemSize();
|
||||
uint8_t * shmemMap = NULL;
|
||||
int exitcode = 0;
|
||||
|
Reference in New Issue
Block a user