diff options
Diffstat (limited to 'chardev/char-win.c')
-rw-r--r-- | chardev/char-win.c | 95 |
1 files changed, 36 insertions, 59 deletions
diff --git a/chardev/char-win.c b/chardev/char-win.c index e4b6957ded..05518e0958 100644 --- a/chardev/char-win.c +++ b/chardev/char-win.c @@ -24,23 +24,30 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "qapi/error.h" -#include "char-win.h" +#include "chardev/char-win.h" -static void win_chr_readfile(Chardev *chr) +static void win_chr_read(Chardev *chr, DWORD len) { WinChardev *s = WIN_CHARDEV(chr); - + int max_size = qemu_chr_be_can_write(chr); int ret, err; uint8_t buf[CHR_READ_BUF_LEN]; DWORD size; + if (len > max_size) { + len = max_size; + } + if (len == 0) { + return; + } + ZeroMemory(&s->orecv, sizeof(s->orecv)); s->orecv.hEvent = s->hrecv; - ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv); + ret = ReadFile(s->file, buf, len, &size, &s->orecv); if (!ret) { err = GetLastError(); if (err == ERROR_IO_PENDING) { - ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE); + ret = GetOverlappedResult(s->file, &s->orecv, &size, TRUE); } } @@ -49,46 +56,22 @@ static void win_chr_readfile(Chardev *chr) } } -static void win_chr_read(Chardev *chr) -{ - WinChardev *s = WIN_CHARDEV(chr); - - if (s->len > s->max_size) { - s->len = s->max_size; - } - if (s->len == 0) { - return; - } - - win_chr_readfile(chr); -} - -static int win_chr_read_poll(Chardev *chr) -{ - WinChardev *s = WIN_CHARDEV(chr); - - s->max_size = qemu_chr_be_can_write(chr); - return s->max_size; -} - -static int win_chr_poll(void *opaque) +static int win_chr_serial_poll(void *opaque) { Chardev *chr = CHARDEV(opaque); WinChardev *s = WIN_CHARDEV(opaque); COMSTAT status; DWORD comerr; - ClearCommError(s->hcom, &comerr, &status); + ClearCommError(s->file, &comerr, &status); if (status.cbInQue > 0) { - s->len = status.cbInQue; - win_chr_read_poll(chr); - win_chr_read(chr); + win_chr_read(chr, status.cbInQue); return 1; } return 0; } -int win_chr_init(Chardev *chr, const char *filename, Error **errp) +int win_chr_serial_init(Chardev *chr, const char *filename, Error **errp) { WinChardev *s = WIN_CHARDEV(chr); COMMCONFIG comcfg; @@ -108,15 +91,15 @@ int win_chr_init(Chardev *chr, const char *filename, Error **errp) goto fail; } - s->hcom = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, + s->file = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); - if (s->hcom == INVALID_HANDLE_VALUE) { + if (s->file == INVALID_HANDLE_VALUE) { error_setg(errp, "Failed CreateFile (%lu)", GetLastError()); - s->hcom = NULL; + s->file = NULL; goto fail; } - if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) { + if (!SetupComm(s->file, NRECVBUF, NSENDBUF)) { error_setg(errp, "Failed SetupComm"); goto fail; } @@ -127,27 +110,27 @@ int win_chr_init(Chardev *chr, const char *filename, Error **errp) comcfg.dcb.DCBlength = sizeof(DCB); CommConfigDialog(filename, NULL, &comcfg); - if (!SetCommState(s->hcom, &comcfg.dcb)) { + if (!SetCommState(s->file, &comcfg.dcb)) { error_setg(errp, "Failed SetCommState"); goto fail; } - if (!SetCommMask(s->hcom, EV_ERR)) { + if (!SetCommMask(s->file, EV_ERR)) { error_setg(errp, "Failed SetCommMask"); goto fail; } cto.ReadIntervalTimeout = MAXDWORD; - if (!SetCommTimeouts(s->hcom, &cto)) { + if (!SetCommTimeouts(s->file, &cto)) { error_setg(errp, "Failed SetCommTimeouts"); goto fail; } - if (!ClearCommError(s->hcom, &err, &comstat)) { + if (!ClearCommError(s->file, &err, &comstat)) { error_setg(errp, "Failed ClearCommError"); goto fail; } - qemu_add_polling_cb(win_chr_poll, chr); + qemu_add_polling_cb(win_chr_serial_poll, chr); return 0; fail: @@ -160,11 +143,9 @@ int win_chr_pipe_poll(void *opaque) WinChardev *s = WIN_CHARDEV(opaque); DWORD size; - PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL); + PeekNamedPipe(s->file, NULL, 0, NULL, &size, NULL); if (size > 0) { - s->len = size; - win_chr_read_poll(chr); - win_chr_read(chr); + win_chr_read(chr, size); return 1; } return 0; @@ -181,14 +162,14 @@ static int win_chr_write(Chardev *chr, const uint8_t *buf, int len1) s->osend.hEvent = s->hsend; while (len > 0) { if (s->hsend) { - ret = WriteFile(s->hcom, buf, len, &size, &s->osend); + ret = WriteFile(s->file, buf, len, &size, &s->osend); } else { - ret = WriteFile(s->hcom, buf, len, &size, NULL); + ret = WriteFile(s->file, buf, len, &size, NULL); } if (!ret) { err = GetLastError(); if (err == ERROR_IO_PENDING) { - ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE); + ret = GetOverlappedResult(s->file, &s->osend, &size, TRUE); if (ret) { buf += size; len -= size; @@ -211,34 +192,30 @@ static void char_win_finalize(Object *obj) Chardev *chr = CHARDEV(obj); WinChardev *s = WIN_CHARDEV(chr); - if (s->skip_free) { - return; - } - if (s->hsend) { CloseHandle(s->hsend); } if (s->hrecv) { CloseHandle(s->hrecv); } - if (s->hcom) { - CloseHandle(s->hcom); + if (!s->keep_open && s->file) { + CloseHandle(s->file); } if (s->fpipe) { qemu_del_polling_cb(win_chr_pipe_poll, chr); } else { - qemu_del_polling_cb(win_chr_poll, chr); + qemu_del_polling_cb(win_chr_serial_poll, chr); } qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } -void qemu_chr_open_win_file(Chardev *chr, HANDLE fd_out) +void win_chr_set_file(Chardev *chr, HANDLE file, bool keep_open) { WinChardev *s = WIN_CHARDEV(chr); - s->skip_free = true; - s->hcom = fd_out; + s->keep_open = keep_open; + s->file = file; } static void char_win_class_init(ObjectClass *oc, void *data) |