1 /* 2 * os-win32.c 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * Copyright (c) 2010-2016 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 33 #include "qemu/osdep.h" 34 #include <windows.h> 35 #include "qemu-common.h" 36 #include "qapi/error.h" 37 #include "qemu/main-loop.h" 38 #include "trace.h" 39 #include "qemu/sockets.h" 40 #include "qemu/cutils.h" 41 #include "qemu/error-report.h" 42 #include <malloc.h> 43 44 /* this must come after including "trace.h" */ 45 #include <shlobj.h> 46 47 static int get_allocation_granularity(void) 48 { 49 SYSTEM_INFO system_info; 50 51 GetSystemInfo(&system_info); 52 return system_info.dwAllocationGranularity; 53 } 54 55 void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared, 56 bool noreserve) 57 { 58 void *ptr; 59 60 if (noreserve) { 61 /* 62 * We need a MEM_COMMIT before accessing any memory in a MEM_RESERVE 63 * area; we cannot easily mimic POSIX MAP_NORESERVE semantics. 64 */ 65 error_report("Skipping reservation of swap space is not supported."); 66 return NULL; 67 } 68 69 ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); 70 trace_qemu_anon_ram_alloc(size, ptr); 71 72 if (ptr && align) { 73 *align = MAX(get_allocation_granularity(), getpagesize()); 74 } 75 return ptr; 76 } 77 78 void qemu_anon_ram_free(void *ptr, size_t size) 79 { 80 trace_qemu_anon_ram_free(ptr, size); 81 if (ptr) { 82 VirtualFree(ptr, 0, MEM_RELEASE); 83 } 84 } 85 86 #ifndef _POSIX_THREAD_SAFE_FUNCTIONS 87 /* FIXME: add proper locking */ 88 struct tm *gmtime_r(const time_t *timep, struct tm *result) 89 { 90 struct tm *p = gmtime(timep); 91 memset(result, 0, sizeof(*result)); 92 if (p) { 93 *result = *p; 94 p = result; 95 } 96 return p; 97 } 98 99 /* FIXME: add proper locking */ 100 struct tm *localtime_r(const time_t *timep, struct tm *result) 101 { 102 struct tm *p = localtime(timep); 103 memset(result, 0, sizeof(*result)); 104 if (p) { 105 *result = *p; 106 p = result; 107 } 108 return p; 109 } 110 #endif /* _POSIX_THREAD_SAFE_FUNCTIONS */ 111 112 static int socket_error(void) 113 { 114 switch (WSAGetLastError()) { 115 case 0: 116 return 0; 117 case WSAEINTR: 118 return EINTR; 119 case WSAEINVAL: 120 return EINVAL; 121 case WSA_INVALID_HANDLE: 122 return EBADF; 123 case WSA_NOT_ENOUGH_MEMORY: 124 return ENOMEM; 125 case WSA_INVALID_PARAMETER: 126 return EINVAL; 127 case WSAENAMETOOLONG: 128 return ENAMETOOLONG; 129 case WSAENOTEMPTY: 130 return ENOTEMPTY; 131 case WSAEWOULDBLOCK: 132 /* not using EWOULDBLOCK as we don't want code to have 133 * to check both EWOULDBLOCK and EAGAIN */ 134 return EAGAIN; 135 case WSAEINPROGRESS: 136 return EINPROGRESS; 137 case WSAEALREADY: 138 return EALREADY; 139 case WSAENOTSOCK: 140 return ENOTSOCK; 141 case WSAEDESTADDRREQ: 142 return EDESTADDRREQ; 143 case WSAEMSGSIZE: 144 return EMSGSIZE; 145 case WSAEPROTOTYPE: 146 return EPROTOTYPE; 147 case WSAENOPROTOOPT: 148 return ENOPROTOOPT; 149 case WSAEPROTONOSUPPORT: 150 return EPROTONOSUPPORT; 151 case WSAEOPNOTSUPP: 152 return EOPNOTSUPP; 153 case WSAEAFNOSUPPORT: 154 return EAFNOSUPPORT; 155 case WSAEADDRINUSE: 156 return EADDRINUSE; 157 case WSAEADDRNOTAVAIL: 158 return EADDRNOTAVAIL; 159 case WSAENETDOWN: 160 return ENETDOWN; 161 case WSAENETUNREACH: 162 return ENETUNREACH; 163 case WSAENETRESET: 164 return ENETRESET; 165 case WSAECONNABORTED: 166 return ECONNABORTED; 167 case WSAECONNRESET: 168 return ECONNRESET; 169 case WSAENOBUFS: 170 return ENOBUFS; 171 case WSAEISCONN: 172 return EISCONN; 173 case WSAENOTCONN: 174 return ENOTCONN; 175 case WSAETIMEDOUT: 176 return ETIMEDOUT; 177 case WSAECONNREFUSED: 178 return ECONNREFUSED; 179 case WSAELOOP: 180 return ELOOP; 181 case WSAEHOSTUNREACH: 182 return EHOSTUNREACH; 183 default: 184 return EIO; 185 } 186 } 187 188 void qemu_set_block(int fd) 189 { 190 unsigned long opt = 0; 191 WSAEventSelect(fd, NULL, 0); 192 ioctlsocket(fd, FIONBIO, &opt); 193 } 194 195 int qemu_try_set_nonblock(int fd) 196 { 197 unsigned long opt = 1; 198 if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) { 199 return -socket_error(); 200 } 201 return 0; 202 } 203 204 void qemu_set_nonblock(int fd) 205 { 206 (void)qemu_try_set_nonblock(fd); 207 } 208 209 int socket_set_fast_reuse(int fd) 210 { 211 /* Enabling the reuse of an endpoint that was used by a socket still in 212 * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows 213 * fast reuse is the default and SO_REUSEADDR does strange things. So we 214 * don't have to do anything here. More info can be found at: 215 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */ 216 return 0; 217 } 218 219 int inet_aton(const char *cp, struct in_addr *ia) 220 { 221 uint32_t addr = inet_addr(cp); 222 if (addr == 0xffffffff) { 223 return 0; 224 } 225 ia->s_addr = addr; 226 return 1; 227 } 228 229 void qemu_set_cloexec(int fd) 230 { 231 } 232 233 /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ 234 #define _W32_FT_OFFSET (116444736000000000ULL) 235 236 int qemu_gettimeofday(qemu_timeval *tp) 237 { 238 union { 239 unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */ 240 FILETIME ft; 241 } _now; 242 243 if(tp) { 244 GetSystemTimeAsFileTime (&_now.ft); 245 tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL ); 246 tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL); 247 } 248 /* Always return 0 as per Open Group Base Specifications Issue 6. 249 Do not set errno on error. */ 250 return 0; 251 } 252 253 int qemu_get_thread_id(void) 254 { 255 return GetCurrentThreadId(); 256 } 257 258 char * 259 qemu_get_local_state_pathname(const char *relative_pathname) 260 { 261 HRESULT result; 262 char base_path[MAX_PATH+1] = ""; 263 264 result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 265 /* SHGFP_TYPE_CURRENT */ 0, base_path); 266 if (result != S_OK) { 267 /* misconfigured environment */ 268 g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result); 269 abort(); 270 } 271 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path, 272 relative_pathname); 273 } 274 275 void qemu_set_tty_echo(int fd, bool echo) 276 { 277 HANDLE handle = (HANDLE)_get_osfhandle(fd); 278 DWORD dwMode = 0; 279 280 if (handle == INVALID_HANDLE_VALUE) { 281 return; 282 } 283 284 GetConsoleMode(handle, &dwMode); 285 286 if (echo) { 287 SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT); 288 } else { 289 SetConsoleMode(handle, 290 dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT)); 291 } 292 } 293 294 static const char *exec_dir; 295 296 void qemu_init_exec_dir(const char *argv0) 297 { 298 299 char *p; 300 char buf[MAX_PATH]; 301 DWORD len; 302 303 if (exec_dir) { 304 return; 305 } 306 307 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1); 308 if (len == 0) { 309 return; 310 } 311 312 buf[len] = 0; 313 p = buf + len - 1; 314 while (p != buf && *p != '\\') { 315 p--; 316 } 317 *p = 0; 318 if (access(buf, R_OK) == 0) { 319 exec_dir = g_strdup(buf); 320 } else { 321 exec_dir = CONFIG_BINDIR; 322 } 323 } 324 325 const char *qemu_get_exec_dir(void) 326 { 327 return exec_dir; 328 } 329 330 int getpagesize(void) 331 { 332 SYSTEM_INFO system_info; 333 334 GetSystemInfo(&system_info); 335 return system_info.dwPageSize; 336 } 337 338 void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, 339 Error **errp) 340 { 341 int i; 342 size_t pagesize = qemu_real_host_page_size; 343 344 memory = (memory + pagesize - 1) & -pagesize; 345 for (i = 0; i < memory / pagesize; i++) { 346 memset(area + pagesize * i, 0, 1); 347 } 348 } 349 350 char *qemu_get_pid_name(pid_t pid) 351 { 352 /* XXX Implement me */ 353 abort(); 354 } 355 356 357 pid_t qemu_fork(Error **errp) 358 { 359 errno = ENOSYS; 360 error_setg_errno(errp, errno, 361 "cannot fork child process"); 362 return -1; 363 } 364 365 366 #undef connect 367 int qemu_connect_wrap(int sockfd, const struct sockaddr *addr, 368 socklen_t addrlen) 369 { 370 int ret; 371 ret = connect(sockfd, addr, addrlen); 372 if (ret < 0) { 373 if (WSAGetLastError() == WSAEWOULDBLOCK) { 374 errno = EINPROGRESS; 375 } else { 376 errno = socket_error(); 377 } 378 } 379 return ret; 380 } 381 382 383 #undef listen 384 int qemu_listen_wrap(int sockfd, int backlog) 385 { 386 int ret; 387 ret = listen(sockfd, backlog); 388 if (ret < 0) { 389 errno = socket_error(); 390 } 391 return ret; 392 } 393 394 395 #undef bind 396 int qemu_bind_wrap(int sockfd, const struct sockaddr *addr, 397 socklen_t addrlen) 398 { 399 int ret; 400 ret = bind(sockfd, addr, addrlen); 401 if (ret < 0) { 402 errno = socket_error(); 403 } 404 return ret; 405 } 406 407 408 #undef socket 409 int qemu_socket_wrap(int domain, int type, int protocol) 410 { 411 int ret; 412 ret = socket(domain, type, protocol); 413 if (ret < 0) { 414 errno = socket_error(); 415 } 416 return ret; 417 } 418 419 420 #undef accept 421 int qemu_accept_wrap(int sockfd, struct sockaddr *addr, 422 socklen_t *addrlen) 423 { 424 int ret; 425 ret = accept(sockfd, addr, addrlen); 426 if (ret < 0) { 427 errno = socket_error(); 428 } 429 return ret; 430 } 431 432 433 #undef shutdown 434 int qemu_shutdown_wrap(int sockfd, int how) 435 { 436 int ret; 437 ret = shutdown(sockfd, how); 438 if (ret < 0) { 439 errno = socket_error(); 440 } 441 return ret; 442 } 443 444 445 #undef ioctlsocket 446 int qemu_ioctlsocket_wrap(int fd, int req, void *val) 447 { 448 int ret; 449 ret = ioctlsocket(fd, req, val); 450 if (ret < 0) { 451 errno = socket_error(); 452 } 453 return ret; 454 } 455 456 457 #undef closesocket 458 int qemu_closesocket_wrap(int fd) 459 { 460 int ret; 461 ret = closesocket(fd); 462 if (ret < 0) { 463 errno = socket_error(); 464 } 465 return ret; 466 } 467 468 469 #undef getsockopt 470 int qemu_getsockopt_wrap(int sockfd, int level, int optname, 471 void *optval, socklen_t *optlen) 472 { 473 int ret; 474 ret = getsockopt(sockfd, level, optname, optval, optlen); 475 if (ret < 0) { 476 errno = socket_error(); 477 } 478 return ret; 479 } 480 481 482 #undef setsockopt 483 int qemu_setsockopt_wrap(int sockfd, int level, int optname, 484 const void *optval, socklen_t optlen) 485 { 486 int ret; 487 ret = setsockopt(sockfd, level, optname, optval, optlen); 488 if (ret < 0) { 489 errno = socket_error(); 490 } 491 return ret; 492 } 493 494 495 #undef getpeername 496 int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr, 497 socklen_t *addrlen) 498 { 499 int ret; 500 ret = getpeername(sockfd, addr, addrlen); 501 if (ret < 0) { 502 errno = socket_error(); 503 } 504 return ret; 505 } 506 507 508 #undef getsockname 509 int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr, 510 socklen_t *addrlen) 511 { 512 int ret; 513 ret = getsockname(sockfd, addr, addrlen); 514 if (ret < 0) { 515 errno = socket_error(); 516 } 517 return ret; 518 } 519 520 521 #undef send 522 ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags) 523 { 524 int ret; 525 ret = send(sockfd, buf, len, flags); 526 if (ret < 0) { 527 errno = socket_error(); 528 } 529 return ret; 530 } 531 532 533 #undef sendto 534 ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags, 535 const struct sockaddr *addr, socklen_t addrlen) 536 { 537 int ret; 538 ret = sendto(sockfd, buf, len, flags, addr, addrlen); 539 if (ret < 0) { 540 errno = socket_error(); 541 } 542 return ret; 543 } 544 545 546 #undef recv 547 ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags) 548 { 549 int ret; 550 ret = recv(sockfd, buf, len, flags); 551 if (ret < 0) { 552 errno = socket_error(); 553 } 554 return ret; 555 } 556 557 558 #undef recvfrom 559 ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags, 560 struct sockaddr *addr, socklen_t *addrlen) 561 { 562 int ret; 563 ret = recvfrom(sockfd, buf, len, flags, addr, addrlen); 564 if (ret < 0) { 565 errno = socket_error(); 566 } 567 return ret; 568 } 569 570 bool qemu_write_pidfile(const char *filename, Error **errp) 571 { 572 char buffer[128]; 573 int len; 574 HANDLE file; 575 OVERLAPPED overlap; 576 BOOL ret; 577 memset(&overlap, 0, sizeof(overlap)); 578 579 file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, 580 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 581 582 if (file == INVALID_HANDLE_VALUE) { 583 error_setg(errp, "Failed to create PID file"); 584 return false; 585 } 586 len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid()); 587 ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len, 588 NULL, &overlap); 589 CloseHandle(file); 590 if (ret == 0) { 591 error_setg(errp, "Failed to write PID file"); 592 return false; 593 } 594 return true; 595 } 596 597 char *qemu_get_host_name(Error **errp) 598 { 599 wchar_t tmp[MAX_COMPUTERNAME_LENGTH + 1]; 600 DWORD size = G_N_ELEMENTS(tmp); 601 602 if (GetComputerNameW(tmp, &size) == 0) { 603 error_setg_win32(errp, GetLastError(), "failed close handle"); 604 return NULL; 605 } 606 607 return g_utf16_to_utf8(tmp, size, NULL, NULL, NULL); 608 } 609 610 size_t qemu_get_host_physmem(void) 611 { 612 MEMORYSTATUSEX statex; 613 statex.dwLength = sizeof(statex); 614 615 if (GlobalMemoryStatusEx(&statex)) { 616 return statex.ullTotalPhys; 617 } 618 return 0; 619 } 620