Statistics
| Branch: | Revision:

root / util / oslib-win32.c @ 13401ba0

History | View | Annotate | Download (5.5 kB)

1 c1b0b93b Jes Sorensen
/*
2 c1b0b93b Jes Sorensen
 * os-win32.c
3 c1b0b93b Jes Sorensen
 *
4 c1b0b93b Jes Sorensen
 * Copyright (c) 2003-2008 Fabrice Bellard
5 c1b0b93b Jes Sorensen
 * Copyright (c) 2010 Red Hat, Inc.
6 c1b0b93b Jes Sorensen
 *
7 c1b0b93b Jes Sorensen
 * QEMU library functions for win32 which are shared between QEMU and
8 c1b0b93b Jes Sorensen
 * the QEMU tools.
9 c1b0b93b Jes Sorensen
 *
10 c1b0b93b Jes Sorensen
 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 c1b0b93b Jes Sorensen
 * of this software and associated documentation files (the "Software"), to deal
12 c1b0b93b Jes Sorensen
 * in the Software without restriction, including without limitation the rights
13 c1b0b93b Jes Sorensen
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 c1b0b93b Jes Sorensen
 * copies of the Software, and to permit persons to whom the Software is
15 c1b0b93b Jes Sorensen
 * furnished to do so, subject to the following conditions:
16 c1b0b93b Jes Sorensen
 *
17 c1b0b93b Jes Sorensen
 * The above copyright notice and this permission notice shall be included in
18 c1b0b93b Jes Sorensen
 * all copies or substantial portions of the Software.
19 c1b0b93b Jes Sorensen
 *
20 c1b0b93b Jes Sorensen
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 c1b0b93b Jes Sorensen
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 c1b0b93b Jes Sorensen
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 c1b0b93b Jes Sorensen
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 c1b0b93b Jes Sorensen
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 c1b0b93b Jes Sorensen
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 c1b0b93b Jes Sorensen
 * THE SOFTWARE.
27 c1b0b93b Jes Sorensen
 */
