xref: /openbmc/qemu/util/oslib-win32.c (revision 116694c3)
1 /*
2  * os-win32.c
3  *
4  * Copyright (c) 2003-2008 Fabrice Bellard
5  * Copyright (c) 2010 Red Hat, Inc.
6  *
7  * QEMU library functions for win32 which are shared between QEMU and
8  * the QEMU tools.
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  * THE SOFTWARE.
27  *
28  * The implementation of g_poll (functions poll_rest, g_poll) at the end of
29  * this file are based on code from GNOME glib-2 and use a different license,
30  * see the license comment there.
31  */
32 #include <windows.h>
33 #include <glib.h>
34 #include <stdlib.h>
35 #include "config-host.h"
36 #include "sysemu/sysemu.h"
37 #include "qemu/main-loop.h"
38 #include "trace.h"
39 #include "qemu/sockets.h"
40 
41 /* this must come after including "trace.h" */
42 #include <shlobj.h>
43 
44 void *qemu_oom_check(void *ptr)
45 {
46     if (ptr == NULL) {
47         fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
48         abort();
49     }
50     return ptr;
51 }
52 
53 void *qemu_try_memalign(size_t alignment, size_t size)
54 {
55     void *ptr;
56 
57     if (!size) {
58         abort();
59     }
60     ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
61     trace_qemu_memalign(alignment, size, ptr);
62     return ptr;
63 }
64 
65 void *qemu_memalign(size_t alignment, size_t size)
66 {
67     return qemu_oom_check(qemu_try_memalign(alignment, size));
68 }
69 
70 void *qemu_anon_ram_alloc(size_t size, uint64_t *align)
71 {
72     void *ptr;
73 
74     /* FIXME: this is not exactly optimal solution since VirtualAlloc
75        has 64Kb granularity, but at least it guarantees us that the
76        memory is page aligned. */
77     ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
78     trace_qemu_anon_ram_alloc(size, ptr);
79     return ptr;
80 }
81 
82 void qemu_vfree(void *ptr)
83 {
84     trace_qemu_vfree(ptr);
85     if (ptr) {
86         VirtualFree(ptr, 0, MEM_RELEASE);
87     }
88 }
89 
90 void qemu_anon_ram_free(void *ptr, size_t size)
91 {
92     trace_qemu_anon_ram_free(ptr, size);
93     if (ptr) {
94         VirtualFree(ptr, 0, MEM_RELEASE);
95     }
96 }
97 
98 /* FIXME: add proper locking */
99 struct tm *gmtime_r(const time_t *timep, struct tm *result)
100 {
101     struct tm *p = gmtime(timep);
102     memset(result, 0, sizeof(*result));
103     if (p) {
104         *result = *p;
105         p = result;
106     }
107     return p;
108 }
109 
110 /* FIXME: add proper locking */
111 struct tm *localtime_r(const time_t *timep, struct tm *result)
112 {
113     struct tm *p = localtime(timep);
114     memset(result, 0, sizeof(*result));
115     if (p) {
116         *result = *p;
117         p = result;
118     }
119     return p;
120 }
121 
122 void qemu_set_block(int fd)
123 {
124     unsigned long opt = 0;
125     WSAEventSelect(fd, NULL, 0);
126     ioctlsocket(fd, FIONBIO, &opt);
127 }
128 
129 void qemu_set_nonblock(int fd)
130 {
131     unsigned long opt = 1;
132     ioctlsocket(fd, FIONBIO, &opt);
133     qemu_fd_register(fd);
134 }
135 
136 int socket_set_fast_reuse(int fd)
137 {
138     /* Enabling the reuse of an endpoint that was used by a socket still in
139      * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows
140      * fast reuse is the default and SO_REUSEADDR does strange things. So we
141      * don't have to do anything here. More info can be found at:
142      * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */
143     return 0;
144 }
145 
146 int inet_aton(const char *cp, struct in_addr *ia)
147 {
148     uint32_t addr = inet_addr(cp);
149     if (addr == 0xffffffff) {
150         return 0;
151     }
152     ia->s_addr = addr;
153     return 1;
154 }
155 
156 void qemu_set_cloexec(int fd)
157 {
158 }
159 
160 /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
161 #define _W32_FT_OFFSET (116444736000000000ULL)
162 
163 int qemu_gettimeofday(qemu_timeval *tp)
164 {
165   union {
166     unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
167     FILETIME ft;
168   }  _now;
169 
170   if(tp) {
171       GetSystemTimeAsFileTime (&_now.ft);
172       tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
173       tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
174   }
175   /* Always return 0 as per Open Group Base Specifications Issue 6.
176      Do not set errno on error.  */
177   return 0;
178 }
179 
180 int qemu_get_thread_id(void)
181 {
182     return GetCurrentThreadId();
183 }
184 
185 char *
186 qemu_get_local_state_pathname(const char *relative_pathname)
187 {
188     HRESULT result;
189     char base_path[MAX_PATH+1] = "";
190 
191     result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
192                              /* SHGFP_TYPE_CURRENT */ 0, base_path);
193     if (result != S_OK) {
194         /* misconfigured environment */
195         g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
196         abort();
197     }
198     return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
199                            relative_pathname);
200 }
201 
202 void qemu_set_tty_echo(int fd, bool echo)
203 {
204     HANDLE handle = (HANDLE)_get_osfhandle(fd);
205     DWORD dwMode = 0;
206 
207     if (handle == INVALID_HANDLE_VALUE) {
208         return;
209     }
210 
211     GetConsoleMode(handle, &dwMode);
212 
213     if (echo) {
214         SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
215     } else {
216         SetConsoleMode(handle,
217                        dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
218     }
219 }
220 
221 static char exec_dir[PATH_MAX];
222 
223 void qemu_init_exec_dir(const char *argv0)
224 {
225 
226     char *p;
227     char buf[MAX_PATH];
228     DWORD len;
229 
230     len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
231     if (len == 0) {
232         return;
233     }
234 
235     buf[len] = 0;
236     p = buf + len - 1;
237     while (p != buf && *p != '\\') {
238         p--;
239     }
240     *p = 0;
241     if (access(buf, R_OK) == 0) {
242         pstrcpy(exec_dir, sizeof(exec_dir), buf);
243     }
244 }
245 
246 char *qemu_get_exec_dir(void)
247 {
248     return g_strdup(exec_dir);
249 }
250 
251 /*
252  * The original implementation of g_poll from glib has a problem on Windows
253  * when using timeouts < 10 ms.
254  *
255  * Whenever g_poll is called with timeout < 10 ms, it does a quick poll instead
256  * of wait. This causes significant performance degradation of QEMU.
257  *
258  * The following code is a copy of the original code from glib/gpoll.c
259  * (glib commit 20f4d1820b8d4d0fc4447188e33efffd6d4a88d8 from 2014-02-19).
260  * Some debug code was removed and the code was reformatted.
261  * All other code modifications are marked with 'QEMU'.
262  */
263 
264 /*
265  * gpoll.c: poll(2) abstraction
266  * Copyright 1998 Owen Taylor
267  * Copyright 2008 Red Hat, Inc.
268  *
269  * This library is free software; you can redistribute it and/or
270  * modify it under the terms of the GNU Lesser General Public
271  * License as published by the Free Software Foundation; either
272  * version 2 of the License, or (at your option) any later version.
273  *
274  * This library is distributed in the hope that it will be useful,
275  * but WITHOUT ANY WARRANTY; without even the implied warranty of
276  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
277  * Lesser General Public License for more details.
278  *
279  * You should have received a copy of the GNU Lesser General Public
280  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
281  */
282 
283 static int poll_rest(gboolean poll_msgs, HANDLE *handles, gint nhandles,
284                      GPollFD *fds, guint nfds, gint timeout)
285 {
286     DWORD ready;
287     GPollFD *f;
288     int recursed_result;
289 
290     if (poll_msgs) {
291         /* Wait for either messages or handles
292          * -> Use MsgWaitForMultipleObjectsEx
293          */
294         ready = MsgWaitForMultipleObjectsEx(nhandles, handles, timeout,
295                                             QS_ALLINPUT, MWMO_ALERTABLE);
296 
297         if (ready == WAIT_FAILED) {
298             gchar *emsg = g_win32_error_message(GetLastError());
299             g_warning("MsgWaitForMultipleObjectsEx failed: %s", emsg);
300             g_free(emsg);
301         }
302     } else if (nhandles == 0) {
303         /* No handles to wait for, just the timeout */
304         if (timeout == INFINITE) {
305             ready = WAIT_FAILED;
306         } else {
307             SleepEx(timeout, TRUE);
308             ready = WAIT_TIMEOUT;
309         }
310     } else {
311         /* Wait for just handles
312          * -> Use WaitForMultipleObjectsEx
313          */
314         ready =
315             WaitForMultipleObjectsEx(nhandles, handles, FALSE, timeout, TRUE);
316         if (ready == WAIT_FAILED) {
317             gchar *emsg = g_win32_error_message(GetLastError());
318             g_warning("WaitForMultipleObjectsEx failed: %s", emsg);
319             g_free(emsg);
320         }
321     }
322 
323     if (ready == WAIT_FAILED) {
324         return -1;
325     } else if (ready == WAIT_TIMEOUT || ready == WAIT_IO_COMPLETION) {
326         return 0;
327     } else if (poll_msgs && ready == WAIT_OBJECT_0 + nhandles) {
328         for (f = fds; f < &fds[nfds]; ++f) {
329             if (f->fd == G_WIN32_MSG_HANDLE && f->events & G_IO_IN) {
330                 f->revents |= G_IO_IN;
331             }
332         }
333 
334         /* If we have a timeout, or no handles to poll, be satisfied
335          * with just noticing we have messages waiting.
336          */
337         if (timeout != 0 || nhandles == 0) {
338             return 1;
339         }
340 
341         /* If no timeout and handles to poll, recurse to poll them,
342          * too.
343          */
344         recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
345         return (recursed_result == -1) ? -1 : 1 + recursed_result;
346     } else if (/* QEMU: removed the following unneeded statement which causes
347                 * a compiler warning: ready >= WAIT_OBJECT_0 && */
348                ready < WAIT_OBJECT_0 + nhandles) {
349         for (f = fds; f < &fds[nfds]; ++f) {
350             if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0]) {
351                 f->revents = f->events;
352             }
353         }
354 
355         /* If no timeout and polling several handles, recurse to poll
356          * the rest of them.
357          */
358         if (timeout == 0 && nhandles > 1) {
359             /* Remove the handle that fired */
360             int i;
361             if (ready < nhandles - 1) {
362                 for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++) {
363                     handles[i-1] = handles[i];
364                 }
365             }
366             nhandles--;
367             recursed_result = poll_rest(FALSE, handles, nhandles, fds, nfds, 0);
368             return (recursed_result == -1) ? -1 : 1 + recursed_result;
369         }
370         return 1;
371     }
372 
373     return 0;
374 }
375 
376 gint g_poll(GPollFD *fds, guint nfds, gint timeout)
377 {
378     HANDLE handles[MAXIMUM_WAIT_OBJECTS];
379     gboolean poll_msgs = FALSE;
380     GPollFD *f;
381     gint nhandles = 0;
382     int retval;
383 
384     for (f = fds; f < &fds[nfds]; ++f) {
385         if (f->fd == G_WIN32_MSG_HANDLE && (f->events & G_IO_IN)) {
386             poll_msgs = TRUE;
387         } else if (f->fd > 0) {
388             /* Don't add the same handle several times into the array, as
389              * docs say that is not allowed, even if it actually does seem
390              * to work.
391              */
392             gint i;
393 
394             for (i = 0; i < nhandles; i++) {
395                 if (handles[i] == (HANDLE) f->fd) {
396                     break;
397                 }
398             }
399 
400             if (i == nhandles) {
401                 if (nhandles == MAXIMUM_WAIT_OBJECTS) {
402                     g_warning("Too many handles to wait for!\n");
403                     break;
404                 } else {
405                     handles[nhandles++] = (HANDLE) f->fd;
406                 }
407             }
408         }
409     }
410 
411     for (f = fds; f < &fds[nfds]; ++f) {
412         f->revents = 0;
413     }
414 
415     if (timeout == -1) {
416         timeout = INFINITE;
417     }
418 
419     /* Polling for several things? */
420     if (nhandles > 1 || (nhandles > 0 && poll_msgs)) {
421         /* First check if one or several of them are immediately
422          * available
423          */
424         retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, 0);
425 
426         /* If not, and we have a significant timeout, poll again with
427          * timeout then. Note that this will return indication for only
428          * one event, or only for messages. We ignore timeouts less than
429          * ten milliseconds as they are mostly pointless on Windows, the
430          * MsgWaitForMultipleObjectsEx() call will timeout right away
431          * anyway.
432          *
433          * Modification for QEMU: replaced timeout >= 10 by timeout > 0.
434          */
435         if (retval == 0 && (timeout == INFINITE || timeout > 0)) {
436             retval = poll_rest(poll_msgs, handles, nhandles,
437                                fds, nfds, timeout);
438         }
439     } else {
440         /* Just polling for one thing, so no need to check first if
441          * available immediately
442          */
443         retval = poll_rest(poll_msgs, handles, nhandles, fds, nfds, timeout);
444     }
445 
446     if (retval == -1) {
447         for (f = fds; f < &fds[nfds]; ++f) {
448             f->revents = 0;
449         }
450     }
451 
452     return retval;
453 }
454 
455 size_t getpagesize(void)
456 {
457     SYSTEM_INFO system_info;
458 
459     GetSystemInfo(&system_info);
460     return system_info.dwPageSize;
461 }
462 
463 void os_mem_prealloc(int fd, char *area, size_t memory)
464 {
465     int i;
466     size_t pagesize = getpagesize();
467 
468     memory = (memory + pagesize - 1) & -pagesize;
469     for (i = 0; i < memory / pagesize; i++) {
470         memset(area + pagesize * i, 0, 1);
471     }
472 }
473 
474 
475 /* XXX: put correct support for win32 */
476 int qemu_read_password(char *buf, int buf_size)
477 {
478     int c, i;
479 
480     printf("Password: ");
481     fflush(stdout);
482     i = 0;
483     for (;;) {
484         c = getchar();
485         if (c < 0) {
486             buf[i] = '\0';
487             return -1;
488         } else if (c == '\n') {
489             break;
490         } else if (i < (buf_size - 1)) {
491             buf[i++] = c;
492         }
493     }
494     buf[i] = '\0';
495     return 0;
496 }
497