diff --git a/common/include/common/ivshmem.h b/common/include/common/ivshmem.h index 73052da4..da6834da 100644 --- a/common/include/common/ivshmem.h +++ b/common/include/common/ivshmem.h @@ -31,6 +31,8 @@ struct IVSHMEM }; void ivshmemOptionsInit(); +bool ivshmemInit(struct IVSHMEM * dev); bool ivshmemOpen(struct IVSHMEM * dev); bool ivshmemOpenDev(struct IVSHMEM * dev, const char * shmDev); -void ivshmemClose(struct IVSHMEM * dev); \ No newline at end of file +void ivshmemClose(struct IVSHMEM * dev); +void ivshmemFree(struct IVSHMEM * dev); diff --git a/common/src/platform/windows/ivshmem.c b/common/src/platform/windows/ivshmem.c index f993a015..a2c94a75 100644 --- a/common/src/platform/windows/ivshmem.c +++ b/common/src/platform/windows/ivshmem.c @@ -49,66 +49,80 @@ void ivshmemOptionsInit() option_register(options); } -bool ivshmemOpen(struct IVSHMEM * dev) +bool ivshmemInit(struct IVSHMEM * dev) { - assert(dev); + assert(dev && !dev->opaque); - HANDLE devHandle; + HANDLE handle; + HDEVINFO devInfoSet; + PSP_DEVICE_INTERFACE_DETAIL_DATA infData = NULL; + SP_DEVICE_INTERFACE_DATA devInterfaceData = {0}; + devInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE); + devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + + const int shmDevice = option_get_int("os", "shmDevice"); + if (SetupDiEnumDeviceInterfaces(devInfoSet, NULL, &GUID_DEVINTERFACE_IVSHMEM, shmDevice, &devInterfaceData) == FALSE) { - HDEVINFO devInfoSet; - PSP_DEVICE_INTERFACE_DETAIL_DATA infData = NULL; - SP_DEVICE_INTERFACE_DATA devInterfaceData = {0}; - - devInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE); - devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - - const int shmDevice = option_get_int("os", "shmDevice"); - if (SetupDiEnumDeviceInterfaces(devInfoSet, NULL, &GUID_DEVINTERFACE_IVSHMEM, shmDevice, &devInterfaceData) == FALSE) + DWORD error = GetLastError(); + if (error == ERROR_NO_MORE_ITEMS) { - 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); + DEBUG_WINERROR("Unable to enumerate the device, is it attached?", error); return false; } - DWORD reqSize = 0; - SetupDiGetDeviceInterfaceDetail(devInfoSet, &devInterfaceData, 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(devInfoSet, &devInterfaceData, infData, reqSize, NULL, NULL)) - { - free(infData); - DEBUG_WINERROR("SetupDiGetDeviceInterfaceDetail", GetLastError()); - return false; - } - - devHandle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0); - if (devHandle == INVALID_HANDLE_VALUE) - { - SetupDiDestroyDeviceInfoList(devInfoSet); - free(infData); - DEBUG_WINERROR("CreateFile returned INVALID_HANDLE_VALUE", GetLastError()); - return false; - } - - free(infData); - SetupDiDestroyDeviceInfoList(devInfoSet); + DEBUG_WINERROR("SetupDiEnumDeviceInterfaces failed", error); + return false; } + DWORD reqSize = 0; + SetupDiGetDeviceInterfaceDetail(devInfoSet, &devInterfaceData, 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(devInfoSet, &devInterfaceData, infData, reqSize, NULL, NULL)) + { + free(infData); + DEBUG_WINERROR("SetupDiGetDeviceInterfaceDetail", GetLastError()); + return false; + } + + handle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0); + if (handle == INVALID_HANDLE_VALUE) + { + SetupDiDestroyDeviceInfoList(devInfoSet); + free(infData); + DEBUG_WINERROR("CreateFile returned INVALID_HANDLE_VALUE", GetLastError()); + return false; + } + + free(infData); + SetupDiDestroyDeviceInfoList(devInfoSet); + + struct IVSHMEMInfo * info = + (struct IVSHMEMInfo *)malloc(sizeof(struct IVSHMEMInfo)); + + info->handle = handle; + dev->opaque = info; + dev->size = 0; + dev->mem = NULL; + + return true; +} + +bool ivshmemOpen(struct IVSHMEM * dev) +{ + assert(dev && dev->opaque && !dev->mem); + + struct IVSHMEMInfo * info = (struct IVSHMEMInfo *)dev->opaque; + IVSHMEM_SIZE size; - if (!DeviceIoControl(devHandle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &size, sizeof(IVSHMEM_SIZE), NULL, NULL)) + if (!DeviceIoControl(info->handle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &size, sizeof(IVSHMEM_SIZE), NULL, NULL)) { DEBUG_WINERROR("DeviceIoControl Failed", GetLastError()); return 0; @@ -117,7 +131,7 @@ bool ivshmemOpen(struct IVSHMEM * dev) IVSHMEM_MMAP_CONFIG config = { .cacheMode = IVSHMEM_CACHE_WRITECOMBINED }; IVSHMEM_MMAP map = { 0 }; if (!DeviceIoControl( - devHandle, + info->handle, IOCTL_IVSHMEM_REQUEST_MMAP, &config, sizeof(IVSHMEM_MMAP_CONFIG), &map , sizeof(IVSHMEM_MMAP), @@ -127,27 +141,30 @@ bool ivshmemOpen(struct IVSHMEM * dev) return false; } - struct IVSHMEMInfo * info = - (struct IVSHMEMInfo *)malloc(sizeof(struct IVSHMEMInfo)); - - info->handle = devHandle; - - dev->opaque = info; dev->size = (unsigned int)size; dev->mem = map.ptr; - return true; } void ivshmemClose(struct IVSHMEM * dev) { - assert(dev); + assert(dev && dev->opaque && dev->mem); - struct IVSHMEMInfo * info = - (struct IVSHMEMInfo *)dev->opaque; + struct IVSHMEMInfo * info = (struct IVSHMEMInfo *)dev->opaque; if (!DeviceIoControl(info->handle, IOCTL_IVSHMEM_RELEASE_MMAP, NULL, 0, NULL, 0, NULL, NULL)) DEBUG_WINERROR("DeviceIoControl failed", GetLastError()); + dev->size = 0; + dev->mem = NULL; +} + +void ivshmemFree(struct IVSHMEM * dev) +{ + assert(dev && dev->opaque && !dev->mem); + + struct IVSHMEMInfo * info = (struct IVSHMEMInfo *)dev->opaque; + free(info); -} \ No newline at end of file + dev->opaque = NULL; +} diff --git a/host/platform/Windows/src/service.c b/host/platform/Windows/src/service.c index f5239bea..82b7b12c 100644 --- a/host/platform/Windows/src/service.c +++ b/host/platform/Windows/src/service.c @@ -20,6 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #define INSTANCE_MUTEX_NAME "Global\\6f1a5eec-af3f-4a65-99dd-ebe0e4ecea55" #include "interface/platform.h" +#include "common/ivshmem.h" #include #include @@ -598,6 +599,15 @@ VOID WINAPI SvcMain(DWORD dwArgc, LPTSTR *lpszArgv) setupLogging(); + /* check if the ivshmem device exists */ + struct IVSHMEM shmDev = { 0 }; + if (!ivshmemInit(&shmDev)) + { + doLog("Unable to find the IVSHMEM device, terminating the service\n"); + goto shutdown; + } + ivshmemFree(&shmDev); + ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); while(1) { @@ -645,6 +655,7 @@ VOID WINAPI SvcMain(DWORD dwArgc, LPTSTR *lpszArgv) } } +shutdown: ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0); CloseHandle(ghSvcStopEvent); finishLogging(); diff --git a/host/src/app.c b/host/src/app.c index 7d7eaa10..b29f2011 100644 --- a/host/src/app.c +++ b/host/src/app.c @@ -447,7 +447,13 @@ int app_main(int argc, char * argv[]) DEBUG_INFO("Looking Glass Host (%s)", BUILD_VERSION); - struct IVSHMEM shmDev; + struct IVSHMEM shmDev = { 0 }; + if (!ivshmemInit(&shmDev)) + { + DEBUG_ERROR("Failed to find the IVSHMEM device"); + return -1; + } + if (!ivshmemOpen(&shmDev)) { DEBUG_ERROR("Failed to open the IVSHMEM device"); @@ -638,6 +644,7 @@ fail: lgmpHostFree(&app.lgmp); ivshmemClose(&shmDev); + ivshmemFree(&shmDev); return exitcode; }