Revision f331110f vl.c

b/vl.c
1713 1713

  
1714 1714
#endif /* !defined(_WIN32) */
1715 1715

  
1716
#ifdef _WIN32
1717
typedef struct {
1718
    IOCanRWHandler *fd_can_read; 
1719
    IOReadHandler *fd_read;
1720
    void *win_opaque;
1721
    int max_size;
1722
    HANDLE hcom, hrecv, hsend;
1723
    OVERLAPPED orecv, osend;
1724
    BOOL fpipe;
1725
    DWORD len;
1726
} WinCharState;
1727

  
1728
#define NSENDBUF 2048
1729
#define NRECVBUF 2048
1730
#define MAXCONNECT 1
1731
#define NTIMEOUT 5000
1732

  
1733
static int win_chr_poll(void *opaque);
1734
static int win_chr_pipe_poll(void *opaque);
1735

  
1736
static void win_chr_close2(WinCharState *s)
1737
{
1738
    if (s->hsend) {
1739
        CloseHandle(s->hsend);
1740
        s->hsend = NULL;
1741
    }
1742
    if (s->hrecv) {
1743
        CloseHandle(s->hrecv);
1744
        s->hrecv = NULL;
1745
    }
1746
    if (s->hcom) {
1747
        CloseHandle(s->hcom);
1748
        s->hcom = NULL;
1749
    }
1750
    if (s->fpipe)
1751
        qemu_del_polling_cb(win_chr_pipe_poll, s);
1752
    else
1753
        qemu_del_polling_cb(win_chr_poll, s);
1754
}
1755

  
1756
static void win_chr_close(CharDriverState *chr)
1757
{
1758
    WinCharState *s = chr->opaque;
1759
    win_chr_close2(s);
1760
}
1761

  
1762
static int win_chr_init(WinCharState *s, const char *filename)
1763
{
1764
    COMMCONFIG comcfg;
1765
    COMMTIMEOUTS cto = { 0, 0, 0, 0, 0};
1766
    COMSTAT comstat;
1767
    DWORD size;
1768
    DWORD err;
1769
    
1770
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
1771
    if (!s->hsend) {
1772
        fprintf(stderr, "Failed CreateEvent\n");
1773
        goto fail;
1774
    }
1775
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
1776
    if (!s->hrecv) {
1777
        fprintf(stderr, "Failed CreateEvent\n");
1778
        goto fail;
1779
    }
1780

  
1781
    s->hcom = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL,
1782
                      OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
1783
    if (s->hcom == INVALID_HANDLE_VALUE) {
1784
        fprintf(stderr, "Failed CreateFile (%lu)\n", GetLastError());
1785
        s->hcom = NULL;
1786
        goto fail;
1787
    }
1788
    
1789
    if (!SetupComm(s->hcom, NRECVBUF, NSENDBUF)) {
1790
        fprintf(stderr, "Failed SetupComm\n");
1791
        goto fail;
1792
    }
1793
    
1794
    ZeroMemory(&comcfg, sizeof(COMMCONFIG));
1795
    size = sizeof(COMMCONFIG);
1796
    GetDefaultCommConfig(filename, &comcfg, &size);
1797
    comcfg.dcb.DCBlength = sizeof(DCB);
1798
    CommConfigDialog(filename, NULL, &comcfg);
1799

  
1800
    if (!SetCommState(s->hcom, &comcfg.dcb)) {
1801
        fprintf(stderr, "Failed SetCommState\n");
1802
        goto fail;
1803
    }
1804

  
1805
    if (!SetCommMask(s->hcom, EV_ERR)) {
1806
        fprintf(stderr, "Failed SetCommMask\n");
1807
        goto fail;
1808
    }
1809

  
1810
    cto.ReadIntervalTimeout = MAXDWORD;
1811
    if (!SetCommTimeouts(s->hcom, &cto)) {
1812
        fprintf(stderr, "Failed SetCommTimeouts\n");
1813
        goto fail;
1814
    }
1815
    
1816
    if (!ClearCommError(s->hcom, &err, &comstat)) {
1817
        fprintf(stderr, "Failed ClearCommError\n");
1818
        goto fail;
1819
    }
1820
    qemu_add_polling_cb(win_chr_poll, s);
1821
    return 0;
1822

  
1823
 fail:
1824
    win_chr_close2(s);
1825
    return -1;
1826
}
1827

  
1828
static int win_chr_write(CharDriverState *chr, const uint8_t *buf, int len1)
1829
{
1830
    WinCharState *s = chr->opaque;
1831
    DWORD len, ret, size, err;
1832

  
1833
    len = len1;
1834
    ZeroMemory(&s->osend, sizeof(s->osend));
1835
    s->osend.hEvent = s->hsend;
1836
    while (len > 0) {
1837
        if (s->hsend)
1838
            ret = WriteFile(s->hcom, buf, len, &size, &s->osend);
1839
        else
1840
            ret = WriteFile(s->hcom, buf, len, &size, NULL);
1841
        if (!ret) {
1842
            err = GetLastError();
1843
            if (err == ERROR_IO_PENDING) {
1844
                ret = GetOverlappedResult(s->hcom, &s->osend, &size, TRUE);
1845
                if (ret) {
1846
                    buf += size;
1847
                    len -= size;
1848
                } else {
1849
                    break;
1850
                }
1851
            } else {
1852
                break;
1853
            }
1854
        } else {
1855
            buf += size;
1856
            len -= size;
1857
        }
1858
    }
1859
    return len1 - len;
1860
}
1861

  
1862
static int win_chr_read_poll(WinCharState *s)
1863
{
1864
    s->max_size = s->fd_can_read(s->win_opaque);
1865
    return s->max_size;
1866
}
1867
            
