[porthole] update in accordance with the recent windows driver changes

This commit is contained in:
Geoffrey McRae 2019-10-31 23:45:08 +11:00
parent 9d6bb57eff
commit 01da541815
6 changed files with 98 additions and 88 deletions

View File

@ -1 +1 @@
B1-18-g438548c427+1
B1-19-g9d6bb57eff+1

View File

@ -21,6 +21,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <stdint.h>
typedef struct PortholeDev *PortholeDev;
typedef int PortholeID;
/**
* Open the porthole device
@ -49,7 +50,7 @@ void porthole_dev_close(PortholeDev *handle);
* @param type The type
* @param buffer The buffer to share
* @param size The size of the buffer
* @returns true on success
* @returns the porthole mapping ID, or -1 on failure
*
* This function locks the supplied buffer in RAM via the porthole device
* driver and is then shared with the device for use outside the guest.
@ -63,23 +64,27 @@ void porthole_dev_close(PortholeDev *handle);
* This is an expensive operation, the idea is that you allocate fixed buffers
* and share them with the host at initialization.
*
* @note the driver is hard limited to 32 shares.
* @note the device & driver are hard limited to 32 shares.
*/
bool porthole_dev_share(PortholeDev handle, const uint32_t type, void *buffer, size_t size);
PortholeID porthole_dev_map(PortholeDev handle, const uint32_t type, void *buffer, size_t size);
/**
* Unlock a previously shared buffer
* Unmap a previously shared buffer
*
* @param handle The porthole device
* @param buffer The buffer to unlock
* @param size The size of the buffer
* @param id The porthole map id returned by porthole_dev_share
* @returns true on success
*
* Unlocks a previously shared buffer. Once this has been done the buffer can
* Unmaps a previously shared buffer. Once this has been done the buffer can
* be freed or re-used. The client application should no longer attempt to
* access this buffer as it may be paged out of RAM.
*
* Note that this is not strictly required as closing the device will cause
* the driver to cleanup any prior locked buffers.
*
* The client application will be notified that the mapping is about to become
* invalid and is expected to clean up and notify when it is done. If your
* application hangs calling this method the issue is very likely with your
* client application.
*/
bool porthole_dev_unlock(PortholeDev handle, void *buffer, size_t size);
bool porthole_dev_unmap(PortholeDev handle, PortholeID id);

View File

@ -1,54 +0,0 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdint.h>
typedef struct {
uint64_t id;
} __attribute__ ((packed)) MsgFd;
typedef struct {
uint64_t fd_id;
uint64_t addr;
uint32_t size;
} __attribute__ ((packed)) MsgSegment;
typedef struct {
uint32_t type;
} __attribute__ ((packed)) MsgFinish;
typedef struct {
uint32_t msg;
union
{
MsgFd fd;
MsgSegment segment;
MsgFinish finish;
} u;
} __attribute__ ((packed)) Msg;
#define INTRO_MSG_RESET 0x1
#define INTRO_MSG_FD 0x2
#define INTRO_MSG_SEGMENT 0x3
#define INTRO_MSG_FINISH 0x4
#define INTRO_MSG_RESET_SIZE (sizeof(uint32_t))
#define INTRO_MSG_FD_SIZE (sizeof(uint32_t) + sizeof(MsgFd))
#define INTRO_MSG_SEGMENT_SIZE (sizeof(uint32_t) + sizeof(MsgSegment))
#define INTRO_MSG_FINISH_SIZE (sizeof(uint32_t) + sizeof(MsgFinish))

62
porthole/src/phmsg.h Normal file
View File

