mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 05:27:20 +00:00
[porthole] added connection state support
This commit is contained in:
parent
968b313993
commit
453b8e6a4d
@ -24,13 +24,20 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
typedef struct PortholeDev *PortholeDev;
|
typedef struct PortholeDev *PortholeDev;
|
||||||
typedef int PortholeID;
|
typedef int PortholeID;
|
||||||
|
typedef enum PortholeState
|
||||||
|
{
|
||||||
|
PH_STATE_NEW_SESSION,
|
||||||
|
PH_STATE_CONNECTED,
|
||||||
|
PH_STATE_DISCONNECTED
|
||||||
|
}
|
||||||
|
PortholeState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the porthole device
|
* Open the porthole device
|
||||||
*
|
*
|
||||||
* @param handle The returned handle if successful, otherwise undefined
|
* @param handle The returned handle if successful, otherwise undefined
|
||||||
* @param vendor_id The subsystem vendor and device id to match
|
* @param vendor_id The subsystem vendor and device id to match
|
||||||
* @returns true on success
|
* @return true on success
|
||||||
*
|
*
|
||||||
* If successful the handle must be closed to free resources when finished.
|
* If successful the handle must be closed to free resources when finished.
|
||||||
*/
|
*/
|
||||||
@ -45,14 +52,38 @@ bool porthole_dev_open(PortholeDev *handle, const uint32_t vendor_id);
|
|||||||
*/
|
*/
|
||||||
void porthole_dev_close(PortholeDev *handle);
|
void porthole_dev_close(PortholeDev *handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the state of the porthole device
|
||||||
|
*
|
||||||
|
* @param handle The porthole device handle obtained form porthole_dev_open
|
||||||
|
* @return The current state of the connection
|
||||||
|
*
|
||||||
|
* This method will return the current state of the porthole device
|
||||||
|
*
|
||||||
|
* * PH_STATE_NEW_SESSION = The client has connected
|
||||||
|
* * PH_STATE_CONNECTED = The client is still connected
|
||||||
|
* * PH_STATE_DISCONNECTED = There is no client connection
|
||||||
|
*/
|
||||||
|
PortholeState porthole_dev_get_state(PortholeDev handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for the specified state
|
||||||
|
*
|
||||||
|
* @param handle The porthole device handle obtained from porthole_dev_open
|
||||||
|
* @param state The state to wait for
|
||||||
|
* @param timeout The maximum amount of time to wait in milliseconds for the state (0 = infinite)
|
||||||
|
* @return true on success, false on timeout
|
||||||
|
*/
|
||||||
|
bool porthole_dev_wait_state(PortholeDev handle, const PortholeState state, const unsigned int timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Share the provided buffer over the porthole device
|
* Share the provided buffer over the porthole device
|
||||||
*
|
*
|
||||||
* @param handle The porthole device
|
* @param handle The porthole device
|
||||||
* @param type The type
|
* @param type The type
|
||||||
* @param buffer The buffer to share
|
* @param buffer The buffer to share
|
||||||
* @param size The size of the buffer
|
* @param size The size of the buffer
|
||||||
* @returns the porthole mapping ID, or -1 on failure
|
* @return the porthole mapping ID, or -1 on failure
|
||||||
*
|
*
|
||||||
* This function locks the supplied buffer in RAM via the porthole device
|
* 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.
|
* driver and is then shared with the device for use outside the guest.
|
||||||
@ -73,9 +104,9 @@ PortholeID porthole_dev_map(PortholeDev handle, const uint32_t type, void *buffe
|
|||||||
/**
|
/**
|
||||||
* Unmap a previously shared buffer
|
* Unmap a previously shared buffer
|
||||||
*
|
*
|
||||||
* @param handle The porthole device
|
* @param handle The porthole device
|
||||||
* @param id The porthole map id returned by porthole_dev_share
|
* @param id The porthole map id returned by porthole_dev_share
|
||||||
* @returns true on success
|
* @return true on success
|
||||||
*
|
*
|
||||||
* Unmaps 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
|
* be freed or re-used. The client application should no longer attempt to
|
||||||
|
@ -28,7 +28,9 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
struct PortholeDev
|
struct PortholeDev
|
||||||
{
|
{
|
||||||
HANDLE dev;
|
HANDLE dev;
|
||||||
|
bool connected;
|
||||||
|
PortholeEvents events;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool porthole_dev_open(PortholeDev *handle, const uint32_t vendor_id)
|
bool porthole_dev_open(PortholeDev *handle, const uint32_t vendor_id)
|
||||||
@ -113,6 +115,22 @@ bool porthole_dev_open(PortholeDev *handle, const uint32_t vendor_id)
|
|||||||
|
|
||||||
(*handle)->dev = dev;
|
(*handle)->dev = dev;
|
||||||
|
|
||||||
|
/* create the events and register them */
|
||||||
|
(*handle)->events.connect = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
(*handle)->events.disconnect = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
|
DWORD returned;
|
||||||
|
if (!DeviceIoControl(dev, IOCTL_PORTHOLE_REGISTER_EVENTS, &(*handle)->events, sizeof(PortholeEvents), NULL, 0, &returned, NULL))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to register the events");
|
||||||
|
CloseHandle((*handle)->events.connect );
|
||||||
|
CloseHandle((*handle)->events.disconnect);
|
||||||
|
CloseHandle(dev);
|
||||||
|
free(*handle);
|
||||||
|
*handle = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,11 +138,89 @@ void porthole_dev_close(PortholeDev *handle)
|
|||||||
{
|
{
|
||||||
assert(handle && *handle);
|
assert(handle && *handle);
|
||||||
|
|
||||||
|
CloseHandle((*handle)->events.connect );
|
||||||
|
CloseHandle((*handle)->events.disconnect);
|
||||||
CloseHandle((*handle)->dev);
|
CloseHandle((*handle)->dev);
|
||||||
free(*handle);
|
free(*handle);
|
||||||
*handle = NULL;
|
*handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PortholeState get_state(PortholeDev handle, unsigned int timeout)
|
||||||
|
{
|
||||||
|
if (handle->connected)
|
||||||
|
{
|
||||||
|
switch(WaitForSingleObject(handle->events.disconnect, timeout))
|
||||||
|
{
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
handle->connected = false;
|
||||||
|
return PH_STATE_DISCONNECTED;
|
||||||
|
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
return PH_STATE_CONNECTED;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DEBUG_FATAL("Error waiting on disconnect event");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(WaitForSingleObject(handle->events.connect, timeout))
|
||||||
|
{
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
handle->connected = true;
|
||||||
|
return PH_STATE_NEW_SESSION;
|
||||||
|
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
return PH_STATE_DISCONNECTED;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DEBUG_FATAL("Error waiting on connection event");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PortholeState porthole_dev_get_state(PortholeDev handle)
|
||||||
|
{
|
||||||
|
return get_state(handle, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool porthole_dev_wait_state(PortholeDev handle, const PortholeState state, const unsigned int timeout)
|
||||||
|
{
|
||||||
|
const DWORD to = (timeout == 0) ? INFINITE : timeout;
|
||||||
|
PortholeState lastState = get_state(handle, 0);
|
||||||
|
|
||||||
|
if (state == lastState)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
PortholeState nextState;
|
||||||
|
switch(lastState)
|
||||||
|
{
|
||||||
|
case PH_STATE_DISCONNECTED:
|
||||||
|
nextState = PH_STATE_NEW_SESSION;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PH_STATE_NEW_SESSION:
|
||||||
|
nextState = PH_STATE_CONNECTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PH_STATE_CONNECTED:
|
||||||
|
nextState = PH_STATE_DISCONNECTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortholeState newState = get_state(handle, to);
|
||||||
|
if (newState == lastState || newState != nextState)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (newState == state)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
lastState = newState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PortholeID porthole_dev_map(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);
|
assert(handle);
|
||||||
|
Loading…
Reference in New Issue
Block a user