1868
static void win_chr_readfile(WinCharState *s)
1869
{
1870
    int ret, err;
1871
    uint8_t buf[1024];
1872
    DWORD size;
1873
    
1874
    ZeroMemory(&s->orecv, sizeof(s->orecv));
1875
    s->orecv.hEvent = s->hrecv;
1876
    ret = ReadFile(s->hcom, buf, s->len, &size, &s->orecv);
1877
    if (!ret) {
1878
        err = GetLastError();
1879
        if (err == ERROR_IO_PENDING) {
1880
            ret = GetOverlappedResult(s->hcom, &s->orecv, &size, TRUE);
1881
        }
1882
    }
1883

  
1884
    if (size > 0) {
1885
        s->fd_read(s->win_opaque, buf, size);
1886
    }
1887
}
1888

  
1889
static void win_chr_read(WinCharState *s)
1890
{
1891
    if (s->len > s->max_size)
1892
        s->len = s->max_size;
1893
    if (s->len == 0)
1894
        return;
1895
    
1896
    win_chr_readfile(s);
1897
}
1898

  
1899
static int win_chr_poll(void *opaque)
1900
{
1901
    WinCharState *s = opaque;
1902
    COMSTAT status;
1903
    DWORD comerr;
1904
    
1905
    ClearCommError(s->hcom, &comerr, &status);
1906
    if (status.cbInQue > 0) {
1907
        s->len = status.cbInQue;
1908
        win_chr_read_poll(s);
1909
        win_chr_read(s);
1910
        return 1;
1911
    }
1912
    return 0;
1913
}
1914

  
1915
static void win_chr_add_read_handler(CharDriverState *chr, 
1916
                                    IOCanRWHandler *fd_can_read, 
1917
                                    IOReadHandler *fd_read, void *opaque)
