mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-22 05:42:58 +00:00
[idd] implemented core shared memory functionallity and LGMP setup
This commit is contained in:
parent
77ddcfe489
commit
3c85957b99
15 changed files with 608 additions and 37 deletions
|
@ -38,6 +38,13 @@
|
|||
#define LGMP_Q_FRAME_LEN 2
|
||||
#define LGMP_Q_POINTER_LEN 20
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// don't warn on zero length arrays
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200)
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
CURSOR_FLAG_POSITION = 0x1,
|
||||
|
@ -165,4 +172,8 @@ typedef struct KVMFRSetCursorPos
|
|||
}
|
||||
KVMFRSetCursorPos;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <algorithm>
|
||||
#include <winioctl.h>
|
||||
|
||||
#include "Debug.h"
|
||||
#include "ivshmem/ivshmem.h"
|
||||
|
||||
CIVSHMEM::CIVSHMEM()
|
||||
|
@ -81,7 +82,7 @@ bool CIVSHMEM::Init()
|
|||
{
|
||||
DWORD bus = it->busAddr >> 32;
|
||||
DWORD addr = it->busAddr & 0xFFFFFFFF;
|
||||
printf("IVSHMEM %u%c on bus 0x%lx, device 0x%lx, function 0x%lx\n",
|
||||
DBGPRINT("IVSHMEM %u%c on bus 0x%lx, device 0x%lx, function 0x%lx\n",
|
||||
i, i == shmDevice ? '*' : ' ', bus, addr >> 16, addr & 0xFFFF);
|
||||
|
||||
if (i == shmDevice)
|
||||
|
@ -132,7 +133,7 @@ bool CIVSHMEM::Open()
|
|||
IVSHMEM_SIZE size;
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_SIZE, nullptr, 0, &size, sizeof(size), nullptr, nullptr))
|
||||
{
|
||||
printf("Failed to request ivshmem size\n");
|
||||
DBGPRINT("Failed to request ivshmem size");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -142,7 +143,7 @@ bool CIVSHMEM::Open()
|
|||
config.cacheMode = IVSHMEM_CACHE_WRITECOMBINED;
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_REQUEST_MMAP, &config, sizeof(config), &map, sizeof(map), nullptr, nullptr))
|
||||
{
|
||||
printf("Failed to request ivshmem mmap\n");
|
||||
DBGPRINT("Failed to request ivshmem mmap");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -159,7 +160,7 @@ void CIVSHMEM::Close()
|
|||
|
||||
if (!DeviceIoControl(m_handle, IOCTL_IVSHMEM_RELEASE_MMAP, nullptr, 0, nullptr, 0, nullptr, nullptr))
|
||||
{
|
||||
printf("Failed to release ivshmem mmap\n");
|
||||
DBGPRINT("Failed to release ivshmem mmap");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ private:
|
|||
|
||||
std::vector<struct IVSHMEMData> m_devices;
|
||||
HANDLE m_handle = INVALID_HANDLE_VALUE;
|
||||
size_t m_size;
|
||||
void * m_mem = nullptr;
|
||||
size_t m_size = 0;
|
||||
void * m_mem = nullptr;
|
||||
|
||||
public:
|
||||
CIVSHMEM();
|
||||
|
@ -25,5 +25,8 @@ public:
|
|||
bool Init();
|
||||
bool Open();
|
||||
void Close();
|
||||
|
||||
size_t GetSize() { return m_size; }
|
||||
void * GetMem () { return m_mem; }
|
||||
};
|
||||
|
||||
|
|
|
@ -1,9 +1,46 @@
|
|||
#include "CIndirectDeviceContext.h"
|
||||
#include "CIndirectMonitorContext.h"
|
||||
|
||||
#include "CPlatformInfo.h"
|
||||
#include "Debug.h"
|
||||
|
||||
static const struct LGMPQueueConfig FRAME_QUEUE_CONFIG =
|
||||
{
|
||||
LGMP_Q_FRAME, //queueID
|
||||
LGMP_Q_FRAME_LEN, //numMessages
|
||||
1000 //subTimeout
|
||||
};
|
||||
|
||||
static const struct LGMPQueueConfig POINTER_QUEUE_CONFIG =
|
||||
{
|
||||
LGMP_Q_POINTER, //queueID
|
||||
LGMP_Q_POINTER_LEN, //numMesages
|
||||
1000 //subTimeout
|
||||
};
|
||||
|
||||
CIndirectDeviceContext::~CIndirectDeviceContext()
|
||||
{
|
||||
if (m_lgmp == nullptr)
|
||||
return;
|
||||
|
||||
if (m_lgmpTimer)
|
||||
{
|
||||
WdfTimerStop(m_lgmpTimer, TRUE);
|
||||
m_lgmpTimer = nullptr;
|
||||
}
|
||||
|
||||
for(int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
|
||||
lgmpHostMemFree(&m_frameMemory[i]);
|
||||
for (int i = 0; i < LGMP_Q_POINTER_LEN; ++i)
|
||||
lgmpHostMemFree(&m_pointerMemory[i]);
|
||||
for (int i = 0; i < POINTER_SHAPE_BUFFERS; ++i)
|
||||
lgmpHostMemFree(&m_pointerShapeMemory[i]);
|
||||
lgmpHostFree(&m_lgmp);
|
||||
}
|
||||
|
||||
void CIndirectDeviceContext::InitAdapter()
|
||||
{
|
||||
if (!m_ivshmem.Init() || !m_ivshmem.Open())
|
||||
if (!SetupLGMP())
|
||||
return;
|
||||
|
||||
IDDCX_ADAPTER_CAPS caps = {};
|
||||
|
@ -117,4 +154,179 @@ void CIndirectDeviceContext::FinishInit(UINT connectorIndex)
|
|||
|
||||
IDARG_OUT_MONITORARRIVAL out;
|
||||
status = IddCxMonitorArrival(createOut.MonitorObject, &out);
|
||||
}
|
||||
|
||||
#include <sstream>
|
||||
|
||||
bool CIndirectDeviceContext::SetupLGMP()
|
||||
{
|
||||
if (!m_ivshmem.Init() || !m_ivshmem.Open())
|
||||
return false;
|
||||
|
||||
std::stringstream ss;
|
||||
{
|
||||
KVMFR kvmfr = {};
|
||||
memcpy_s(kvmfr.magic, sizeof(kvmfr.magic), KVMFR_MAGIC, sizeof(KVMFR_MAGIC) - 1);
|
||||
kvmfr.version = KVMFR_VERSION;
|
||||
kvmfr.features = KVMFR_FEATURE_SETCURSORPOS;
|
||||
strncpy_s(kvmfr.hostver, "FIXME-IDD", sizeof(kvmfr.hostver) - 1);
|
||||
ss.write(reinterpret_cast<const char *>(&kvmfr), sizeof(kvmfr));
|
||||
}
|
||||
|
||||
{
|
||||
const std::string & model = CPlatformInfo::GetCPUModel();
|
||||
|
||||
KVMFRRecord_VMInfo * vmInfo = static_cast<KVMFRRecord_VMInfo *>(calloc(1, sizeof(*vmInfo)));
|
||||
vmInfo->cpus = static_cast<uint8_t>(CPlatformInfo::GetProcCount ());
|
||||
vmInfo->cores = static_cast<uint8_t>(CPlatformInfo::GetCoreCount ());
|
||||
vmInfo->sockets = static_cast<uint8_t>(CPlatformInfo::GetSocketCount());
|
||||
|
||||
const uint8_t * uuid = CPlatformInfo::GetUUID();
|
||||
memcpy_s (vmInfo->uuid, sizeof(vmInfo->uuid), uuid, 16);
|
||||
strncpy_s(vmInfo->capture, "Idd Driver", sizeof(vmInfo->capture));
|
||||
|
||||
KVMFRRecord * record = static_cast<KVMFRRecord *>(calloc(1, sizeof(*record)));
|
||||
record->type = KVMFR_RECORD_VMINFO;
|
||||
record->size = sizeof(*vmInfo) + (uint32_t)model.length() + 1;
|
||||
|
||||
ss.write(reinterpret_cast<const char*>(record ), sizeof(*record));
|
||||
ss.write(reinterpret_cast<const char*>(vmInfo ), sizeof(*vmInfo));
|
||||
ss.write(reinterpret_cast<const char*>(model.c_str()), model.length() + 1);
|
||||
}
|
||||
|
||||
{
|
||||
KVMFRRecord_OSInfo * osInfo = static_cast<KVMFRRecord_OSInfo *>(calloc(1, sizeof(*osInfo)));
|
||||
osInfo->os = KVMFR_OS_WINDOWS;
|
||||
|
||||
const std::string & osName = CPlatformInfo::GetProductName();
|
||||
|
||||
KVMFRRecord* record = static_cast<KVMFRRecord*>(calloc(1, sizeof(*record)));
|
||||
record->type = KVMFR_RECORD_OSINFO;
|
||||
record->size = sizeof(*osInfo) + (uint32_t)osName.length() + 1;
|
||||
|
||||
ss.write(reinterpret_cast<const char*>(record), sizeof(*record));
|
||||
ss.write(reinterpret_cast<const char*>(osInfo), sizeof(*osInfo));
|
||||
ss.write(reinterpret_cast<const char*>(osName.c_str()), osName.length() + 1);
|
||||
}
|
||||
|
||||
LGMP_STATUS status;
|
||||
std::string udata = ss.str();
|
||||
|
||||
if ((status = lgmpHostInit(m_ivshmem.GetMem(), (uint32_t)m_ivshmem.GetSize(),
|
||||
&m_lgmp, (uint32_t)udata.size(), (uint8_t*)&udata[0])) != LGMP_OK)
|
||||
{
|
||||
DBGPRINT("lgmpHostInit Failed: %s", lgmpStatusString(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((status = lgmpHostQueueNew(m_lgmp, FRAME_QUEUE_CONFIG, &m_frameQueue)) != LGMP_OK)
|
||||
{
|
||||
DBGPRINT("lgmpHostQueueCreate Failed (Frame): %s", lgmpStatusString(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((status = lgmpHostQueueNew(m_lgmp, POINTER_QUEUE_CONFIG, &m_pointerQueue)) != LGMP_OK)
|
||||
{
|
||||
DBGPRINT("lgmpHostQueueCreate Failed (Pointer): %s", lgmpStatusString(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < LGMP_Q_POINTER_LEN; ++i)
|
||||
{
|
||||
if ((status = lgmpHostMemAlloc(m_lgmp, MAX_POINTER_SIZE, &m_pointerMemory[i])) != LGMP_OK)
|
||||
{
|
||||
DBGPRINT("lgmpHostMemAlloc Failed (Pointer): %s", lgmpStatusString(status));
|
||||
return false;
|
||||
}
|
||||
memset(lgmpHostMemPtr(m_pointerMemory[i]), 0, MAX_POINTER_SIZE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < POINTER_SHAPE_BUFFERS; ++i)
|
||||
{
|
||||
if ((status = lgmpHostMemAlloc(m_lgmp, MAX_POINTER_SIZE, &m_pointerShapeMemory[i])) != LGMP_OK)
|
||||
{
|
||||
DBGPRINT("lgmpHostMemAlloc Failed (Pointer Shapes): %s", lgmpStatusString(status));
|
||||
return false;
|
||||
}
|
||||
memset(lgmpHostMemPtr(m_pointerShapeMemory[i]), 0, MAX_POINTER_SIZE);
|
||||
}
|
||||
|
||||
m_maxFrameSize = lgmpHostMemAvail(m_lgmp);
|
||||
m_maxFrameSize = (m_maxFrameSize -(CPlatformInfo::GetPageSize() - 1)) & ~(CPlatformInfo::GetPageSize() - 1);
|
||||
m_maxFrameSize /= LGMP_Q_FRAME_LEN;
|
||||
DBGPRINT("Max Frame Size: %u MiB\n", (unsigned int)(m_maxFrameSize / 1048576LL));
|
||||
|
||||
for (int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
|
||||
if ((status = lgmpHostMemAllocAligned(m_lgmp, (uint32_t)m_maxFrameSize,
|
||||
(uint32_t)CPlatformInfo::GetPageSize(), &m_frameMemory[i])) != LGMP_OK)
|
||||
{
|
||||
DBGPRINT("lgmpHostMemAllocAligned Failed (Frame): %s", lgmpStatusString(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
WDF_TIMER_CONFIG config;
|
||||
WDF_TIMER_CONFIG_INIT_PERIODIC(&config,
|
||||
[](WDFTIMER timer) -> void
|
||||
{
|
||||
WDFOBJECT parent = WdfTimerGetParentObject(timer);
|
||||
auto wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(parent);
|
||||
wrapper->context->LGMPTimer();
|
||||
},
|
||||
10);
|
||||
config.AutomaticSerialization = FALSE;
|
||||
|
||||
/**
|
||||
* documentation states that Dispatch is not available under the UDMF, however...
|
||||
* using Passive returns a not supported error, and Dispatch works.
|
||||
*/
|
||||
WDF_OBJECT_ATTRIBUTES attribs;
|
||||
WDF_OBJECT_ATTRIBUTES_INIT(&attribs);
|
||||
attribs.ParentObject = m_wdfDevice;
|
||||
attribs.ExecutionLevel = WdfExecutionLevelDispatch;
|
||||
|
||||
NTSTATUS s = WdfTimerCreate(&config, &attribs, &m_lgmpTimer);
|
||||
if (!NT_SUCCESS(s))
|
||||
{
|
||||
DBGPRINT("Timer creation failed: 0x%08x", s);
|
||||
return false;
|
||||
}
|
||||
WdfTimerStart(m_lgmpTimer, WDF_REL_TIMEOUT_IN_MS(10));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CIndirectDeviceContext::LGMPTimer()
|
||||
{
|
||||
LGMP_STATUS status;
|
||||
if ((status = lgmpHostProcess(m_lgmp)) != LGMP_OK)
|
||||
{
|
||||
if (status == LGMP_ERR_CORRUPTED)
|
||||
{
|
||||
DBGPRINT("LGMP reported the shared memory has been corrupted, attempting to recover\n");
|
||||
//TODO: fixme - reinit
|
||||
return;
|
||||
}
|
||||
|
||||
DBGPRINT("lgmpHostProcess Failed: %s", lgmpStatusString(status));
|
||||
//TODO: fixme - shutdown
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t data[LGMP_MSGS_SIZE];
|
||||
size_t size;
|
||||
while ((status = lgmpHostReadData(m_pointerQueue, &data, &size)) == LGMP_OK)
|
||||
{
|
||||
KVMFRMessage * msg = (KVMFRMessage *)data;
|
||||
switch (msg->type)
|
||||
{
|
||||
case KVMFR_MESSAGE_SETCURSORPOS:
|
||||
{
|
||||
KVMFRSetCursorPos *sp = (KVMFRSetCursorPos *)msg;
|
||||
SetCursorPos(sp->x, sp->y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lgmpHostAckData(m_pointerQueue);
|
||||
}
|
||||
}
|
|
@ -3,8 +3,17 @@
|
|||
#include <Windows.h>
|
||||
#include <wdf.h>
|
||||
#include <IddCx.h>
|
||||
|
||||
#include "CIVSHMEM.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lgmp/host.h"
|
||||
}
|
||||
|
||||
#include "common/KVMFR.h"
|
||||
#define MAX_POINTER_SIZE (sizeof(KVMFRCursor) + (512 * 512 * 4))
|
||||
#define POINTER_SHAPE_BUFFERS 3
|
||||
|
||||
class CIndirectDeviceContext
|
||||
{
|
||||
private:
|
||||
|
@ -12,11 +21,27 @@ private:
|
|||
IDDCX_ADAPTER m_adapter = nullptr;
|
||||
CIVSHMEM m_ivshmem;
|
||||
|
||||
PLGMPHost m_lgmp = nullptr;
|
||||
PLGMPHostQueue m_frameQueue = nullptr;
|
||||
|
||||
PLGMPHostQueue m_pointerQueue = nullptr;
|
||||
PLGMPMemory m_pointerMemory [LGMP_Q_POINTER_LEN ] = {};
|
||||
PLGMPMemory m_pointerShapeMemory[POINTER_SHAPE_BUFFERS] = {};
|
||||
|
||||
size_t m_maxFrameSize = 0;
|
||||
PLGMPMemory m_frameMemory[LGMP_Q_FRAME_LEN] = {};
|
||||
|
||||
bool SetupLGMP();
|
||||
|
||||
void LGMPTimer();
|
||||
|
||||
WDFTIMER m_lgmpTimer = nullptr;
|
||||
|
||||
public:
|
||||
CIndirectDeviceContext(_In_ WDFDEVICE wdfDevice) :
|
||||
m_wdfDevice(wdfDevice) {};
|
||||
|
||||
virtual ~CIndirectDeviceContext() {};
|
||||
virtual ~CIndirectDeviceContext();
|
||||
|
||||
void InitAdapter();
|
||||
|
||||
|
|
|
@ -4,18 +4,15 @@
|
|||
CIndirectMonitorContext::CIndirectMonitorContext(_In_ IDDCX_MONITOR monitor) :
|
||||
m_monitor(monitor)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
}
|
||||
|
||||
CIndirectMonitorContext::~CIndirectMonitorContext()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
m_thread.reset();
|
||||
}
|
||||
|
||||
void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID renderAdapter, HANDLE newFrameEvent)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
m_thread.reset();
|
||||
auto device = std::make_shared<Direct3DDevice>(renderAdapter);
|
||||
if (FAILED(device->Init()))
|
||||
|
@ -29,6 +26,5 @@ void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID re
|
|||
|
||||
void CIndirectMonitorContext::UnassignSwapChain()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
m_thread.reset();
|
||||
}
|
253
idd/LGIdd/CPlatformInfo.cpp
Normal file
253
idd/LGIdd/CPlatformInfo.cpp
Normal file
|
@ -0,0 +1,253 @@
|
|||
#include "CPlatformInfo.h"
|
||||
|
||||
#include "Debug.h"
|
||||
#include <Windows.h>
|
||||
|
||||
size_t CPlatformInfo::m_pageSize = 0;
|
||||
std::string CPlatformInfo::m_productName = "Unknown";
|
||||
uint8_t CPlatformInfo::m_uuid[16];
|
||||
|
||||
std::string CPlatformInfo::m_model = "Unknown";
|
||||
int CPlatformInfo::m_cores = 0;
|
||||
int CPlatformInfo::m_procs = 0;
|
||||
int CPlatformInfo::m_sockets = 0;
|
||||
|
||||
void CPlatformInfo::Init()
|
||||
{
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
m_pageSize = (size_t)si.dwPageSize;
|
||||
|
||||
// we only use this for reporting, it's OK that it might not be exactly accurate
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996)
|
||||
OSVERSIONINFOA osvi = {};
|
||||
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
||||
GetVersionExA(&osvi);
|
||||
#pragma warning(pop)
|
||||
|
||||
DWORD bufferSize = 0;
|
||||
LSTATUS status = RegGetValueA(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName",
|
||||
RRF_RT_REG_SZ, nullptr, nullptr, &bufferSize);
|
||||
if (status == ERROR_SUCCESS)
|
||||
{
|
||||
m_productName.resize(bufferSize);
|
||||
status = RegGetValueA(HKEY_LOCAL_MACHINE,
|
||||
"Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName",
|
||||
RRF_RT_REG_SZ, nullptr, &m_productName[0], &bufferSize);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
m_productName = "Unknown";
|
||||
DBGPRINT("Failed to read the ProductName");
|
||||
}
|
||||
else
|
||||
m_productName.resize(bufferSize - 1); // remove the double null termination
|
||||
}
|
||||
else
|
||||
{
|
||||
m_productName = "Windows " +
|
||||
std::to_string(osvi.dwMajorVersion) + "." +
|
||||
std::to_string(osvi.dwMinorVersion);
|
||||
}
|
||||
|
||||
m_productName += " (Build: " +
|
||||
std::to_string(osvi.dwBuildNumber) + ") " +
|
||||
osvi.szCSDVersion;
|
||||
|
||||
InitUUID();
|
||||
InitCPUInfo();
|
||||
}
|
||||
|
||||
#define TABLE_SIG(x) (\
|
||||
((uint32_t)(x[0]) << 24) | \
|
||||
((uint32_t)(x[1]) << 16) | \
|
||||
((uint32_t)(x[2]) << 8 ) | \
|
||||
((uint32_t)(x[3]) << 0 ))
|
||||
|
||||
#define SMB_SST_SystemInformation 1
|
||||
|
||||
#define SMBVER(major, minor) \
|
||||
((smbData->SMBIOSMajorVersion == major && \
|
||||
smbData->SMBIOSMinorVersion >= minor) || \
|
||||
(smbData->SMBIOSMajorVersion > major))
|
||||
|
||||
#define REVERSE32(x) \
|
||||
*(uint32_t*)(x) = ((*(uint32_t*)(x) & 0xFFFF0000) >> 16) | \
|
||||
((*(uint32_t*)(x) & 0x0000FFFF) << 16)
|
||||
|
||||
#define REVERSE16(x) \
|
||||
*(uint16_t*)(x) = ((*(uint16_t*)(x) & 0xFF00) >> 8) | \
|
||||
((*(uint16_t*)(x) & 0x00FF) << 8)
|
||||
|
||||
|
||||
static void* smbParseData(uint8_t** data, char* strings[])
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
struct SMBHeader
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
SMBHeader* h = (SMBHeader*)*data;
|
||||
|
||||
*data += h->length;
|
||||
if (**data)
|
||||
for (int i = 1; i < 256 && **data; ++i)
|
||||
{
|
||||
strings[i] = (char*)*data;
|
||||
*data += strlen((char*)*data) + 1;
|
||||
}
|
||||
else
|
||||
++* data;
|
||||
|
||||
++* data;
|
||||
return h;
|
||||
}
|
||||
|
||||
void CPlatformInfo::InitUUID()
|
||||
{
|
||||
// don't warn on zero length arrays
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200)
|
||||
struct RawSMBIOSData
|
||||
{
|
||||
BYTE Used20CallingMethod;
|
||||
BYTE SMBIOSMajorVersion;
|
||||
BYTE SMBIOSMinorVersion;
|
||||
BYTE DmiRevision;
|
||||
DWORD Length;
|
||||
BYTE SMBIOSTableData[];
|
||||
};
|
||||
#pragma warning(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct SMBSystemInformation
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint16_t handle;
|
||||
uint8_t manufacturerStr;
|
||||
uint8_t productStr;
|
||||
uint8_t versionStr;
|
||||
uint8_t serialStr;
|
||||
uint8_t uuid[16];
|
||||
uint8_t wakeupType;
|
||||
uint8_t skuNumberStr;
|
||||
uint8_t familyStr;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
DWORD smbDataSize;
|
||||
RawSMBIOSData * smbData;
|
||||
smbDataSize = GetSystemFirmwareTable(TABLE_SIG("RSMB"), 0, nullptr, 0);
|
||||
smbData = (RawSMBIOSData*)new BYTE[smbDataSize];
|
||||
if (!smbData)
|
||||
{
|
||||
DBGPRINT("out of memory");
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetSystemFirmwareTable(TABLE_SIG("RSMB"), 0, smbData, smbDataSize)
|
||||
!= smbDataSize)
|
||||
{
|
||||
DBGPRINT("Failed to read the RSMB table");
|
||||
delete[] smbData;
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t * data = (uint8_t *)smbData->SMBIOSTableData;
|
||||
uint8_t * end = (uint8_t *)smbData->SMBIOSTableData + smbData->Length;
|
||||
char * strings[256] = {};
|
||||
|
||||
while (data != end)
|
||||
{
|
||||
if (data[0] == SMB_SST_SystemInformation)
|
||||
{
|
||||
SMBSystemInformation * info = (SMBSystemInformation *)smbParseData(&data, strings);
|
||||
memcpy(&m_uuid, &info->uuid, 16);
|
||||
|
||||
REVERSE32(&m_uuid[0]);
|
||||
REVERSE16(&m_uuid[0]);
|
||||
REVERSE16(&m_uuid[2]);
|
||||
REVERSE16(&m_uuid[4]);
|
||||
REVERSE16(&m_uuid[6]);
|
||||
break;
|
||||
}
|
||||
|
||||
smbParseData(&data, strings);
|
||||
}
|
||||
|
||||
delete[] smbData;
|
||||
}
|
||||
|
||||
void CPlatformInfo::InitCPUInfo()
|
||||
{
|
||||
DWORD bufferSize = 0;
|
||||
LSTATUS status = RegGetValueA(HKEY_LOCAL_MACHINE,
|
||||
"HARDWARE\\DESCRIPTION\\SYSTEM\\CentralProcessor\\0",
|
||||
"ProcessorNameString", RRF_RT_REG_SZ, nullptr, nullptr, &bufferSize);
|
||||
if (status == ERROR_SUCCESS)
|
||||
{
|
||||
m_model.resize(bufferSize);
|
||||
status = RegGetValueA(HKEY_LOCAL_MACHINE,
|
||||
"HARDWARE\\DESCRIPTION\\SYSTEM\\CentralProcessor\\0",
|
||||
"ProcessorNameString", RRF_RT_REG_SZ, nullptr, &m_model[0], &bufferSize);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
m_model = "Unknown";
|
||||
DBGPRINT("Failed to read the CPU Model");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_model.resize(bufferSize - 1); // remove the double null termination
|
||||
m_model.erase(m_model.find_last_not_of(" \t\n\r\f\v") + 1);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD cb = 0;
|
||||
GetLogicalProcessorInformationEx(RelationAll, nullptr, &cb);
|
||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
DBGPRINT("Failed to call GetLogicalProcessorInformationEx");
|
||||
return;
|
||||
}
|
||||
|
||||
BYTE * buffer = static_cast<BYTE *>(_malloca(cb));
|
||||
if (!GetLogicalProcessorInformationEx(RelationAll,
|
||||
(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)buffer, &cb))
|
||||
{
|
||||
DBGPRINT("Failed to call GetLogicalProcessorInformationEx");
|
||||
_freea(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD offset = 0;
|
||||
while (offset < cb)
|
||||
{
|
||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX lpi =
|
||||
(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)(buffer + offset);
|
||||
switch (lpi->Relationship)
|
||||
{
|
||||
case RelationProcessorCore:
|
||||
++m_cores;
|
||||
|
||||
for(int i = 0; i < lpi->Processor.GroupCount; ++i)
|
||||
m_procs += (int)__popcnt64(lpi->Processor.GroupMask[i].Mask);
|
||||
break;
|
||||
|
||||
case RelationProcessorPackage:
|
||||
++m_sockets;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
offset += lpi->Size;
|
||||
}
|
||||
|
||||
_freea(buffer);
|
||||
}
|
31
idd/LGIdd/CPlatformInfo.h
Normal file
31
idd/LGIdd/CPlatformInfo.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class CPlatformInfo
|
||||
{
|
||||
private:
|
||||
static size_t m_pageSize;
|
||||
static std::string m_productName;
|
||||
static uint8_t m_uuid[16];
|
||||
|
||||
static std::string m_model;
|
||||
static int m_cores;
|
||||
static int m_procs;
|
||||
static int m_sockets;
|
||||
|
||||
static void InitUUID();
|
||||
static void InitCPUInfo();
|
||||
|
||||
public:
|
||||
static void Init();
|
||||
|
||||
inline static size_t GetPageSize() { return m_pageSize; }
|
||||
inline static const std::string& GetProductName() { return m_productName; }
|
||||
inline static const uint8_t* GetUUID() { return m_uuid; }
|
||||
|
||||
inline static const std::string & GetCPUModel() { return m_model; }
|
||||
inline static int GetCoreCount() { return m_cores; }
|
||||
inline static int GetProcCount() { return m_procs; }
|
||||
inline static int GetSocketCount() { return m_sockets; }
|
||||
};
|
|
@ -8,14 +8,12 @@ CSwapChainProcessor::CSwapChainProcessor(IDDCX_SWAPCHAIN hSwapChain, std::shared
|
|||
m_device(device),
|
||||
m_newFrameEvent(newFrameEvent)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
m_terminateEvent.Attach(CreateEvent(nullptr, FALSE, FALSE, nullptr));
|
||||
m_thread.Attach(CreateThread(nullptr, 0, RunThread, this, 0, nullptr));
|
||||
}
|
||||
|
||||
CSwapChainProcessor::~CSwapChainProcessor()
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
SetEvent(m_terminateEvent.Get());
|
||||
if (m_thread.Get())
|
||||
WaitForSingleObject(m_thread.Get(), INFINITE);
|
||||
|
@ -23,7 +21,6 @@ CSwapChainProcessor::~CSwapChainProcessor()
|
|||
|
||||
DWORD CALLBACK CSwapChainProcessor::RunThread(LPVOID argument)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
reinterpret_cast<CSwapChainProcessor*>(argument)->Run();
|
||||
return 0;
|
||||
}
|
||||
|
|
32
idd/LGIdd/Debug.cpp
Normal file
32
idd/LGIdd/Debug.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <Windows.h>
|
||||
#include <malloc.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
/* credit: https://stackoverflow.com/questions/29049686/is-there-a-better-way-to-pass-formatted-output-to-outputdebugstring */
|
||||
VOID _DBGPRINT(PCSTR kwszFunction, INT iLineNumber, LPCSTR kszDebugFormatString, ...) \
|
||||
{
|
||||
INT cbFormatString = 0;
|
||||
va_list args;
|
||||
PCHAR szDebugString = NULL;
|
||||
size_t st_Offset = 0;
|
||||
|
||||
va_start(args, kszDebugFormatString);
|
||||
|
||||
cbFormatString = _scprintf("[%s:%d] ", kwszFunction, iLineNumber) * sizeof(CHAR);
|
||||
cbFormatString += _vscprintf(kszDebugFormatString, args) * sizeof(CHAR) + 2;
|
||||
|
||||
/* Depending on the size of the format string, allocate space on the stack or the heap. */
|
||||
szDebugString = (PCHAR)_malloca(cbFormatString);
|
||||
if (!szDebugString)
|
||||
return;
|
||||
|
||||
/* Populate the buffer with the contents of the format string. */
|
||||
StringCbPrintfA(szDebugString, cbFormatString, "[%s:%d] ", kwszFunction, iLineNumber);
|
||||
StringCbLengthA(szDebugString, cbFormatString, &st_Offset);
|
||||
StringCbVPrintfA(&szDebugString[st_Offset / sizeof(CHAR)], cbFormatString - st_Offset, kszDebugFormatString, args);
|
||||
|
||||
OutputDebugStringA(szDebugString);
|
||||
|
||||
_freea(szDebugString);
|
||||
va_end(args);
|
||||
}
|
8
idd/LGIdd/Debug.h
Normal file
8
idd/LGIdd/Debug.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
VOID _DBGPRINT(PCSTR kszFunction, INT iLineNumber, LPCSTR kszDebugFormatString, ...);
|
||||
#define DBGPRINT(kszDebugFormatString, ...) \
|
||||
_DBGPRINT(__FUNCTION__, __LINE__, kszDebugFormatString, __VA_ARGS__)
|
|
@ -16,7 +16,7 @@ NTSTATUS LGIddDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previousSta
|
|||
{
|
||||
UNREFERENCED_PARAMETER(previousState);
|
||||
UNREFERENCED_PARAMETER(device);
|
||||
|
||||
|
||||
auto * wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(device);
|
||||
wrapper->context->InitAdapter();
|
||||
|
||||
|
@ -132,7 +132,6 @@ NTSTATUS LGIddMonitorUnassignSwapChain(IDDCX_MONITOR monitor)
|
|||
|
||||
NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
|
||||
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
|
||||
pnpPowerCallbacks.EvtDeviceD0Entry = LGIddDeviceD0Entry;
|
||||
|
@ -150,10 +149,7 @@ NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit)
|
|||
|
||||
NTSTATUS status = IddCxDeviceInitConfig(deviceInit, &config);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__ " FAILURE1");
|
||||
return status;
|
||||
}
|
||||
|
||||
WDF_OBJECT_ATTRIBUTES deviceAttributes;
|
||||
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, CIndirectDeviceContextWrapper);
|
||||
|
@ -167,16 +163,11 @@ NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit)
|
|||
WDFDEVICE device = nullptr;
|
||||
status = WdfDeviceCreate(&deviceInit, &deviceAttributes, &device);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__ " FAILURE2");
|
||||
return status;
|
||||
}
|
||||
|
||||
status = IddCxDeviceInitialize(device);
|
||||
|
||||
auto wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(device);
|
||||
wrapper->context = new CIndirectDeviceContext(device);
|
||||
|
||||
OutputDebugStringA(__FUNCTION__ " SUCCESS");
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "driver.h"
|
||||
#include "driver.tmh"
|
||||
|
||||
#include "CPlatformInfo.h"
|
||||
|
||||
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
|
||||
WDF_DRIVER_CONFIG config;
|
||||
NTSTATUS status;
|
||||
WDF_OBJECT_ATTRIBUTES attributes;
|
||||
|
@ -21,10 +21,10 @@ NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING Reg
|
|||
attributes.EvtCleanupCallback = LGIddEvtDriverContextCleanup;
|
||||
WDF_DRIVER_CONFIG_INIT(&config, LGIddEvtDeviceAdd);
|
||||
|
||||
CPlatformInfo::Init();
|
||||
status = WdfDriverCreate(DriverObject, RegistryPath, &attributes, &config, WDF_NO_HANDLE);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__ " FAILURE");
|
||||
TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
|
||||
#if UMDF_VERSION_MAJOR == 2 && UMDF_VERSION_MINOR == 0
|
||||
WPP_CLEANUP();
|
||||
|
@ -35,14 +35,11 @@ NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING Reg
|
|||
}
|
||||
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
|
||||
OutputDebugStringA(__FUNCTION__ " SUCCESS");
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS LGIddEvtDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
|
||||
NTSTATUS status;
|
||||
UNREFERENCED_PARAMETER(Driver);
|
||||
|
||||
|
@ -54,8 +51,6 @@ NTSTATUS LGIddEvtDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT Device
|
|||
|
||||
VOID LGIddEvtDriverContextCleanup(_In_ WDFOBJECT DriverObject)
|
||||
{
|
||||
OutputDebugStringA(__FUNCTION__);
|
||||
|
||||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
|
||||
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry");
|
||||
|
|
|
@ -41,7 +41,9 @@
|
|||
<ClCompile Include="CIndirectDeviceContext.cpp" />
|
||||
<ClCompile Include="CIndirectMonitorContext.cpp" />
|
||||
<ClCompile Include="CIVSHMEM.cpp" />
|
||||
<ClCompile Include="CPlatformInfo.cpp" />
|
||||
<ClCompile Include="CSwapChainProcessor.cpp" />
|
||||
<ClCompile Include="Debug.cpp" />
|
||||
<ClCompile Include="Device.cpp" />
|
||||
<ClCompile Include="Direct3DDevice.cpp" />
|
||||
<ClCompile Include="Driver.cpp" />
|
||||
|
@ -49,7 +51,9 @@
|
|||
<ItemGroup>
|
||||
<ClInclude Include="CIndirectMonitorContext.h" />
|
||||
<ClInclude Include="CIVSHMEM.h" />
|
||||
<ClInclude Include="CPlatformInfo.h" />
|
||||
<ClInclude Include="CSwapChainProcessor.h" />
|
||||
<ClInclude Include="Debug.h" />
|
||||
<ClInclude Include="Device.h" />
|
||||
<ClInclude Include="Direct3DDevice.h" />
|
||||
<ClInclude Include="Driver.h" />
|
||||
|
@ -220,7 +224,7 @@
|
|||
<WppRecorderEnabled>true</WppRecorderEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
|
||||
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
|
||||
|
@ -232,7 +236,7 @@
|
|||
<WppRecorderEnabled>true</WppRecorderEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
|
||||
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
|
||||
|
@ -244,7 +248,7 @@
|
|||
<WppRecorderEnabled>true</WppRecorderEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
|
||||
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
|
||||
|
@ -256,7 +260,7 @@
|
|||
<WppRecorderEnabled>true</WppRecorderEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
|
||||
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=4 /IDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);OneCoreUAP.lib;avrt.lib</AdditionalDependencies>
|
||||
|
|
|
@ -54,6 +54,12 @@
|
|||
<ClInclude Include="CIVSHMEM.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Debug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CPlatformInfo.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Device.cpp">
|
||||
|
@ -77,5 +83,11 @@
|
|||
<ClCompile Include="CIVSHMEM.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debug.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CPlatformInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in a new issue