@ -0,0 +1,62 @@
/*
Looking Glass - KVM FrameRelay (KVMFR) Client
Copyright (C) 2017-2019 Geoffrey McRae <geoff@hostfission.com>
https://looking-glass.hostfission.com
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdint.h>
typedef struct {
uint32_t id; // the ID of the FD
} __attribute__ ((packed)) PHMsgFd;
typedef struct {
uint32_t fd_id; // the ID of the FD for this segment
uint32_t size; // the size of this segment
uint64_t addr; // the base address of this segment
} __attribute__ ((packed)) PHMsgSegment;
typedef struct {
uint32_t type; // the application defined type
uint32_t id; // the ID of the new mapping
} __attribute__ ((packed)) PHMsgFinish;
typedef struct {
uint32_t id; // the mapping ID
} __attribute__ ((packed)) PHMsgUnmap;
typedef struct {
uint32_t msg;
union
{
PHMsgFd fd;
PHMsgSegment segment;
PHMsgFinish finish;
PHMsgUnmap unmap;
} u;
} __attribute__ ((packed)) PHMsg;
#define PH_MSG_MAP 0x1 // start of a map sequence
#define PH_MSG_FD 0x2 // file descriptor
#define PH_MSG_SEGMENT 0x3 // map segment
#define PH_MSG_FINISH 0x4 // finish of map sequence
#define PH_MSG_UNMAP 0x5 // unmap a previous map
#define PH_MSG_MAP_SIZE (sizeof(uint32_t))
#define PH_MSG_FD_SIZE (sizeof(uint32_t) + sizeof(PHMsgFd))
#define PH_MSG_SEGMENT_SIZE (sizeof(uint32_t) + sizeof(PHMsgSegment))
#define PH_MSG_FINISH_SIZE (sizeof(uint32_t) + sizeof(PHMsgFinish))
#define PH_MSG_UNMAP_SIZE (sizeof(uint32_t) + sizeof(PHMsgUnmap))

View File

@ -24,6 +24,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <windows.h>
#include <setupapi.h>
#include <assert.h>
struct PortholeDev
{
@ -37,11 +38,7 @@ bool porthole_dev_open(PortholeDev *handle, const uint32_t vendor_id)
SP_DEVICE_INTERFACE_DATA devInfData = {0};
HANDLE dev;
if (!handle)
{
DEBUG_ERROR("Invalid buffer provided");
return false;
}
assert(handle);
devInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_DEVICEINTERFACE);
devInfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
@ -121,13 +118,17 @@ bool porthole_dev_open(PortholeDev *handle, const uint32_t vendor_id)
void porthole_dev_close(PortholeDev *handle)
{
assert(handle && *handle);
CloseHandle((*handle)->dev);
free(*handle);
*handle = NULL;
}
bool porthole_dev_share(PortholeDev handle, const uint32_t type, void *buffer, size_t size)
PortholeID porthole_dev_map(PortholeDev handle, const uint32_t type, void *buffer, size_t size)
{
assert(handle);
DWORD returned;
PortholeMsg msg = {
@ -136,22 +137,23 @@ bool porthole_dev_share(PortholeDev handle, const uint32_t type, void *buffer, s
.size = size
};
if (!DeviceIoControl(handle->dev, IOCTL_PORTHOLE_SEND_MSG, &msg, sizeof(PortholeMsg), NULL, 0, &returned, NULL))
return false;
PortholeMapID out;
return true;
if (!DeviceIoControl(handle->dev, IOCTL_PORTHOLE_SEND_MSG, &msg, sizeof(PortholeMsg), &out, sizeof(PortholeMapID), &returned, NULL))
return -1;
PortholeID ret = out;
return ret;
}
bool porthole_dev_unlock(PortholeDev handle, void *buffer, size_t size)
bool porthole_dev_unmap(PortholeDev handle, PortholeID id)
{
assert(handle);
DWORD returned;
PortholeLockMsg msg = {
.addr = buffer,
.size = size
};
if (!DeviceIoControl(handle->dev, IOCTL_PORTHOLE_UNLOCK_BUFFER, &msg , sizeof(PortholeLockMsg), NULL, 0, &returned, NULL))
PortholeMapID msg = id;
if (!DeviceIoControl(handle->dev, IOCTL_PORTHOLE_UNLOCK_BUFFER, &msg, sizeof(PortholeMapID), NULL, 0, &returned, NULL))
return false;
return true;

View File

@ -7,18 +7,13 @@ DEFINE_GUID (GUID_DEVINTERFACE_PORTHOLE,
typedef struct _PortholeMsg
{
UINT32 type;
PVOID addr;
UINT32 size;
UINT32 type;
PVOID addr;
UINT32 size;
}
PortholeMsg, *PPortholeMsg;
typedef struct _PortholeLockMsg
{
PVOID addr;
UINT32 size;
}
PortholeLockMsg, *PPortholeLockMsg;
typedef int PortholeMapID, *PPortholeMapID;
#define IOCTL_PORTHOLE_SEND_MSG CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PORTHOLE_UNLOCK_BUFFER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)