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