summaryrefslogtreecommitdiff
path: root/vdservice
diff options
context:
space:
mode:
Diffstat (limited to 'vdservice')
-rw-r--r--vdservice/pci_vdi_port.cpp256
-rw-r--r--vdservice/pci_vdi_port.h2
-rw-r--r--vdservice/vdi_port.h134
-rw-r--r--vdservice/virtio_vdi_port.cpp328
-rw-r--r--vdservice/virtio_vdi_port.h4
5 files changed, 362 insertions, 362 deletions
diff --git a/vdservice/pci_vdi_port.cpp b/vdservice/pci_vdi_port.cpp
index b055c5a..d07eab7 100644
--- a/vdservice/pci_vdi_port.cpp
+++ b/vdservice/pci_vdi_port.cpp
@@ -1,128 +1,128 @@
-/*
- Copyright (C) 2009 Red Hat, Inc.
-
- 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "stdio.h"
-#include "pci_vdi_port.h"
-#include "vdlog.h"
-
-#define VDI_PORT_DEV_NAME TEXT("\\\\.\\VDIPort")
-#define FILE_DEVICE_UNKNOWN 0x00000022
-#define METHOD_BUFFERED 0
-#define FILE_ANY_ACCESS 0
-
-#define CTL_CODE(DeviceType, Function, Method, Access) ( \
- ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
-)
-
-#define FIRST_AVAIL_IO_FUNC 0x800
-#define RED_TUNNEL_CTL_FUNC FIRST_AVAIL_IO_FUNC
-
-#define IOCTL_RED_TUNNEL_SET_EVENT \
- CTL_CODE(FILE_DEVICE_UNKNOWN, RED_TUNNEL_CTL_FUNC, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define MIN(a, b) ((a) > (b) ? (b) : (a))
-
-PCIVDIPort::PCIVDIPort()
- : _handle (INVALID_HANDLE_VALUE)
- , _event (NULL)
-{
-}
-
-PCIVDIPort::~PCIVDIPort()
-{
- if (_handle != INVALID_HANDLE_VALUE) {
- CloseHandle(_handle);
- }
- if (_event) {
- CloseHandle(_event);
- }
-}
-
-void PCIVDIPort::fill_events(HANDLE *handle) {
- handle[PCI_VDI_PORT_EVENT] = _event;
-}
-
-bool PCIVDIPort::init()
-{
- DWORD io_ret_len;
- _handle = CreateFile(VDI_PORT_DEV_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
- OPEN_EXISTING, 0, NULL);
- if (_handle == INVALID_HANDLE_VALUE) {
- vd_printf("CreateFile() failed: %u", GetLastError());
- return false;
- }
- _event = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (_event == NULL) {
- vd_printf("CreateEvent() failed: %u", GetLastError());
- return false;
- }
- if (!DeviceIoControl(_handle, IOCTL_RED_TUNNEL_SET_EVENT, &_event, sizeof(_event),
- NULL, 0, &io_ret_len, NULL)) {
- vd_printf("DeviceIoControl() failed: %u", GetLastError());
- return false;
- }
- return true;
-}
-
-int PCIVDIPort::write()
-{
- int size;
- int n;
-
- if (_write.start == _write.end) {
- return 0;
- }
- if (_write.start < _write.end) {
- size = (int)(_write.end - _write.start);
- } else {
- size = (int)(&_write.ring[BUF_SIZE] - _write.start);
- }
- if (!WriteFile(_handle, _write.start, size, (LPDWORD)&n, NULL)) {
- return handle_error();
- }
- _write.start = _write.ring + (_write.start - _write.ring + n) % BUF_SIZE;
- return n;
-}
-
-int PCIVDIPort::read()
-{
- int size;
- int n;
-
- if ((_read.end - _read.ring + 1) % BUF_SIZE == _read.start - _read.ring) {
- return 0;
- }
- if (_read.start == _read.end) {
- _read.start = _read.end = _read.ring;
- }
- if (_read.start <= _read.end) {
- size = MIN(BUF_SIZE - 1, (int)(&_read.ring[BUF_SIZE] - _read.end));
- } else {
- size = (int)(_read.start - _read.end - 1);
- }
- if (!ReadFile(_handle, _read.end, size, (LPDWORD)&n, NULL)) {
- return handle_error();
- }
- _read.end = _read.ring + (_read.end - _read.ring + n) % BUF_SIZE;
- return n;
-}
-
-void PCIVDIPort::handle_event(int event)
-{
- // do nothing - the event merely serves to wake us up, then we call read/write
- // at VDService::execute start of while(_running) loop.
-}
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdio.h"
+#include "pci_vdi_port.h"
+#include "vdlog.h"
+
+#define VDI_PORT_DEV_NAME TEXT("\\\\.\\VDIPort")
+#define FILE_DEVICE_UNKNOWN 0x00000022
+#define METHOD_BUFFERED 0
+#define FILE_ANY_ACCESS 0
+
+#define CTL_CODE(DeviceType, Function, Method, Access) ( \
+ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
+)
+
+#define FIRST_AVAIL_IO_FUNC 0x800
+#define RED_TUNNEL_CTL_FUNC FIRST_AVAIL_IO_FUNC
+
+#define IOCTL_RED_TUNNEL_SET_EVENT \
+ CTL_CODE(FILE_DEVICE_UNKNOWN, RED_TUNNEL_CTL_FUNC, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+PCIVDIPort::PCIVDIPort()
+ : _handle (INVALID_HANDLE_VALUE)
+ , _event (NULL)
+{
+}
+
+PCIVDIPort::~PCIVDIPort()
+{
+ if (_handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(_handle);
+ }
+ if (_event) {
+ CloseHandle(_event);
+ }
+}
+
+void PCIVDIPort::fill_events(HANDLE* handles) {
+ handles[PCI_VDI_PORT_EVENT] = _event;
+}
+
+bool PCIVDIPort::init()
+{
+ DWORD io_ret_len;
+ _handle = CreateFile(VDI_PORT_DEV_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ OPEN_EXISTING, 0, NULL);
+ if (_handle == INVALID_HANDLE_VALUE) {
+ vd_printf("CreateFile() failed: %u", GetLastError());
+ return false;
+ }
+ _event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (_event == NULL) {
+ vd_printf("CreateEvent() failed: %u", GetLastError());
+ return false;
+ }
+ if (!DeviceIoControl(_handle, IOCTL_RED_TUNNEL_SET_EVENT, &_event, sizeof(_event),
+ NULL, 0, &io_ret_len, NULL)) {
+ vd_printf("DeviceIoControl() failed: %u", GetLastError());
+ return false;
+ }
+ return true;
+}
+
+int PCIVDIPort::write()
+{
+ int size;
+ int n;
+
+ if (_write.start == _write.end) {
+ return 0;
+ }
+ if (_write.start < _write.end) {
+ size = (int)(_write.end - _write.start);
+ } else {
+ size = (int)(&_write.ring[BUF_SIZE] - _write.start);
+ }
+ if (!WriteFile(_handle, _write.start, size, (LPDWORD)&n, NULL)) {
+ return handle_error();
+ }
+ _write.start = _write.ring + (_write.start - _write.ring + n) % BUF_SIZE;
+ return n;
+}
+
+int PCIVDIPort::read()
+{
+ int size;
+ int n;
+
+ if ((_read.end - _read.ring + 1) % BUF_SIZE == _read.start - _read.ring) {
+ return 0;
+ }
+ if (_read.start == _read.end) {
+ _read.start = _read.end = _read.ring;
+ }
+ if (_read.start <= _read.end) {
+ size = MIN(BUF_SIZE - 1, (int)(&_read.ring[BUF_SIZE] - _read.end));
+ } else {
+ size = (int)(_read.start - _read.end - 1);
+ }
+ if (!ReadFile(_handle, _read.end, size, (LPDWORD)&n, NULL)) {
+ return handle_error();
+ }
+ _read.end = _read.ring + (_read.end - _read.ring + n) % BUF_SIZE;
+ return n;
+}
+
+void PCIVDIPort::handle_event(int event)
+{
+ // do nothing - the event merely serves to wake us up, then we call read/write
+ // at VDService::execute start of while(_running) loop.
+}
diff --git a/vdservice/pci_vdi_port.h b/vdservice/pci_vdi_port.h
index d9b6d67..caa990f 100644
--- a/vdservice/pci_vdi_port.h
+++ b/vdservice/pci_vdi_port.h
@@ -40,7 +40,7 @@ public:
virtual int write();
virtual int read();
virtual unsigned get_num_events() { return PCI_VDI_PORT_EVENT_COUNT; }
- virtual void fill_events(HANDLE* handle);
+ virtual void fill_events(HANDLE* handles);
virtual void handle_event(int event);
private:
diff --git a/vdservice/vdi_port.h b/vdservice/vdi_port.h
index b5c6f46..50c4d29 100644
--- a/vdservice/vdi_port.h
+++ b/vdservice/vdi_port.h
@@ -1,33 +1,33 @@
-/*
- Copyright (C) 2009 Red Hat, Inc.
-
- 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _H_VDI_PORT
-#define _H_VDI_PORT
-
-#include <windows.h>
-#include <stdint.h>
-
-#define MIN(a, b) ((a) > (b) ? (b) : (a))
-
-#define BUF_SIZE (1024 * 1024)
-
-#define VDI_PORT_BLOCKED 0
-#define VDI_PORT_RESET -1
-#define VDI_PORT_ERROR -2
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_VDI_PORT
+#define _H_VDI_PORT
+
+#include <windows.h>
+#include <stdint.h>
+
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+#define BUF_SIZE (1024 * 1024)
+
+#define VDI_PORT_BLOCKED 0
+#define VDI_PORT_RESET -1
+#define VDI_PORT_ERROR -2
// Ring notes:
// _end is one after the end of data
@@ -36,40 +36,40 @@
// _start-1 is never used
// ring_write & read on right side of the ring (update _end)
// ring_read & write from left (update _start)
-
-typedef struct VDIPortBuffer {
- OVERLAPPED overlap;
- uint8_t* start;
- uint8_t* end;
- bool pending;
- int bytes;
- uint8_t ring[BUF_SIZE];
-} VDIPortBuffer;
-
-class VDIPort {
-public:
- VDIPort();
- virtual ~VDIPort() {}
-
- size_t ring_write(const void* buf, size_t size);
- size_t write_ring_free_space();
- size_t ring_read(void* buf, size_t size);
- size_t read_ring_size();
- size_t read_ring_continuous_remaining_size();
-
- virtual const char *name() = 0;
- virtual bool init() = 0;
- virtual unsigned get_num_events() = 0;
- virtual void fill_events(HANDLE *handle) = 0;
- virtual void handle_event(int event) = 0;
- virtual int write() = 0;
- virtual int read() = 0;
-
-protected:
- int handle_error();
-
- VDIPortBuffer _write;
- VDIPortBuffer _read;
-};
-
-#endif
+
+typedef struct VDIPortBuffer {
+ OVERLAPPED overlap;
+ uint8_t* start;
+ uint8_t* end;
+ bool pending;
+ int bytes;
+ uint8_t ring[BUF_SIZE];
+} VDIPortBuffer;
+
+class VDIPort {
+public:
+ VDIPort();
+ virtual ~VDIPort() {}
+
+ size_t ring_write(const void* buf, size_t size);
+ size_t write_ring_free_space();
+ size_t ring_read(void* buf, size_t size);
+ size_t read_ring_size();
+ size_t read_ring_continuous_remaining_size();
+
+ virtual const char *name() = 0;
+ virtual bool init() = 0;
+ virtual unsigned get_num_events() = 0;
+ virtual void fill_events(HANDLE* handles) = 0;
+ virtual void handle_event(int event) = 0;
+ virtual int write() = 0;
+ virtual int read() = 0;
+
+protected:
+ int handle_error();
+
+ VDIPortBuffer _write;
+ VDIPortBuffer _read;
+};
+
+#endif
diff --git a/vdservice/virtio_vdi_port.cpp b/vdservice/virtio_vdi_port.cpp
index bbdd59e..ce4d80a 100644
--- a/vdservice/virtio_vdi_port.cpp
+++ b/vdservice/virtio_vdi_port.cpp
@@ -1,56 +1,56 @@
-/*
- Copyright (C) 2009 Red Hat, Inc.
-
- 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "stdio.h"
-#include "virtio_vdi_port.h"
-#include "vdlog.h"
-
-#define VIOSERIAL_PORT_PATH L"\\\\.\\Global\\com.redhat.spice.0"
-
-// Current limitation of virtio-serial windows driver (RHBZ 617000)
-#define VIOSERIAL_PORT_MAX_WRITE_BYTES 2048
-
-VirtioVDIPort* VirtioVDIPort::_singleton;
-
-VirtioVDIPort::VirtioVDIPort()
- : VDIPort()
- , _handle (INVALID_HANDLE_VALUE)
-{
- _singleton = this;
-}
-
-VirtioVDIPort::~VirtioVDIPort()
-{
- if (_handle != INVALID_HANDLE_VALUE) {
- CloseHandle(_handle);
- }
- if (_read.overlap.hEvent) {
- CloseHandle(_read.overlap.hEvent);
- }
- if (_write.overlap.hEvent) {
- CloseHandle(_write.overlap.hEvent);
- }
-}
-
-void VirtioVDIPort::fill_events(HANDLE *handle) {
- handle[VIRTIO_VDI_PORT_EVENT_WRITE] = _write.overlap.hEvent;
- handle[VIRTIO_VDI_PORT_EVENT_READ] = _read.overlap.hEvent;
-}
-
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdio.h"
+#include "virtio_vdi_port.h"
+#include "vdlog.h"
+
+#define VIOSERIAL_PORT_PATH L"\\\\.\\Global\\com.redhat.spice.0"
+
+// Current limitation of virtio-serial windows driver (RHBZ 617000)
+#define VIOSERIAL_PORT_MAX_WRITE_BYTES 2048
+
+VirtioVDIPort* VirtioVDIPort::_singleton;
+
+VirtioVDIPort::VirtioVDIPort()
+ : VDIPort()
+ , _handle (INVALID_HANDLE_VALUE)
+{
+ _singleton = this;
+}
+
+VirtioVDIPort::~VirtioVDIPort()
+{
+ if (_handle != INVALID_HANDLE_VALUE) {
+ CloseHandle(_handle);
+ }
+ if (_read.overlap.hEvent) {
+ CloseHandle(_read.overlap.hEvent);
+ }
+ if (_write.overlap.hEvent) {
+ CloseHandle(_write.overlap.hEvent);
+ }
+}
+
+void VirtioVDIPort::fill_events(HANDLE* handles) {
+ handles[VIRTIO_VDI_PORT_EVENT_WRITE] = _write.overlap.hEvent;
+ handles[VIRTIO_VDI_PORT_EVENT_READ] = _read.overlap.hEvent;
+}
+
void VirtioVDIPort::handle_event(int event) {
switch (event) {
case VIRTIO_VDI_PORT_EVENT_WRITE:
@@ -62,114 +62,114 @@ void VirtioVDIPort::handle_event(int event) {
default:
vd_printf("ERROR: unexpected event %d", event);
}
-}
-
-bool VirtioVDIPort::init()
-{
- _handle = CreateFile(VIOSERIAL_PORT_PATH, GENERIC_READ | GENERIC_WRITE , 0, NULL,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (_handle == INVALID_HANDLE_VALUE) {
- vd_printf("CreateFile() %s failed: %u", VIOSERIAL_PORT_PATH, GetLastError());
- return false;
- }
- _write.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (_write.overlap.hEvent == NULL) {
- vd_printf("CreateEvent() failed: %u", GetLastError());
- return false;
- }
- _read.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (_read.overlap.hEvent == NULL) {
- vd_printf("CreateEvent() failed: %u", GetLastError());
- return false;
- }
- return true;
-}
-
-int VirtioVDIPort::write()
-{
- int size;
- int ret;
-
- //FIXME: return VDI_PORT_NO_DATA
- if (_write.start == _write.end) {
- return 0;
- }
- if (!_write.pending) {
- if (_write.start < _write.end) {
- size = (int)(_write.end - _write.start);
- } else {
- size = (int)(&_write.ring[BUF_SIZE] - _write.start);
- }
- size = MIN(size, VIOSERIAL_PORT_MAX_WRITE_BYTES);
- _write.pending = true;
- if (WriteFile(_handle, _write.start, size, NULL, &_write.overlap)) {
- write_completion();
- } if (GetLastError() != ERROR_IO_PENDING) {
- return handle_error();
- }
- }
- ret = _write.bytes;
- _write.bytes = 0;
- return ret;
-}
-
-void VirtioVDIPort::write_completion()
-{
- DWORD bytes;
-
- if (!_write.pending) {
- return;
- }
- if (!GetOverlappedResult(_handle, &_write.overlap, &bytes, FALSE)) {
- vd_printf("GetOverlappedResult failed: %u", GetLastError());
- return;
- }
- _write.start = _write.ring + (_write.start - _write.ring + bytes) % BUF_SIZE;
- _write.bytes = bytes;
- _write.pending = false;
-}
-
-int VirtioVDIPort::read()
-{
- int size;
- int ret;
-
- if (!_read.pending) {
- //FIXME: read_ring_continuous_remaining_size? return VDI_PORT_BUFFER_FULL
- if ((_read.end - _read.ring + 1) % BUF_SIZE == _read.start - _read.ring) {
- vd_printf("DEBUG: buffer full");
- return 0;
- }
- if (_read.start == _read.end) {
- _read.start = _read.end = _read.ring;
- }
- if (_read.start <= _read.end) {
- size = MIN(BUF_SIZE - 1, (int)(&_read.ring[BUF_SIZE] - _read.end));
- } else {
- size = (int)(_read.start - _read.end - 1);
- }
- _read.pending = true;
- if (ReadFile(_handle, _read.end, size, NULL, &_read.overlap)) {
- read_completion();
- } else if (GetLastError() != ERROR_IO_PENDING) {
- return handle_error();
- }
- }
- ret = _read.bytes;
- _read.bytes = 0;
- return ret;
-}
-
-void VirtioVDIPort::read_completion()
-{
- DWORD bytes;
-
- if (!GetOverlappedResult(_handle, &_read.overlap, &bytes, FALSE) &&
- GetLastError() != ERROR_MORE_DATA) {
- vd_printf("GetOverlappedResult failed: %u", GetLastError());
- return;
- }
- _read.end = _read.ring + (_read.end - _read.ring + bytes) % BUF_SIZE;
- _read.bytes = bytes;
- _read.pending = false;
-}
+}
+
+bool VirtioVDIPort::init()
+{
+ _handle = CreateFile(VIOSERIAL_PORT_PATH, GENERIC_READ | GENERIC_WRITE , 0, NULL,
+ OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+ if (_handle == INVALID_HANDLE_VALUE) {
+ vd_printf("CreateFile() %s failed: %u", VIOSERIAL_PORT_PATH, GetLastError());
+ return false;
+ }
+ _write.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (_write.overlap.hEvent == NULL) {
+ vd_printf("CreateEvent() failed: %u", GetLastError());
+ return false;
+ }
+ _read.overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (_read.overlap.hEvent == NULL) {
+ vd_printf("CreateEvent() failed: %u", GetLastError());
+ return false;
+ }
+ return true;
+}
+
+int VirtioVDIPort::write()
+{
+ int size;
+ int ret;
+
+ //FIXME: return VDI_PORT_NO_DATA
+ if (_write.start == _write.end) {
+ return 0;
+ }
+ if (!_write.pending) {
+ if (_write.start < _write.end) {
+ size = (int)(_write.end - _write.start);
+ } else {
+ size = (int)(&_write.ring[BUF_SIZE] - _write.start);
+ }
+ size = MIN(size, VIOSERIAL_PORT_MAX_WRITE_BYTES);
+ _write.pending = true;
+ if (WriteFile(_handle, _write.start, size, NULL, &_write.overlap)) {
+ write_completion();
+ } if (GetLastError() != ERROR_IO_PENDING) {
+ return handle_error();
+ }
+ }
+ ret = _write.bytes;
+ _write.bytes = 0;
+ return ret;
+}
+
+void VirtioVDIPort::write_completion()
+{
+ DWORD bytes;
+
+ if (!_write.pending) {
+ return;
+ }
+ if (!GetOverlappedResult(_handle, &_write.overlap, &bytes, FALSE)) {
+ vd_printf("GetOverlappedResult failed: %u", GetLastError());
+ return;
+ }
+ _write.start = _write.ring + (_write.start - _write.ring + bytes) % BUF_SIZE;
+ _write.bytes = bytes;
+ _write.pending = false;
+}
+
+int VirtioVDIPort::read()
+{
+ int size;
+ int ret;
+
+ if (!_read.pending) {
+ //FIXME: read_ring_continuous_remaining_size? return VDI_PORT_BUFFER_FULL
+ if ((_read.end - _read.ring + 1) % BUF_SIZE == _read.start - _read.ring) {
+ vd_printf("DEBUG: buffer full");
+ return 0;
+ }
+ if (_read.start == _read.end) {
+ _read.start = _read.end = _read.ring;
+ }
+ if (_read.start <= _read.end) {
+ size = MIN(BUF_SIZE - 1, (int)(&_read.ring[BUF_SIZE] - _read.end));
+ } else {
+ size = (int)(_read.start - _read.end - 1);
+ }
+ _read.pending = true;
+ if (ReadFile(_handle, _read.end, size, NULL, &_read.overlap)) {
+ read_completion();
+ } else if (GetLastError() != ERROR_IO_PENDING) {
+ return handle_error();
+ }
+ }
+ ret = _read.bytes;
+ _read.bytes = 0;
+ return ret;
+}
+
+void VirtioVDIPort::read_completion()
+{
+ DWORD bytes;
+
+ if (!GetOverlappedResult(_handle, &_read.overlap, &bytes, FALSE) &&
+ GetLastError() != ERROR_MORE_DATA) {
+ vd_printf("GetOverlappedResult failed: %u", GetLastError());
+ return;
+ }
+ _read.end = _read.ring + (_read.end - _read.ring + bytes) % BUF_SIZE;
+ _read.bytes = bytes;
+ _read.pending = false;
+}
diff --git a/vdservice/virtio_vdi_port.h b/vdservice/virtio_vdi_port.h
index 04d3412..15b6811 100644
--- a/vdservice/virtio_vdi_port.h
+++ b/vdservice/virtio_vdi_port.h
@@ -16,7 +16,7 @@ public:
virtual const char *name() { return "VirtioVDIPort"; }
virtual bool init();
virtual unsigned get_num_events() { return VIRTIO_VDI_PORT_EVENT_COUNT; }
- virtual void fill_events(HANDLE *handle);
+ virtual void fill_events(HANDLE* handles);
virtual void handle_event(int event);
virtual int write();
virtual int read();
@@ -30,4 +30,4 @@ private:
HANDLE _handle;
};
-#endif //_H_VIRTIO_VDI_PORT \ No newline at end of file
+#endif //_H_VIRTIO_VDI_PORT