[c-host] provide a platform agnostic method of passing args to app_main

This commit is contained in:
Geoffrey McRae 2019-05-09 19:30:09 +10:00
parent fc907b802f
commit 4617829d41
5 changed files with 63 additions and 30 deletions

View File

@ -1 +1 @@
a12-159-gba50fbdc3e+1 a12-160-gfc907b802f+1

View File

@ -21,7 +21,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <stdbool.h> #include <stdbool.h>
int app_main(); int app_main(int argc, char * argv[]);
void app_quit(); void app_quit();
// these must be implemented for each OS // these must be implemented for each OS

View File

@ -174,7 +174,7 @@ int main(int argc, char * argv[])
signal(SIGINT, sigHandler); signal(SIGINT, sigHandler);
int result = app_main(); int result = app_main(argc, argv);
os_shmemUnmap(); os_shmemUnmap();
close(app.shmFD); close(app.shmFD);

View File

@ -20,19 +20,34 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "platform.h" #include "platform.h"
#include "windows/platform.h" #include "windows/platform.h"
#include "windows/mousehook.h" #include "windows/mousehook.h"
#include <windows.h> #include <windows.h>
#include <setupapi.h> #include <setupapi.h>
#include <shellapi.h>
#include "interface/platform.h" #include "interface/platform.h"
#include "common/debug.h" #include "common/debug.h"
#include "windows/debug.h" #include "windows/debug.h"
#include "ivshmem/Public.h" #include "ivshmem/Public.h"
static char executable[MAX_PATH + 1]; struct AppState
static HANDLE shmemHandle = INVALID_HANDLE_VALUE; {
static bool shmemOwned = false; int argc;
static IVSHMEM_MMAP shmemMap = {0}; char * argv[];
static HWND messageWnd;
static char executable[MAX_PATH + 1];
static HANDLE shmemHandle;
static bool shmemOwned;
static IVSHMEM_MMAP shmemMap;
static HWND messageWnd;
};
static struct AppState state =
{
.shmemHandle = INVALID_HANDLE_VALUE,
.shmemOwned = false,
.shmemMap = {0}
};
struct osThreadHandle struct osThreadHandle
{ {
@ -72,21 +87,21 @@ LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
static int appThread(void * opaque) static int appThread(void * opaque)
{ {
int result = app_main(); int result = app_main(app.argc, app.argv);
SendMessage(messageWnd, WM_CLOSE, 0, 0); SendMessage(app.messageWnd, WM_CLOSE, 0, 0);
return result; return result;
} }
LRESULT sendAppMessage(UINT Msg, WPARAM wParam, LPARAM lParam) LRESULT sendAppMessage(UINT Msg, WPARAM wParam, LPARAM lParam)
{ {
return SendMessage(messageWnd, Msg, wParam, lParam); return SendMessage(app.messageWnd, Msg, wParam, lParam);
} }
static BOOL WINAPI CtrlHandler(DWORD dwCtrlType) static BOOL WINAPI CtrlHandler(DWORD dwCtrlType)
{ {
if (dwCtrlType == CTRL_C_EVENT) if (dwCtrlType == CTRL_C_EVENT)
{ {
SendMessage(messageWnd, WM_CLOSE, 0, 0); SendMessage(app.messageWnd, WM_CLOSE, 0, 0);
return TRUE; return TRUE;
} }
@ -100,7 +115,19 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
PSP_DEVICE_INTERFACE_DETAIL_DATA infData = NULL; PSP_DEVICE_INTERFACE_DETAIL_DATA infData = NULL;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData; SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
GetModuleFileName(NULL, executable, sizeof(executable)); // convert the command line to the standard argc and argv
LPWSTR * wargv = CommandLineToArgvA(GetCommandLineW(), &app.argc);
app.argv = malloc(sizeof(char *) * app.argc);
for(int i = 0; i < app.argc; ++i)
{
const size_t s = (wcslen(wargv[i])+1) * 2;
size_t unused;
app.argv[i] = malloc(s);
wcstombs_s(&unused, app.argv[i], s, wargv[i], _TRUNCATE);
}
LocalFree(wargv);
GetModuleFileName(NULL, app.executable, sizeof(app.executable));
// redirect stderr to a file // redirect stderr to a file
{ {
@ -154,8 +181,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
goto finish; goto finish;
} }
shmemHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0); app.shmemHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
if (shmemHandle == INVALID_HANDLE_VALUE) if (app.shmemHandle == INVALID_HANDLE_VALUE)
{ {
SetupDiDestroyDeviceInfoList(deviceInfoSet); SetupDiDestroyDeviceInfoList(deviceInfoSet);
free(infData); free(infData);
@ -182,8 +209,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
result = -1; result = -1;
goto finish_shmem; goto finish_shmem;
} }
messageWnd = CreateWindowEx(0, "DUMMY_CLASS", "DUMMY_NAME", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); app.messageWnd = CreateWindowEx(0, "DUMMY_CLASS", "DUMMY_NAME", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
// create the application thread
osThreadHandle * thread; osThreadHandle * thread;
if (!os_createThread("appThread", appThread, NULL, &thread)) if (!os_createThread("appThread", appThread, NULL, &thread))
{ {
@ -222,20 +250,25 @@ shutdown:
} }
finish_shmem: finish_shmem:
os_shmemUnmap(); os_shmemUnmap();
CloseHandle(shmemHandle); CloseHandle(app.shmemHandle);
finish: finish:
for(int i = 0; i < app.argc; ++i)
free(app.argv[i]);
free(app.argv);
return result; return result;
} }
const char * os_getExecutable() const char * os_getExecutable()
{ {
return executable; return app.executable;
} }
unsigned int os_shmemSize() unsigned int os_shmemSize()
{ {
IVSHMEM_SIZE size; IVSHMEM_SIZE size;
if (!DeviceIoControl(shmemHandle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &size, sizeof(IVSHMEM_SIZE), NULL, NULL)) if (!DeviceIoControl(app.shmemHandle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &size, sizeof(IVSHMEM_SIZE), NULL, NULL))
{ {
DEBUG_WINERROR("DeviceIoControl Failed", GetLastError()); DEBUG_WINERROR("DeviceIoControl Failed", GetLastError());
return 0; return 0;
@ -246,38 +279,38 @@ unsigned int os_shmemSize()
bool os_shmemMmap(void **ptr) bool os_shmemMmap(void **ptr)
{ {
if (shmemOwned) if (app.shmemOwned)
{ {
*ptr = shmemMap.ptr; *ptr = app.shmemMap.ptr;
return true; return true;
} }
memset(&shmemMap, 0, sizeof(IVSHMEM_MMAP)); memset(&app.shmemMap, 0, sizeof(IVSHMEM_MMAP));
if (!DeviceIoControl( if (!DeviceIoControl(
shmemHandle, app.shmemHandle,
IOCTL_IVSHMEM_REQUEST_MMAP, IOCTL_IVSHMEM_REQUEST_MMAP,
NULL, 0, NULL, 0,
&shmemMap, sizeof(IVSHMEM_MMAP), &app.shmemMap, sizeof(IVSHMEM_MMAP),
NULL, NULL)) NULL, NULL))
{ {
DEBUG_WINERROR("DeviceIoControl Failed", GetLastError()); DEBUG_WINERROR("DeviceIoControl Failed", GetLastError());
return false; return false;
} }
*ptr = shmemMap.ptr; *ptr = app.shmemMap.ptr;
shmemOwned = true; app.shmemOwned = true;
return true; return true;
} }
void os_shmemUnmap() void os_shmemUnmap()
{ {
if (!shmemOwned) if (!app.shmemOwned)
return; return;
if (!DeviceIoControl(shmemHandle, IOCTL_IVSHMEM_RELEASE_MMAP, NULL, 0, NULL, 0, NULL, NULL)) if (!DeviceIoControl(app.shmemHandle, IOCTL_IVSHMEM_RELEASE_MMAP, NULL, 0, NULL, 0, NULL, NULL))
DEBUG_WINERROR("DeviceIoControl failed", GetLastError()); DEBUG_WINERROR("DeviceIoControl failed", GetLastError());
else else
shmemOwned = false; app.shmemOwned = false;
} }
static DWORD WINAPI threadWrapper(LPVOID lpParameter) static DWORD WINAPI threadWrapper(LPVOID lpParameter)

View File

@ -256,7 +256,7 @@ static bool captureRestart()
return true; return true;
} }
int app_main() int app_main(int argc, char * argv[])
{ {
if (!installCrashHandler(os_getExecutable())) if (!installCrashHandler(os_getExecutable()))
DEBUG_WARN("Failed to install the crash handler"); DEBUG_WARN("Failed to install the crash handler");