xref: /openbmc/qemu/util/oslib-win32.c (revision e2ea3515)
1baacf047SPaolo Bonzini /*
2baacf047SPaolo Bonzini  * os-win32.c
3baacf047SPaolo Bonzini  *
4baacf047SPaolo Bonzini  * Copyright (c) 2003-2008 Fabrice Bellard
5baacf047SPaolo Bonzini  * Copyright (c) 2010 Red Hat, Inc.
6baacf047SPaolo Bonzini  *
7baacf047SPaolo Bonzini  * QEMU library functions for win32 which are shared between QEMU and
8baacf047SPaolo Bonzini  * the QEMU tools.
9baacf047SPaolo Bonzini  *
10baacf047SPaolo Bonzini  * Permission is hereby granted, free of charge, to any person obtaining a copy
11baacf047SPaolo Bonzini  * of this software and associated documentation files (the "Software"), to deal
12baacf047SPaolo Bonzini  * in the Software without restriction, including without limitation the rights
13baacf047SPaolo Bonzini  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14baacf047SPaolo Bonzini  * copies of the Software, and to permit persons to whom the Software is
15baacf047SPaolo Bonzini  * furnished to do so, subject to the following conditions:
16baacf047SPaolo Bonzini  *
17baacf047SPaolo Bonzini  * The above copyright notice and this permission notice shall be included in
18baacf047SPaolo Bonzini  * all copies or substantial portions of the Software.
19baacf047SPaolo Bonzini  *
20baacf047SPaolo Bonzini  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21baacf047SPaolo Bonzini  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22baacf047SPaolo Bonzini  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23baacf047SPaolo Bonzini  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24baacf047SPaolo Bonzini  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25baacf047SPaolo Bonzini  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26baacf047SPaolo Bonzini  * THE SOFTWARE.
27baacf047SPaolo Bonzini  */
28baacf047SPaolo Bonzini #include <windows.h>
29*e2ea3515SLaszlo Ersek #include <glib.h>
30*e2ea3515SLaszlo Ersek #include <stdlib.h>
31baacf047SPaolo Bonzini #include "config-host.h"
32baacf047SPaolo Bonzini #include "sysemu/sysemu.h"
33baacf047SPaolo Bonzini #include "qemu/main-loop.h"
34baacf047SPaolo Bonzini #include "trace.h"
35baacf047SPaolo Bonzini #include "qemu/sockets.h"
36baacf047SPaolo Bonzini 
37*e2ea3515SLaszlo Ersek /* this must come after including "trace.h" */
38*e2ea3515SLaszlo Ersek #include <shlobj.h>
39*e2ea3515SLaszlo Ersek 
40baacf047SPaolo Bonzini void *qemu_oom_check(void *ptr)
41baacf047SPaolo Bonzini {
42baacf047SPaolo Bonzini     if (ptr == NULL) {
43baacf047SPaolo Bonzini         fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
44baacf047SPaolo Bonzini         abort();
45baacf047SPaolo Bonzini     }
46baacf047SPaolo Bonzini     return ptr;
47baacf047SPaolo Bonzini }
48baacf047SPaolo Bonzini 
49baacf047SPaolo Bonzini void *qemu_memalign(size_t alignment, size_t size)
50baacf047SPaolo Bonzini {
51baacf047SPaolo Bonzini     void *ptr;
52baacf047SPaolo Bonzini 
53baacf047SPaolo Bonzini     if (!size) {
54baacf047SPaolo Bonzini         abort();
55baacf047SPaolo Bonzini     }
56baacf047SPaolo Bonzini     ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
57baacf047SPaolo Bonzini     trace_qemu_memalign(alignment, size, ptr);
58baacf047SPaolo Bonzini     return ptr;
59baacf047SPaolo Bonzini }
60baacf047SPaolo Bonzini 
616eebf958SPaolo Bonzini void *qemu_anon_ram_alloc(size_t size)
62baacf047SPaolo Bonzini {
63baacf047SPaolo Bonzini     void *ptr;
64baacf047SPaolo Bonzini 
65baacf047SPaolo Bonzini     /* FIXME: this is not exactly optimal solution since VirtualAlloc
66baacf047SPaolo Bonzini        has 64Kb granularity, but at least it guarantees us that the
67baacf047SPaolo Bonzini        memory is page aligned. */
68baacf047SPaolo Bonzini     if (!size) {
69baacf047SPaolo Bonzini         abort();
70baacf047SPaolo Bonzini     }
71baacf047SPaolo Bonzini     ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
726eebf958SPaolo Bonzini     trace_qemu_anon_ram_alloc(size, ptr);
73baacf047SPaolo Bonzini     return ptr;
74baacf047SPaolo Bonzini }
75baacf047SPaolo Bonzini 
76baacf047SPaolo Bonzini void qemu_vfree(void *ptr)
77baacf047SPaolo Bonzini {
78baacf047SPaolo Bonzini     trace_qemu_vfree(ptr);
7994c8ff3aSMarkus Armbruster     if (ptr) {
80baacf047SPaolo Bonzini         VirtualFree(ptr, 0, MEM_RELEASE);
81baacf047SPaolo Bonzini     }
8294c8ff3aSMarkus Armbruster }
83baacf047SPaolo Bonzini 
84e7a09b92SPaolo Bonzini void qemu_anon_ram_free(void *ptr, size_t size)
85e7a09b92SPaolo Bonzini {
86e7a09b92SPaolo Bonzini     trace_qemu_anon_ram_free(ptr, size);
87e7a09b92SPaolo Bonzini     if (ptr) {
88e7a09b92SPaolo Bonzini         VirtualFree(ptr, 0, MEM_RELEASE);
89e7a09b92SPaolo Bonzini     }
90e7a09b92SPaolo Bonzini }
91e7a09b92SPaolo Bonzini 
92baacf047SPaolo Bonzini /* FIXME: add proper locking */
93baacf047SPaolo Bonzini struct tm *gmtime_r(const time_t *timep, struct tm *result)
94baacf047SPaolo Bonzini {
95baacf047SPaolo Bonzini     struct tm *p = gmtime(timep);
96baacf047SPaolo Bonzini     memset(result, 0, sizeof(*result));
97baacf047SPaolo Bonzini     if (p) {
98baacf047SPaolo Bonzini         *result = *p;
99baacf047SPaolo Bonzini         p = result;
100baacf047SPaolo Bonzini     }
101baacf047SPaolo Bonzini     return p;
102baacf047SPaolo Bonzini }
103baacf047SPaolo Bonzini 
104baacf047SPaolo Bonzini /* FIXME: add proper locking */
105baacf047SPaolo Bonzini struct tm *localtime_r(const time_t *timep, struct tm *result)
106baacf047SPaolo Bonzini {
107baacf047SPaolo Bonzini     struct tm *p = localtime(timep);
108baacf047SPaolo Bonzini     memset(result, 0, sizeof(*result));
109baacf047SPaolo Bonzini     if (p) {
110baacf047SPaolo Bonzini         *result = *p;
111baacf047SPaolo Bonzini         p = result;
112baacf047SPaolo Bonzini     }
113baacf047SPaolo Bonzini     return p;
114baacf047SPaolo Bonzini }
115baacf047SPaolo Bonzini 
116f9e8caccSStefan Hajnoczi void qemu_set_block(int fd)
117baacf047SPaolo Bonzini {
118baacf047SPaolo Bonzini     unsigned long opt = 0;
119baacf047SPaolo Bonzini     WSAEventSelect(fd, NULL, 0);
120baacf047SPaolo Bonzini     ioctlsocket(fd, FIONBIO, &opt);
121baacf047SPaolo Bonzini }
122baacf047SPaolo Bonzini 
123f9e8caccSStefan Hajnoczi void qemu_set_nonblock(int fd)
124baacf047SPaolo Bonzini {
125baacf047SPaolo Bonzini     unsigned long opt = 1;
126baacf047SPaolo Bonzini     ioctlsocket(fd, FIONBIO, &opt);
127baacf047SPaolo Bonzini     qemu_fd_register(fd);
128baacf047SPaolo Bonzini }
129baacf047SPaolo Bonzini 
130baacf047SPaolo Bonzini int inet_aton(const char *cp, struct in_addr *ia)
131baacf047SPaolo Bonzini {
132baacf047SPaolo Bonzini     uint32_t addr = inet_addr(cp);
133baacf047SPaolo Bonzini     if (addr == 0xffffffff) {
134baacf047SPaolo Bonzini 	return 0;
135baacf047SPaolo Bonzini     }
136baacf047SPaolo Bonzini     ia->s_addr = addr;
137baacf047SPaolo Bonzini     return 1;
138baacf047SPaolo Bonzini }
139baacf047SPaolo Bonzini 
140baacf047SPaolo Bonzini void qemu_set_cloexec(int fd)
141baacf047SPaolo Bonzini {
142baacf047SPaolo Bonzini }
143baacf047SPaolo Bonzini 
144baacf047SPaolo Bonzini /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
145baacf047SPaolo Bonzini #define _W32_FT_OFFSET (116444736000000000ULL)
146baacf047SPaolo Bonzini 
147baacf047SPaolo Bonzini int qemu_gettimeofday(qemu_timeval *tp)
148baacf047SPaolo Bonzini {
149baacf047SPaolo Bonzini   union {
150baacf047SPaolo Bonzini     unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
151baacf047SPaolo Bonzini     FILETIME ft;
152baacf047SPaolo Bonzini   }  _now;
153baacf047SPaolo Bonzini 
154baacf047SPaolo Bonzini   if(tp) {
155baacf047SPaolo Bonzini       GetSystemTimeAsFileTime (&_now.ft);
156baacf047SPaolo Bonzini       tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
157baacf047SPaolo Bonzini       tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
158baacf047SPaolo Bonzini   }
159baacf047SPaolo Bonzini   /* Always return 0 as per Open Group Base Specifications Issue 6.
160baacf047SPaolo Bonzini      Do not set errno on error.  */
161baacf047SPaolo Bonzini   return 0;
162baacf047SPaolo Bonzini }
163baacf047SPaolo Bonzini 
164baacf047SPaolo Bonzini int qemu_get_thread_id(void)
165baacf047SPaolo Bonzini {
166baacf047SPaolo Bonzini     return GetCurrentThreadId();
167baacf047SPaolo Bonzini }
168*e2ea3515SLaszlo Ersek 
169*e2ea3515SLaszlo Ersek char *
170*e2ea3515SLaszlo Ersek qemu_get_local_state_pathname(const char *relative_pathname)
171*e2ea3515SLaszlo Ersek {
172*e2ea3515SLaszlo Ersek     HRESULT result;
173*e2ea3515SLaszlo Ersek     char base_path[MAX_PATH+1] = "";
174*e2ea3515SLaszlo Ersek 
175*e2ea3515SLaszlo Ersek     result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL,
176*e2ea3515SLaszlo Ersek                              /* SHGFP_TYPE_CURRENT */ 0, base_path);
177*e2ea3515SLaszlo Ersek     if (result != S_OK) {
178*e2ea3515SLaszlo Ersek         /* misconfigured environment */
179*e2ea3515SLaszlo Ersek         g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result);
180*e2ea3515SLaszlo Ersek         abort();
181*e2ea3515SLaszlo Ersek     }
182*e2ea3515SLaszlo Ersek     return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path,
183*e2ea3515SLaszlo Ersek                            relative_pathname);
184*e2ea3515SLaszlo Ersek }
185