1918
{
1919
    WinCharState *s = chr->opaque;
1920

  
1921
    s->fd_can_read = fd_can_read;
1922
    s->fd_read = fd_read;
1923
    s->win_opaque = opaque;
1924
}
1925

  
1926
CharDriverState *qemu_chr_open_win(const char *filename)
1927
{
1928
    CharDriverState *chr;
1929
    WinCharState *s;
1930
    
1931
    chr = qemu_mallocz(sizeof(CharDriverState));
1932
    if (!chr)
1933
        return NULL;
1934
    s = qemu_mallocz(sizeof(WinCharState));
1935
    if (!s) {
1936
        free(chr);
1937
        return NULL;
1938
    }
1939
    chr->opaque = s;
1940
    chr->chr_write = win_chr_write;
1941
    chr->chr_add_read_handler = win_chr_add_read_handler;
1942
    chr->chr_close = win_chr_close;
1943

  
1944
    if (win_chr_init(s, filename) < 0) {
1945
        free(s);
1946
        free(chr);
1947
        return NULL;
1948
    }
1949
    return chr;
1950
}
1951

  
1952
static int win_chr_pipe_poll(void *opaque)
1953
{
1954
    WinCharState *s = opaque;
1955
    DWORD size;
1956

  
1957
    PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
1958
    if (size > 0) {
1959
        s->len = size;
1960
        win_chr_read_poll(s);
1961
        win_chr_read(s);
1962
        return 1;
1963
    }
1964
    return 0;
1965
}
1966

  
1967
static int win_chr_pipe_init(WinCharState *s, const char *filename)
1968
{
1969
    OVERLAPPED ov;
1970
    int ret;
1971
    DWORD size;
1972
    char openname[256];
1973
    
1974
    s->fpipe = TRUE;
1975

  
1976
    s->hsend = CreateEvent(NULL, TRUE, FALSE, NULL);
1977
    if (!s->hsend) {
1978
        fprintf(stderr, "Failed CreateEvent\n");
1979
        goto fail;
1980
    }
1981
    s->hrecv = CreateEvent(NULL, TRUE, FALSE, NULL);
1982
    if (!s->hrecv) {
1983
        fprintf(stderr, "Failed CreateEvent\n");
1984
        goto fail;
1985
    }
1986
    
1987
    snprintf(openname, sizeof(openname), "\\\\.\\pipe\\%s", filename);
1988
    s->hcom = CreateNamedPipe(openname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
1989
                              PIPE_TYPE_BYTE | PIPE_READMODE_BYTE |
1990
                              PIPE_WAIT,
1991
                              MAXCONNECT, NSENDBUF, NRECVBUF, NTIMEOUT, NULL);
1992
    if (s->hcom == INVALID_HANDLE_VALUE) {
1993
        fprintf(stderr, "Failed CreateNamedPipe (%lu)\n", GetLastError());
1994
        s->hcom = NULL;
1995
        goto fail;
1996
    }
1997

  
1998
    ZeroMemory(&ov, sizeof(ov));
1999
    ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
2000
    ret = ConnectNamedPipe(s->hcom, &ov);
2001
    if (ret) {
2002
        fprintf(stderr, "Failed ConnectNamedPipe\n");
2003
        goto fail;
2004
    }
2005

  
2006
    ret = GetOverlappedResult(s->hcom, &ov, &size, TRUE);
2007
    if (!ret) {
2008
        fprintf(stderr, "Failed GetOverlappedResult\n");
2009
        if (ov.hEvent) {
2010
            CloseHandle(ov.hEvent);
2011
            ov.hEvent = NULL;
2012
        }
2013
        goto fail;
2014
    }
2015

  
2016
    if (ov.hEvent) {
2017
        CloseHandle(ov.hEvent);
2018
        ov.hEvent = NULL;
2019
    }
2020
    qemu_add_polling_cb(win_chr_pipe_poll, s);
2021
    return 0;
2022

  
2023
 fail:
2024
    win_chr_close2(s);
2025
    return -1;
2026
}
2027

  
2028

  
2029
CharDriverState *qemu_chr_open_win_pipe(const char *filename)
2030
{
2031
    CharDriverState *chr;
2032
    WinCharState *s;
2033

  
2034
    chr = qemu_mallocz(sizeof(CharDriverState));
2035
    if (!chr)
2036
        return NULL;
2037
    s = qemu_mallocz(sizeof(WinCharState));
2038
    if (!s) {
2039
        free(chr);
2040
        return NULL;
2041
    }
2042
    chr->opaque = s;
2043
    chr->chr_write = win_chr_write;
2044
    chr->chr_add_read_handler = win_chr_add_read_handler;
2045
    chr->chr_close = win_chr_close;
2046
    
2047
    if (win_chr_pipe_init(s, filename) < 0) {
2048
        free(s);
2049
        free(chr);
2050
        return NULL;
2051
    }
2052
    return chr;
2053
}
2054

  
2055
CharDriverState *qemu_chr_open_win_file(HANDLE fd_out)
2056
{
2057
    CharDriverState *chr;
2058
    WinCharState *s;
2059

  
2060
    chr = qemu_mallocz(sizeof(CharDriverState));
2061
    if (!chr)
2062
        return NULL;
2063
    s = qemu_mallocz(sizeof(WinCharState));
2064
    if (!s) {
2065
        free(chr);
2066
        return NULL;
2067
    }
2068
    s->hcom = fd_out;
2069
    chr->opaque = s;
2070
    chr->chr_write = win_chr_write;
2071
    chr->chr_add_read_handler = win_chr_add_read_handler;
2072
    return chr;
2073
}
2074
    