28 c1b0b93b Jes Sorensen
#include <windows.h>
29 e2ea3515 Laszlo Ersek
#include <glib.h>
30 e2ea3515 Laszlo Ersek
#include <stdlib.h>
31 c1b0b93b Jes Sorensen
#include "config-host.h"
32 9c17d615 Paolo Bonzini
#include "sysemu/sysemu.h"
33 1de7afc9 Paolo Bonzini
#include "qemu/main-loop.h"
34 c1b0b93b Jes Sorensen
#include "trace.h"
35 1de7afc9 Paolo Bonzini
#include "qemu/sockets.h"
36 c1b0b93b Jes Sorensen
37 e2ea3515 Laszlo Ersek
/* this must come after including "trace.h" */
38 e2ea3515 Laszlo Ersek
#include <shlobj.h>
39 e2ea3515 Laszlo Ersek
40 b152aa84 Jes Sorensen
void *qemu_oom_check(void *ptr)
41 c1b0b93b Jes Sorensen
{
42 c1b0b93b Jes Sorensen
    if (ptr == NULL) {
43 c1b0b93b Jes Sorensen
        fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
44 c1b0b93b Jes Sorensen
        abort();
45 c1b0b93b Jes Sorensen
    }
46 c1b0b93b Jes Sorensen
    return ptr;
47 c1b0b93b Jes Sorensen
}
48 c1b0b93b Jes Sorensen
49 c1b0b93b Jes Sorensen
void *qemu_memalign(size_t alignment, size_t size)
50 c1b0b93b Jes Sorensen
{
51 c1b0b93b Jes Sorensen
    void *ptr;
52 c1b0b93b Jes Sorensen
53 c1b0b93b Jes Sorensen
    if (!size) {
54 c1b0b93b Jes Sorensen
        abort();
55 c1b0b93b Jes Sorensen
    }
56 b152aa84 Jes Sorensen
    ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
57 c1b0b93b Jes Sorensen
    trace_qemu_memalign(alignment, size, ptr);
58 c1b0b93b Jes Sorensen
    return ptr;
59 c1b0b93b Jes Sorensen
}
60 c1b0b93b Jes Sorensen
61 6eebf958 Paolo Bonzini
void *qemu_anon_ram_alloc(size_t size)
62 c1b0b93b Jes Sorensen
{
63 c1b0b93b Jes Sorensen
    void *ptr;
64 c1b0b93b Jes Sorensen
65 c1b0b93b Jes Sorensen
    /* FIXME: this is not exactly optimal solution since VirtualAlloc
66 c1b0b93b Jes Sorensen
       has 64Kb granularity, but at least it guarantees us that the
67 c1b0b93b Jes Sorensen
       memory is page aligned. */
68 39228250 Markus Armbruster
    ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
69 6eebf958 Paolo Bonzini
    trace_qemu_anon_ram_alloc(size, ptr);
70 c1b0b93b Jes Sorensen
    return ptr;
71 c1b0b93b Jes Sorensen
}
72 c1b0b93b Jes Sorensen
73 c1b0b93b Jes Sorensen
void qemu_vfree(void *ptr)
74 c1b0b93b Jes Sorensen
{
75 c1b0b93b Jes Sorensen
    trace_qemu_vfree(ptr);
76 94c8ff3a Markus Armbruster
    if (ptr) {
77 94c8ff3a Markus Armbruster
        VirtualFree(ptr, 0, MEM_RELEASE);
78 94c8ff3a Markus Armbruster
    }
79 c1b0b93b Jes Sorensen
}
80 9549e764 Jes Sorensen
81 e7a09b92 Paolo Bonzini
void qemu_anon_ram_free(void *ptr, size_t size)
82 e7a09b92 Paolo Bonzini
{
83 e7a09b92 Paolo Bonzini
    trace_qemu_anon_ram_free(ptr, size);
84 e7a09b92 Paolo Bonzini
    if (ptr) {
85 e7a09b92 Paolo Bonzini
        VirtualFree(ptr, 0, MEM_RELEASE);
86 e7a09b92 Paolo Bonzini
    }
87 e7a09b92 Paolo Bonzini
}
88 e7a09b92 Paolo Bonzini
89 d3e8f957 Stefan Weil
/* FIXME: add proper locking */
90 d3e8f957 Stefan Weil
struct tm *gmtime_r(const time_t *timep, struct tm *result)
91 d3e8f957 Stefan Weil
{
92 d3e8f957 Stefan Weil
    struct tm *p = gmtime(timep);
93 d3e8f957 Stefan Weil
    memset(result, 0, sizeof(*result));
94 d3e8f957 Stefan Weil
    if (p) {
95 d3e8f957 Stefan Weil
        *result = *p;
96 d3e8f957 Stefan Weil
        p = result;
97 d3e8f957 Stefan Weil
    }
98 d3e8f957 Stefan Weil
    return p;
99 d3e8f957 Stefan Weil
}
100 d3e8f957 Stefan Weil
101 d3e8f957 Stefan Weil
/* FIXME: add proper locking */
102 d3e8f957 Stefan Weil
struct tm *localtime_r(const time_t *timep, struct tm *result)
103 d3e8f957 Stefan Weil
{
104 d3e8f957 Stefan Weil
    struct tm *p = localtime(timep);
105 d3e8f957 Stefan Weil
    memset(result, 0, sizeof(*result));
106 d3e8f957 Stefan Weil
    if (p) {
107 d3e8f957 Stefan Weil
        *result = *p;
108 d3e8f957 Stefan Weil
        p = result;
109 d3e8f957 Stefan Weil
    }
110 d3e8f957 Stefan Weil
    return p;
111 d3e8f957 Stefan Weil
}
112 d3e8f957 Stefan Weil
113 f9e8cacc Stefan Hajnoczi
void qemu_set_block(int fd)
114 154b9a0c Paolo Bonzini
{
115 154b9a0c Paolo Bonzini
    unsigned long opt = 0;
116 d3385eb4 Paolo Bonzini
    WSAEventSelect(fd, NULL, 0);
117 154b9a0c Paolo Bonzini
    ioctlsocket(fd, FIONBIO, &opt);
118 154b9a0c Paolo Bonzini
}
119 154b9a0c Paolo Bonzini
120 f9e8cacc Stefan Hajnoczi
void qemu_set_nonblock(int fd)
121 9549e764 Jes Sorensen
{
122 9549e764 Jes Sorensen
    unsigned long opt = 1;
123 9549e764 Jes Sorensen
    ioctlsocket(fd, FIONBIO, &opt);
124 d3385eb4 Paolo Bonzini
    qemu_fd_register(fd);
125 9549e764 Jes Sorensen
}
126 9549e764 Jes Sorensen
127 606600a1 Sebastian Ottlik
int socket_set_fast_reuse(int fd)
128 606600a1 Sebastian Ottlik
{
129 606600a1 Sebastian Ottlik
    /* Enabling the reuse of an endpoint that was used by a socket still in
130 606600a1 Sebastian Ottlik
     * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
131 606600a1 Sebastian Ottlik
     * fast reuse is the default and SO_REUSEADDR does strange things. So we
132 606600a1 Sebastian Ottlik
     * don't have to do anything here. More info can be found at:
133 606600a1 Sebastian Ottlik
     * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
134 606600a1 Sebastian Ottlik
    return 0;
135 606600a1 Sebastian Ottlik
}
136 606600a1 Sebastian Ottlik
137 9549e764 Jes Sorensen
int inet_aton(const char *cp, struct in_addr *ia)
138 9549e764 Jes Sorensen
{
139 9549e764 Jes Sorensen
    uint32_t addr = inet_addr(cp);
140 9549e764 Jes Sorensen
    if (addr == 0xffffffff) {
141 9549e764 Jes Sorensen
        return 0;
142 9549e764 Jes Sorensen
    }
143 9549e764 Jes Sorensen
    ia->s_addr = addr;
144 9549e764 Jes Sorensen
    return 1;
145 9549e764 Jes Sorensen
}
146 9549e764 Jes Sorensen
147 9549e764 Jes Sorensen
void qemu_set_cloexec(int fd)
148 9549e764 Jes Sorensen
{
149 9549e764 Jes Sorensen
}
150 dc786bc9 Jes Sorensen
151 dc786bc9 Jes Sorensen
/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
152 dc786bc9 Jes Sorensen
#define _W32_FT_OFFSET (116444736000000000ULL)
153 dc786bc9 Jes Sorensen
154 dc786bc9 Jes Sorensen
int qemu_gettimeofday(qemu_timeval *tp)
155 dc786bc9 Jes Sorensen
{
156 dc786bc9 Jes Sorensen
  union {
157 dc786bc9 Jes Sorensen
    unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
158 dc786bc9 Jes Sorensen
    FILETIME ft;
159 dc786bc9 Jes Sorensen
  }  _now;
160 dc786bc9 Jes Sorensen
161 dc786bc9 Jes Sorensen
  if(tp) {
162 dc786bc9 Jes Sorensen
      GetSystemTimeAsFileTime (&_now.ft);
163 dc786bc9 Jes Sorensen
      tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
164 dc786bc9 Jes Sorensen
      tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
165 dc786bc9 Jes Sorensen
  }
166 dc786bc9 Jes Sorensen
  /* Always return 0 as per Open Group Base Specifications Issue 6.
167 dc786bc9 Jes Sorensen
     Do not set errno on error.  */
168 dc786bc9 Jes Sorensen
  return 0;
169 dc786bc9 Jes Sorensen
}
170 cbcfa041 Paolo Bonzini
171 cbcfa041 Paolo Bonzini
int qemu_get_thread_id(void)
172 cbcfa041 Paolo Bonzini
{
173 cbcfa041 Paolo Bonzini
    return GetCurrentThreadId();
174 cbcfa041 Paolo Bonzini
}
175 e2ea3515 Laszlo Ersek
176 e2ea3515 Laszlo Ersek
char *
177 e2ea3515 Laszlo Ersek
qemu_get_local_state_pathname(const char *relative_pathname)
178 e2ea3515 Laszlo Ersek
{
179 e2ea3515 Laszlo Ersek
    HRESULT result;
180 e2ea3515 Laszlo Ersek
    char base_path[MAX_PATH+1] = "";
181 e2ea3515 Laszlo Ersek
182 e2ea3515 Laszlo Ersek
    result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
183 e2ea3515 Laszlo Ersek
                             /* SHGFP_TYPE_CURRENT */ 0, base_path);
