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