2075
CharDriverState *qemu_chr_open_win_file_out(const char *file_out)
2076
{
2077
    HANDLE fd_out;
2078
    
2079
    fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,
2080
                        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2081
    if (fd_out == INVALID_HANDLE_VALUE)
2082
        return NULL;
2083

  
2084
    return qemu_chr_open_win_file(fd_out);
2085
}
2086
#endif
2087

  
1716 2088
CharDriverState *qemu_chr_open(const char *filename)
1717 2089
{
1718
#ifndef _WIN32
1719 2090
    const char *p;
1720
#endif
1721 2091

  
1722 2092
    if (!strcmp(filename, "vc")) {
1723 2093
        return text_console_init(&display_state);
......
1743 2113
        return qemu_chr_open_tty(filename);
1744 2114
    } else 
1745 2115
#endif
2116
#ifdef _WIN32
2117
    if (strstart(filename, "COM", NULL)) {
2118
        return qemu_chr_open_win(filename);
2119
    } else
2120
    if (strstart(filename, "pipe:", &p)) {
2121
        return qemu_chr_open_win_pipe(p);
2122
    } else
2123
    if (strstart(filename, "file:", &p)) {
2124
        return qemu_chr_open_win_file_out(p);
2125
    }
2126
#endif
1746 2127
    {
1747 2128
        return NULL;
1748 2129
    }
1749 2130
}
1750 2131

  
2132
void qemu_chr_close(CharDriverState *chr)
2133
{
2134
    if (chr->chr_close)
2135
        chr->chr_close(chr);
2136
}
2137

  
1751 2138
/***********************************************************/
1752 2139
/* network device redirectors */
1753 2140

  
......
3090 3477
}
3091 3478

  
3092 3479
/***********************************************************/
3480
/* Polling handling */
3481

  
3482
typedef struct PollingEntry {
3483
    PollingFunc *func;
3484
    void *opaque;
3485
    struct PollingEntry *next;
3486
} PollingEntry;
3487

  
3488
static PollingEntry *first_polling_entry;
3489

  
3490
int qemu_add_polling_cb(PollingFunc *func, void *opaque)
3491
{
3492
    PollingEntry **ppe, *pe;
3493
    pe = qemu_mallocz(sizeof(PollingEntry));
3494
    if (!pe)
3495
        return -1;
3496
    pe->func = func;
3497
    pe->opaque = opaque;
3498
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
3499
    *ppe = pe;
3500
    return 0;
3501
}
3502

  
3503
void qemu_del_polling_cb(PollingFunc *func, void *opaque)
3504
{
3505
    PollingEntry **ppe, *pe;
3506
    for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next) {
3507
        pe = *ppe;
3508
        if (pe->func == func && pe->opaque == opaque) {
3509
            *ppe = pe->next;
3510
            qemu_free(pe);
3511
            break;
3512
        }
3513
    }
3514
}
3515

  
3516
/***********************************************************/
3093 3517
/* savevm/loadvm support */
3094 3518

  
3095 3519
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
......
3955 4379
    fd_set rfds, wfds;
3956 4380
    int ret, nfds;
3957 4381
    struct timeval tv;
4382
    PollingEntry *pe;
4383

  
3958 4384

  
4385
    /* XXX: need to suppress polling by better using win32 events */
4386
    ret = 0;
4387
    for(pe = first_polling_entry; pe != NULL; pe = pe->next) {
4388
        ret |= pe->func(pe->opaque);
4389
    }
3959 4390
#ifdef _WIN32
3960
    /* XXX: see how to merge it with the select. The constraint is
3961
       that the select must be interrupted by the timer */
3962
    if (timeout > 0)
4391
    if (ret == 0 && timeout > 0) {
3963 4392
        Sleep(timeout);
4393
    }
3964 4394
#endif
3965 4395
    /* poll any events */
3966 4396
    /* XXX: separate device handlers from system ones */

Also available in: Unified diff