184 e2ea3515 Laszlo Ersek
    if (result != S_OK) {
185 e2ea3515 Laszlo Ersek
        /* misconfigured environment */
186 e2ea3515 Laszlo Ersek
        g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
187 e2ea3515 Laszlo Ersek
        abort();
188 e2ea3515 Laszlo Ersek
    }
189 e2ea3515 Laszlo Ersek
    return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
190 e2ea3515 Laszlo Ersek
                           relative_pathname);
191 e2ea3515 Laszlo Ersek
}
192 13401ba0 Stefan Hajnoczi
193 13401ba0 Stefan Hajnoczi
void qemu_set_tty_echo(int fd, bool echo)
194 13401ba0 Stefan Hajnoczi
{
195 13401ba0 Stefan Hajnoczi
    HANDLE handle = (HANDLE)_get_osfhandle(fd);
196 13401ba0 Stefan Hajnoczi
    DWORD dwMode = 0;
197 13401ba0 Stefan Hajnoczi
198 13401ba0 Stefan Hajnoczi
    if (handle == INVALID_HANDLE_VALUE) {
199 13401ba0 Stefan Hajnoczi
        return;
200 13401ba0 Stefan Hajnoczi
    }
201 13401ba0 Stefan Hajnoczi
202 13401ba0 Stefan Hajnoczi
    GetConsoleMode(handle, &dwMode);
203 13401ba0 Stefan Hajnoczi
204 13401ba0 Stefan Hajnoczi
    if (echo) {
205 13401ba0 Stefan Hajnoczi
        SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
206 13401ba0 Stefan Hajnoczi
    } else {
207 13401ba0 Stefan Hajnoczi
        SetConsoleMode(handle,
208 13401ba0 Stefan Hajnoczi
                       dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
209 13401ba0 Stefan Hajnoczi
    }
210 13401ba0 Stefan Hajnoczi
}