mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-12 17:38:19 +00:00
[host] implemented initial IVSHMEM interface class
This commit is contained in:
parent
f24cf74238
commit
215d2c7a4b
192
host/ivshmem.cpp
Normal file
192
host/ivshmem.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
#include "ivshmem.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <SetupAPI.h>
|
||||
#include <vendor\kvm-guest-drivers-windows\ivshmem\Public.h>
|
||||
#include <common\debug.h>
|
||||
|
||||
IVSHMEM * IVSHMEM::m_instance = NULL;
|
||||
|
||||
IVSHMEM::IVSHMEM() :
|
||||
m_initialized(false),
|
||||
m_handle(INVALID_HANDLE_VALUE),
|
||||
m_gotSize(false),
|
||||
m_gotPeerID(false),
|
||||
m_gotMemory(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IVSHMEM::~IVSHMEM()
|
||||
{
|
||||
DeInitialize();
|
||||
}
|
||||
|
||||
bool IVSHMEM::Initialize()
|
||||
{
|
||||
if (m_initialized)
|
||||
DeInitialize();
|
||||
|
||||
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);
|
||||
ZeroMemory(&deviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA));
|
||||
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &GUID_DEVINTERFACE_IVSHMEM, 0, &deviceInterfaceData) == FALSE)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
if (error == ERROR_NO_MORE_ITEMS)
|
||||
{
|
||||
DEBUG_ERROR("Unable to enumerate the device, is it attached?");
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG_ERROR("SetupDiEnumDeviceInterfaces failed");
|
||||
break;
|
||||
}
|
||||
|
||||
DWORD reqSize = 0;
|
||||
SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &reqSize, NULL);
|
||||
if (!reqSize)
|
||||
{
|
||||
DEBUG_ERROR("SetupDiGetDeviceInterfaceDetail");
|
||||
break;
|
||||
}
|
||||
|
||||
infData = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(malloc(reqSize));
|
||||
ZeroMemory(infData, reqSize);
|
||||
infData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, infData, reqSize, NULL, NULL))
|
||||
{
|
||||
DEBUG_ERROR("SetupDiGetDeviceInterfaceDetail");
|
||||
break;
|
||||
}
|
||||
|
||||
m_handle = CreateFile(infData->DevicePath, 0, 0, NULL, OPEN_EXISTING, 0, 0);
|
||||
if (m_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DEBUG_ERROR("CreateFile returned INVALID_HANDLE_VALUE");
|
||||
break;
|
||||
}
|
||||
|
||||
m_initialized = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (infData)
|
||||
free(infData);
|
||||
|
||||
SetupDiDestroyDeviceInfoList(deviceInfoSet);
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
void IVSHMEM::DeInitialize()
|
||||
{
|
||||
if (!m_initialized)
|
||||
return;
|
||||
|
||||
if (m_gotMemory)
|
||||
{
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_RELEASE_MMAP, NULL, 0, NULL, 0, NULL, NULL))
|
||||
DEBUG_ERROR("DeviceIoControl failed: %d", GetLastError());
|
||||
m_memory = NULL;
|
||||
}
|
||||
|
||||
if (m_handle != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(m_handle);
|
||||
|
||||
m_initialized = false;
|
||||
m_handle = INVALID_HANDLE_VALUE;
|
||||
m_gotSize = false;
|
||||
m_gotPeerID = false;
|
||||
m_gotVectors = false;
|
||||
m_gotMemory = false;
|
||||
}
|
||||
|
||||
bool IVSHMEM::IsInitialized()
|
||||
{
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
UINT64 IVSHMEM::GetSize()
|
||||
{
|
||||
if (!m_initialized)
|
||||
return 0;
|
||||
|
||||
if (m_gotSize)
|
||||
return m_size;
|
||||
|
||||
IVSHMEM_SIZE size;
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &size, sizeof(IVSHMEM_SIZE), NULL, NULL))
|
||||
{
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_gotSize = true;
|
||||
m_size = static_cast<UINT64>(size);
|
||||
return m_size;
|
||||
}
|
||||
|
||||
UINT16 IVSHMEM::GetPeerID()
|
||||
{
|
||||
if (!m_initialized)
|
||||
return 0;
|
||||
|
||||
if (m_gotPeerID)
|
||||
return m_peerID;
|
||||
|
||||
IVSHMEM_PEERID peerID;
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, NULL, 0, &peerID, sizeof(IVSHMEM_PEERID), NULL, NULL))
|
||||
{
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", GetLastError());
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_gotPeerID = true;
|
||||
m_peerID = static_cast<UINT16>(peerID);
|
||||
return m_peerID;
|
||||
}
|
||||
|
||||
UINT16 IVSHMEM::GetVectors()
|
||||
{
|
||||
if (!m_initialized)
|
||||
return 0;
|
||||
|
||||
if (!m_gotVectors)
|
||||
return 0;
|
||||
|
||||
return m_vectors;
|
||||
}
|
||||
|
||||
void * IVSHMEM::GetMemory()
|
||||
{
|
||||
if (!m_initialized)
|
||||
return NULL;
|
||||
|
||||
if (m_gotMemory)
|
||||
return m_memory;
|
||||
|
||||
IVSHMEM_MMAP map;
|
||||
ZeroMemory(&map, sizeof(IVSHMEM_MMAP));
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_MMAP, NULL, 0, &map, sizeof(IVSHMEM_MMAP), NULL, NULL))
|
||||
{
|
||||
DEBUG_ERROR("DeviceIoControl Failed: %d", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m_gotSize = true;
|
||||
m_gotPeerID = true;
|
||||
m_gotMemory = true;
|
||||
m_gotVectors = true;
|
||||
m_size = static_cast<UINT64>(map.size );
|
||||
m_peerID = static_cast<UINT16>(map.peerID );
|
||||
m_vectors = static_cast<UINT16>(map.vectors);
|
||||
|
||||
return m_memory;
|
||||
}
|
42
host/ivshmem.h
Normal file
42
host/ivshmem.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#define W32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
class IVSHMEM
|
||||
{
|
||||
public:
|
||||
static IVSHMEM * Get()
|
||||
{
|
||||
if (!m_instance)
|
||||
m_instance = new IVSHMEM();
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
bool Initialize();
|
||||
void DeInitialize();
|
||||
bool IsInitialized();
|
||||
|
||||
UINT64 GetSize();
|
||||
UINT16 GetPeerID();
|
||||
UINT16 GetVectors();
|
||||
void * GetMemory();
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
private:
|
||||
static IVSHMEM * m_instance;
|
||||
|
||||
IVSHMEM();
|
||||
~IVSHMEM();
|
||||
|
||||
bool m_initialized;
|
||||
HANDLE m_handle;
|
||||
|
||||
UINT64 m_size ; bool m_gotSize ;
|
||||
UINT16 m_peerID ; bool m_gotPeerID;
|
||||
void * m_memory ; bool m_gotMemory;
|
||||
UINT16 m_vectors; bool m_gotVectors;
|
||||
};
|
@ -69,17 +69,19 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\common</IncludePath>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\common</IncludePath>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@ -87,12 +89,13 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);DEBUG</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@ -101,12 +104,13 @@
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_DEBUG;_WINDOWS;%(PreprocessorDefinitions);DEBUG</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
@ -125,6 +129,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@ -143,10 +148,15 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="ivshmem.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ivshmem.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
@ -15,8 +15,16 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c">
|
||||
<ClCompile Include="ivshmem.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ivshmem.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,12 +1,11 @@
|
||||
#include <Windows.h>
|
||||
#include <tchar.h>
|
||||
#include <common\debug.h>
|
||||
|
||||
#include "ivshmem.h"
|
||||
|
||||
#define SERVICE_NAME "kvm-ivshmem-host"
|
||||
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
#define DEBUG_HERE(...) SERVICE_NAME " " __FUNCTION__ ":" STR(__LINE__) " " ## __VA_ARGS__
|
||||
|
||||
//=============================================================================
|
||||
|
||||
struct App
|
||||
@ -18,9 +17,9 @@ struct App
|
||||
|
||||
struct App app =
|
||||
{
|
||||
.serviceStatus = {0},
|
||||
.statusHandle = NULL,
|
||||
.serviceStopEvent = INVALID_HANDLE_VALUE
|
||||
{0},
|
||||
NULL,
|
||||
INVALID_HANDLE_VALUE
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
@ -35,7 +34,7 @@ int main(int argc, TCHAR *argv[])
|
||||
{
|
||||
SERVICE_TABLE_ENTRY ServiceTable[] =
|
||||
{
|
||||
{SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
|
||||
{_T(SERVICE_NAME), (LPSERVICE_MAIN_FUNCTION)ServiceMain},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@ -59,7 +58,7 @@ int main(int argc, TCHAR *argv[])
|
||||
|
||||
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
|
||||
{
|
||||
app.statusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
|
||||
app.statusHandle = RegisterServiceCtrlHandler(_T(SERVICE_NAME), ServiceCtrlHandler);
|
||||
if (!app.statusHandle)
|
||||
return;
|
||||
|
||||
@ -73,7 +72,7 @@ VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
|
||||
|
||||
if (SetServiceStatus(app.statusHandle, &app.serviceStatus) == FALSE)
|
||||
{
|
||||
OutputDebugString(DEBUG_HERE("SetServiceStatus failed"));
|
||||
DEBUG_ERROR("SetServiceStatus failed");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -86,7 +85,7 @@ VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
|
||||
app.serviceStatus.dwCheckPoint = 1;
|
||||
if (SetServiceStatus(app.statusHandle, &app.serviceStatus) == FALSE)
|
||||
{
|
||||
OutputDebugString(DEBUG_HERE("SetServiceStatus failed"));
|
||||
DEBUG_ERROR("SetServiceStatus failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -97,7 +96,7 @@ VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
|
||||
app.serviceStatus.dwCheckPoint = 0;
|
||||
if (SetServiceStatus(app.statusHandle, &app.serviceStatus) == FALSE)
|
||||
{
|
||||
OutputDebugString(DEBUG_HERE("SetServiceStatus failed"));
|
||||
DEBUG_ERROR("SetServiceStatus failed");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -112,7 +111,7 @@ VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
|
||||
|
||||
if (SetServiceStatus(app.statusHandle, &app.serviceStatus) == FALSE)
|
||||
{
|
||||
OutputDebugString(DEBUG_HERE("SetServiceStatus failed"));
|
||||
DEBUG_ERROR("SetServiceStatus failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -133,7 +132,7 @@ VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
|
||||
app.serviceStatus.dwCheckPoint = 4;
|
||||
|
||||
if (SetServiceStatus(app.statusHandle, &app.serviceStatus) == FALSE)
|
||||
OutputDebugString(DEBUG_HERE("SetServiceStatus failed"));
|
||||
DEBUG_ERROR("SetServiceStatus failed");
|
||||
|
||||
SetEvent(app.serviceStopEvent);
|
||||
break;
|
||||
@ -147,10 +146,19 @@ VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
|
||||
|
||||
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
|
||||
{
|
||||
IVSHMEM * ivshmem = IVSHMEM::Get();
|
||||
if (!ivshmem->Initialize())
|
||||
{
|
||||
DEBUG_ERROR("Failed to initialize IVSHMEM");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
while (WaitForSingleObject(app.serviceStopEvent, 0) != WAIT_OBJECT_0)
|
||||
{
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
ivshmem->DeInitialize();
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user