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 int qemu_get_thread_id(void) 234 { 235 return GetCurrentThreadId(); 236 } 237 238 char * 239 qemu_get_local_state_pathname(const char *relative_pathname) 240 { 241 HRESULT result; 242 char base_path[MAX_PATH+1] = ""; 243 244 result = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 245 /* SHGFP_TYPE_CURRENT */ 0, base_path); 246 if (result != S_OK) { 247 /* misconfigured environment */ 248 g_critical("CSIDL_COMMON_APPDATA unavailable: %ld", (long)result); 249 abort(); 250 } 251 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", base_path, 252 relative_pathname); 253 } 254 255 void qemu_set_tty_echo(int fd, bool echo) 256 { 257 HANDLE handle = (HANDLE)_get_osfhandle(fd); 258 DWORD dwMode = 0; 259 260 if (handle == INVALID_HANDLE_VALUE) { 261 return; 262 } 263 264 GetConsoleMode(handle, &dwMode); 265 266 if (echo) { 267 SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT); 268 } else { 269 SetConsoleMode(handle, 270 dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT)); 271 } 272 } 273 274 static const char *exec_dir; 275 276 void qemu_init_exec_dir(const char *argv0) 277 { 278 279 char *p; 280 char buf[MAX_PATH]; 281 DWORD len; 282 283 if (exec_dir) { 284 return; 285 } 286 287 len = GetModuleFileName(NULL, buf, sizeof(buf) - 1); 288 if (len == 0) { 289 return; 290 } 291 292 buf[len] = 0; 293 p = buf + len - 1; 294 while (p != buf && *p != '\\') { 295 p--; 296 } 297 *p = 0; 298 if (access(buf, R_OK) == 0) { 299 exec_dir = g_strdup(buf); 300 } else { 301 exec_dir = CONFIG_BINDIR; 302 } 303 } 304 305 const char *qemu_get_exec_dir(void) 306 { 307 return exec_dir; 308 } 309 310 int getpagesize(void) 311 { 312 SYSTEM_INFO system_info; 313 314 GetSystemInfo(&system_info); 315 return system_info.dwPageSize; 316 } 317 318 void os_mem_prealloc(int fd, char *area, size_t memory, int smp_cpus, 319 Error **errp) 320 { 321 int i; 322 size_t pagesize = qemu_real_host_page_size(); 323 324 memory = (memory + pagesize - 1) & -pagesize; 325 for (i = 0; i < memory / pagesize; i++) { 326 memset(area + pagesize * i, 0, 1); 327 } 328 } 329 330 char *qemu_get_pid_name(pid_t pid) 331 { 332 /* XXX Implement me */ 333 abort(); 334 } 335 336 337 pid_t qemu_fork(Error **errp) 338 { 339 errno = ENOSYS; 340 error_setg_errno(errp, errno, 341 "cannot fork child process"); 342 return -1; 343 } 344 345 346 #undef connect 347 int qemu_connect_wrap(int sockfd, const struct sockaddr *addr, 348 socklen_t addrlen) 349 { 350 int ret; 351 ret = connect(sockfd, addr, addrlen); 352 if (ret < 0) { 353 if (WSAGetLastError() == WSAEWOULDBLOCK) { 354 errno = EINPROGRESS; 355 } else { 356 errno = socket_error(); 357 } 358 } 359 return ret; 360 } 361 362 363 #undef listen 364 int qemu_listen_wrap(int sockfd, int backlog) 365 { 366 int ret; 367 ret = listen(sockfd, backlog); 368 if (ret < 0) { 369 errno = socket_error(); 370 } 371 return ret; 372 } 373 374 375 #undef bind 376 int qemu_bind_wrap(int sockfd, const struct sockaddr *addr, 377 socklen_t addrlen) 378 { 379 int ret; 380 ret = bind(sockfd, addr, addrlen); 381 if (ret < 0) { 382 errno = socket_error(); 383 } 384 return ret; 385 } 386 387 388 #undef socket 389 int qemu_socket_wrap(int domain, int type, int protocol) 390 { 391 int ret; 392 ret = socket(domain, type, protocol); 393 if (ret < 0) { 394 errno = socket_error(); 395 } 396 return ret; 397 } 398 399 400 #undef accept 401 int qemu_accept_wrap(int sockfd, struct sockaddr *addr, 402 socklen_t *addrlen) 403 { 404 int ret; 405 ret = accept(sockfd, addr, addrlen); 406 if (ret < 0) { 407 errno = socket_error(); 408 } 409 return ret; 410 } 411 412 413 #undef shutdown 414 int qemu_shutdown_wrap(int sockfd, int how) 415 { 416 int ret; 417 ret = shutdown(sockfd, how); 418 if (ret < 0) { 419 errno = socket_error(); 420 } 421 return ret; 422 } 423 424 425 #undef ioctlsocket 426 int qemu_ioctlsocket_wrap(int fd, int req, void *val) 427 { 428 int ret; 429 ret = ioctlsocket(fd, req, val); 430 if (ret < 0) { 431 errno = socket_error(); 432 } 433 return ret; 434 } 435 436 437 #undef closesocket 438 int qemu_closesocket_wrap(int fd) 439 { 440 int ret; 441 ret = closesocket(fd); 442 if (ret < 0) { 443 errno = socket_error(); 444 } 445 return ret; 446 } 447 448 449 #undef getsockopt 450 int qemu_getsockopt_wrap(int sockfd, int level, int optname, 451 void *optval, socklen_t *optlen) 452 { 453 int ret; 454 ret = getsockopt(sockfd, level, optname, optval, optlen); 455 if (ret < 0) { 456 errno = socket_error(); 457 } 458 return ret; 459 } 460 461 462 #undef setsockopt 463 int qemu_setsockopt_wrap(int sockfd, int level, int optname, 464 const void *optval, socklen_t optlen) 465 { 466 int ret; 467 ret = setsockopt(sockfd, level, optname, optval, optlen); 468 if (ret < 0) { 469 errno = socket_error(); 470 } 471 return ret; 472 } 473 474 475 #undef getpeername 476 int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr, 477 socklen_t *addrlen) 478 { 479 int ret; 480 ret = getpeername(sockfd, addr, addrlen); 481 if (ret < 0) { 482 errno = socket_error(); 483 } 484 return ret; 485 } 486 487 488 #undef getsockname 489 int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr, 490 socklen_t *addrlen) 491 { 492 int ret; 493 ret = getsockname(sockfd, addr, addrlen); 494 if (ret < 0) { 495 errno = socket_error(); 496 } 497 return ret; 498 } 499 500 501 #undef send 502 ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags) 503 { 504 int ret; 505 ret = send(sockfd, buf, len, flags); 506 if (ret < 0) { 507 errno = socket_error(); 508 } 509 return ret; 510 } 511 512 513 #undef sendto 514 ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags, 515 const struct sockaddr *addr, socklen_t addrlen) 516 { 517 int ret; 518 ret = sendto(sockfd, buf, len, flags, addr, addrlen); 519 if (ret < 0) { 520 errno = socket_error(); 521 } 522 return ret; 523 } 524 525 526 #undef recv 527 ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags) 528 { 529 int ret; 530 ret = recv(sockfd, buf, len, flags); 531 if (ret < 0) { 532 errno = socket_error(); 533 } 534 return ret; 535 } 536 537 538 #undef recvfrom 539 ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags, 540 struct sockaddr *addr, socklen_t *addrlen) 541 { 542 int ret; 543 ret = recvfrom(sockfd, buf, len, flags, addr, addrlen); 544 if (ret < 0) { 545 errno = socket_error(); 546 } 547 return ret; 548 } 549 550 bool qemu_write_pidfile(const char *filename, Error **errp) 551 { 552 char buffer[128]; 553 int len; 554 HANDLE file; 555 OVERLAPPED overlap; 556 BOOL ret; 557 memset(&overlap, 0, sizeof(overlap)); 558 559 file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, 560 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 561 562 if (file == INVALID_HANDLE_VALUE) { 563 error_setg(errp, "Failed to create PID file"); 564 return false; 565 } 566 len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid()); 567 ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len, 568 NULL, &overlap); 569 CloseHandle(file); 570 if (ret == 0) { 571 error_setg(errp, "Failed to write PID file"); 572 return false; 573 } 574 return true; 575 } 576 577 char *qemu_get_host_name(Error **errp) 578 { 579 wchar_t tmp[MAX_COMPUTERNAME_LENGTH + 1]; 580 DWORD size = G_N_ELEMENTS(tmp); 581 582 if (GetComputerNameW(tmp, &size) == 0) { 583 error_setg_win32(errp, GetLastError(), "failed close handle"); 584 return NULL; 585 } 586 587 return g_utf16_to_utf8(tmp, size, NULL, NULL, NULL); 588 } 589 590 size_t qemu_get_host_physmem(void) 591 { 592 MEMORYSTATUSEX statex; 593 statex.dwLength = sizeof(statex); 594 595 if (GlobalMemoryStatusEx(&statex)) { 596 return statex.ullTotalPhys; 597 } 598 return 0; 599 } 600