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 29 #include "qemu/osdep.h" 30 #include <windows.h> 31 #include "qapi/error.h" 32 #include "qemu/main-loop.h" 33 #include "trace.h" 34 #include "qemu/sockets.h" 35 #include "qemu/cutils.h" 36 #include "qemu/error-report.h" 37 #include <malloc.h> 38 39 static int get_allocation_granularity(void) 40 { 41 SYSTEM_INFO system_info; 42 43 GetSystemInfo(&system_info); 44 return system_info.dwAllocationGranularity; 45 } 46 47 void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared, 48 bool noreserve) 49 { 50 void *ptr; 51 52 if (noreserve) { 53 /* 54 * We need a MEM_COMMIT before accessing any memory in a MEM_RESERVE 55 * area; we cannot easily mimic POSIX MAP_NORESERVE semantics. 56 */ 57 error_report("Skipping reservation of swap space is not supported."); 58 return NULL; 59 } 60 61 ptr = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); 62 trace_qemu_anon_ram_alloc(size, ptr); 63 64 if (ptr && align) { 65 *align = MAX(get_allocation_granularity(), getpagesize()); 66 } 67 return ptr; 68 } 69 70 void qemu_anon_ram_free(void *ptr, size_t size) 71 { 72 trace_qemu_anon_ram_free(ptr, size); 73 if (ptr) { 74 VirtualFree(ptr, 0, MEM_RELEASE); 75 } 76 } 77 78 #ifndef _POSIX_THREAD_SAFE_FUNCTIONS 79 /* FIXME: add proper locking */ 80 struct tm *gmtime_r(const time_t *timep, struct tm *result) 81 { 82 struct tm *p = gmtime(timep); 83 memset(result, 0, sizeof(*result)); 84 if (p) { 85 *result = *p; 86 p = result; 87 } 88 return p; 89 } 90 91 /* FIXME: add proper locking */ 92 struct tm *localtime_r(const time_t *timep, struct tm *result) 93 { 94 struct tm *p = localtime(timep); 95 memset(result, 0, sizeof(*result)); 96 if (p) { 97 *result = *p; 98 p = result; 99 } 100 return p; 101 } 102 #endif /* _POSIX_THREAD_SAFE_FUNCTIONS */ 103 104 static int socket_error(void) 105 { 106 switch (WSAGetLastError()) { 107 case 0: 108 return 0; 109 case WSAEINTR: 110 return EINTR; 111 case WSAEINVAL: 112 return EINVAL; 113 case WSA_INVALID_HANDLE: 114 return EBADF; 115 case WSA_NOT_ENOUGH_MEMORY: 116 return ENOMEM; 117 case WSA_INVALID_PARAMETER: 118 return EINVAL; 119 case WSAENAMETOOLONG: 120 return ENAMETOOLONG; 121 case WSAENOTEMPTY: 122 return ENOTEMPTY; 123 case WSAEWOULDBLOCK: 124 /* not using EWOULDBLOCK as we don't want code to have 125 * to check both EWOULDBLOCK and EAGAIN */ 126 return EAGAIN; 127 case WSAEINPROGRESS: 128 return EINPROGRESS; 129 case WSAEALREADY: 130 return EALREADY; 131 case WSAENOTSOCK: 132 return ENOTSOCK; 133 case WSAEDESTADDRREQ: 134 return EDESTADDRREQ; 135 case WSAEMSGSIZE: 136 return EMSGSIZE; 137 case WSAEPROTOTYPE: 138 return EPROTOTYPE; 139 case WSAENOPROTOOPT: 140 return ENOPROTOOPT; 141 case WSAEPROTONOSUPPORT: 142 return EPROTONOSUPPORT; 143 case WSAEOPNOTSUPP: 144 return EOPNOTSUPP; 145 case WSAEAFNOSUPPORT: 146 return EAFNOSUPPORT; 147 case WSAEADDRINUSE: 148 return EADDRINUSE; 149 case WSAEADDRNOTAVAIL: 150 return EADDRNOTAVAIL; 151 case WSAENETDOWN: 152 return ENETDOWN; 153 case WSAENETUNREACH: 154 return ENETUNREACH; 155 case WSAENETRESET: 156 return ENETRESET; 157 case WSAECONNABORTED: 158 return ECONNABORTED; 159 case WSAECONNRESET: 160 return ECONNRESET; 161 case WSAENOBUFS: 162 return ENOBUFS; 163 case WSAEISCONN: 164 return EISCONN; 165 case WSAENOTCONN: 166 return ENOTCONN; 167 case WSAETIMEDOUT: 168 return ETIMEDOUT; 169 case WSAECONNREFUSED: 170 return ECONNREFUSED; 171 case WSAELOOP: 172 return ELOOP; 173 case WSAEHOSTUNREACH: 174 return EHOSTUNREACH; 175 default: 176 return EIO; 177 } 178 } 179 180 bool qemu_set_blocking(int fd, bool block, Error **errp) 181 { 182 unsigned long opt = block ? 0 : 1; 183 184 if (block) { 185 qemu_socket_unselect_nofail(fd); 186 } 187 188 if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) { 189 error_setg_errno(errp, socket_error(), 190 "Can't set file descriptor %d %s", fd, 191 block ? "blocking" : "non-blocking"); 192 return false; 193 } 194 195 return true; 196 } 197 198 int socket_set_fast_reuse(int fd) 199 { 200 /* Enabling the reuse of an endpoint that was used by a socket still in 201 * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows 202 * fast reuse is the default and SO_REUSEADDR does strange things. So we 203 * don't have to do anything here. More info can be found at: 204 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */ 205 return 0; 206 } 207 208 int inet_aton(const char *cp, struct in_addr *ia) 209 { 210 uint32_t addr = inet_addr(cp); 211 if (addr == 0xffffffff) { 212 return 0; 213 } 214 ia->s_addr = addr; 215 return 1; 216 } 217 218 void qemu_set_cloexec(int fd) 219 { 220 } 221 222 void qemu_clear_cloexec(int fd) 223 { 224 } 225 226 int qemu_get_thread_id(void) 227 { 228 return GetCurrentThreadId(); 229 } 230 231 char * 232 qemu_get_local_state_dir(void) 233 { 234 const char * const *data_dirs = g_get_system_data_dirs(); 235 236 g_assert(data_dirs && data_dirs[0]); 237 238 return g_strdup(data_dirs[0]); 239 } 240 241 void qemu_set_tty_echo(int fd, bool echo) 242 { 243 HANDLE handle = (HANDLE)_get_osfhandle(fd); 244 DWORD dwMode = 0; 245 246 if (handle == INVALID_HANDLE_VALUE) { 247 return; 248 } 249 250 GetConsoleMode(handle, &dwMode); 251 252 if (echo) { 253 SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT); 254 } else { 255 SetConsoleMode(handle, 256 dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT)); 257 } 258 } 259 260 int getpagesize(void) 261 { 262 SYSTEM_INFO system_info; 263 264 GetSystemInfo(&system_info); 265 return system_info.dwPageSize; 266 } 267 268 bool qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, 269 ThreadContext *tc, bool async, Error **errp) 270 { 271 int i; 272 size_t pagesize = qemu_real_host_page_size(); 273 274 sz = (sz + pagesize - 1) & -pagesize; 275 for (i = 0; i < sz / pagesize; i++) { 276 memset(area + pagesize * i, 0, 1); 277 } 278 279 return true; 280 } 281 282 bool qemu_finish_async_prealloc_mem(Error **errp) 283 { 284 /* async prealloc not supported, there is nothing to finish */ 285 return true; 286 } 287 288 char *qemu_get_pid_name(pid_t pid) 289 { 290 /* XXX Implement me */ 291 abort(); 292 } 293 294 295 bool qemu_socket_select(int sockfd, WSAEVENT hEventObject, 296 long lNetworkEvents, Error **errp) 297 { 298 SOCKET s = _get_osfhandle(sockfd); 299 300 if (s == INVALID_SOCKET) { 301 error_setg(errp, "invalid socket fd=%d", sockfd); 302 return false; 303 } 304 305 if (WSAEventSelect(s, hEventObject, lNetworkEvents) != 0) { 306 error_setg_win32(errp, WSAGetLastError(), "failed to WSAEventSelect()"); 307 return false; 308 } 309 310 return true; 311 } 312 313 bool qemu_socket_unselect(int sockfd, Error **errp) 314 { 315 return qemu_socket_select(sockfd, NULL, 0, errp); 316 } 317 318 void qemu_socket_select_nofail(int sockfd, WSAEVENT hEventObject, 319 long lNetworkEvents) 320 { 321 Error *err = NULL; 322 323 if (!qemu_socket_select(sockfd, hEventObject, lNetworkEvents, &err)) { 324 warn_report_err(err); 325 } 326 } 327 328 void qemu_socket_unselect_nofail(int sockfd) 329 { 330 Error *err = NULL; 331 332 if (!qemu_socket_unselect(sockfd, &err)) { 333 warn_report_err(err); 334 } 335 } 336 337 int qemu_socketpair(int domain, int type, int protocol, int sv[2]) 338 { 339 struct sockaddr_un addr = { 340 0, 341 }; 342 socklen_t socklen; 343 int listener = -1; 344 int client = -1; 345 int server = -1; 346 g_autofree char *path = NULL; 347 int tmpfd; 348 u_long arg; 349 int ret = -1; 350 351 g_return_val_if_fail(sv != NULL, -1); 352 353 addr.sun_family = AF_UNIX; 354 socklen = sizeof(addr); 355 356 tmpfd = g_file_open_tmp(NULL, &path, NULL); 357 if (tmpfd == -1 || !path) { 358 errno = EACCES; 359 goto out; 360 } 361 362 close(tmpfd); 363 364 if (strlen(path) >= sizeof(addr.sun_path)) { 365 errno = EINVAL; 366 goto out; 367 } 368 369 strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); 370 371 listener = socket(domain, type, protocol); 372 if (listener == -1) { 373 goto out; 374 } 375 376 if (DeleteFile(path) == 0 && GetLastError() != ERROR_FILE_NOT_FOUND) { 377 errno = EACCES; 378 goto out; 379 } 380 g_clear_pointer(&path, g_free); 381 382 if (bind(listener, (struct sockaddr *)&addr, socklen) == -1) { 383 goto out; 384 } 385 386 if (listen(listener, 1) == -1) { 387 goto out; 388 } 389 390 client = socket(domain, type, protocol); 391 if (client == -1) { 392 goto out; 393 } 394 395 arg = 1; 396 if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) { 397 goto out; 398 } 399 400 if (connect(client, (struct sockaddr *)&addr, socklen) == -1 && 401 WSAGetLastError() != WSAEWOULDBLOCK) { 402 goto out; 403 } 404 405 server = accept(listener, NULL, NULL); 406 if (server == -1) { 407 goto out; 408 } 409 410 arg = 0; 411 if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) { 412 goto out; 413 } 414 415 arg = 0; 416 if (ioctlsocket(client, SIO_AF_UNIX_GETPEERPID, &arg) != NO_ERROR) { 417 goto out; 418 } 419 420 if (arg != GetCurrentProcessId()) { 421 errno = EPERM; 422 goto out; 423 } 424 425 sv[0] = server; 426 server = -1; 427 sv[1] = client; 428 client = -1; 429 ret = 0; 430 431 out: 432 if (listener != -1) { 433 close(listener); 434 } 435 if (client != -1) { 436 close(client); 437 } 438 if (server != -1) { 439 close(server); 440 } 441 if (path) { 442 DeleteFile(path); 443 } 444 return ret; 445 } 446 447 #undef connect 448 int qemu_connect_wrap(int sockfd, const struct sockaddr *addr, 449 socklen_t addrlen) 450 { 451 int ret; 452 SOCKET s = _get_osfhandle(sockfd); 453 454 if (s == INVALID_SOCKET) { 455 return -1; 456 } 457 458 ret = connect(s, addr, addrlen); 459 if (ret < 0) { 460 if (WSAGetLastError() == WSAEWOULDBLOCK) { 461 errno = EINPROGRESS; 462 } else { 463 errno = socket_error(); 464 } 465 } 466 return ret; 467 } 468 469 470 #undef listen 471 int qemu_listen_wrap(int sockfd, int backlog) 472 { 473 int ret; 474 SOCKET s = _get_osfhandle(sockfd); 475 476 if (s == INVALID_SOCKET) { 477 return -1; 478 } 479 480 ret = listen(s, backlog); 481 if (ret < 0) { 482 errno = socket_error(); 483 } 484 return ret; 485 } 486 487 488 #undef bind 489 int qemu_bind_wrap(int sockfd, const struct sockaddr *addr, 490 socklen_t addrlen) 491 { 492 int ret; 493 SOCKET s = _get_osfhandle(sockfd); 494 495 if (s == INVALID_SOCKET) { 496 return -1; 497 } 498 499 ret = bind(s, addr, addrlen); 500 if (ret < 0) { 501 errno = socket_error(); 502 } 503 return ret; 504 } 505 506 QEMU_USED EXCEPTION_DISPOSITION 507 win32_close_exception_handler(struct _EXCEPTION_RECORD *exception_record, 508 void *registration, struct _CONTEXT *context, 509 void *dispatcher) 510 { 511 return EXCEPTION_EXECUTE_HANDLER; 512 } 513 514 #undef close 515 int qemu_close_socket_osfhandle(int fd) 516 { 517 SOCKET s = _get_osfhandle(fd); 518 DWORD flags = 0; 519 520 /* 521 * If we were to just call _close on the descriptor, it would close the 522 * HANDLE, but it wouldn't free any of the resources associated to the 523 * SOCKET, and we can't call _close after calling closesocket, because 524 * closesocket has already closed the HANDLE, and _close would attempt to 525 * close the HANDLE again, resulting in a double free. We can however 526 * protect the HANDLE from actually being closed long enough to close the 527 * file descriptor, then close the socket itself. 528 */ 529 if (!GetHandleInformation((HANDLE)s, &flags)) { 530 errno = EACCES; 531 return -1; 532 } 533 534 if (!SetHandleInformation((HANDLE)s, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE)) { 535 errno = EACCES; 536 return -1; 537 } 538 539 __try1(win32_close_exception_handler) { 540 /* 541 * close() returns EBADF since we PROTECT_FROM_CLOSE the underlying 542 * handle, but the FD is actually freed 543 */ 544 if (close(fd) < 0 && errno != EBADF) { 545 return -1; 546 } 547 } 548 __except1 { 549 } 550 551 if (!SetHandleInformation((HANDLE)s, flags, flags)) { 552 errno = EACCES; 553 return -1; 554 } 555 556 return 0; 557 } 558 559 int qemu_close_wrap(int fd) 560 { 561 SOCKET s = INVALID_SOCKET; 562 int ret = -1; 563 564 if (!fd_is_socket(fd)) { 565 return close(fd); 566 } 567 568 s = _get_osfhandle(fd); 569 qemu_close_socket_osfhandle(fd); 570 571 ret = closesocket(s); 572 if (ret < 0) { 573 errno = socket_error(); 574 } 575 576 return ret; 577 } 578 579 580 #undef socket 581 int qemu_socket_wrap(int domain, int type, int protocol) 582 { 583 SOCKET s; 584 int fd; 585 586 s = socket(domain, type, protocol); 587 if (s == -1) { 588 errno = socket_error(); 589 return -1; 590 } 591 592 fd = _open_osfhandle(s, _O_BINARY); 593 if (fd < 0) { 594 closesocket(s); 595 /* _open_osfhandle may not set errno, and closesocket() may override it */ 596 errno = ENOMEM; 597 } 598 599 return fd; 600 } 601 602 603 #undef accept 604 int qemu_accept_wrap(int sockfd, struct sockaddr *addr, 605 socklen_t *addrlen) 606 { 607 int fd; 608 SOCKET s = _get_osfhandle(sockfd); 609 610 if (s == INVALID_SOCKET) { 611 return -1; 612 } 613 614 s = accept(s, addr, addrlen); 615 if (s == -1) { 616 errno = socket_error(); 617 return -1; 618 } 619 620 fd = _open_osfhandle(s, _O_BINARY); 621 if (fd < 0) { 622 closesocket(s); 623 /* _open_osfhandle may not set errno, and closesocket() may override it */ 624 errno = ENOMEM; 625 } 626 627 return fd; 628 } 629 630 631 #undef shutdown 632 int qemu_shutdown_wrap(int sockfd, int how) 633 { 634 int ret; 635 SOCKET s = _get_osfhandle(sockfd); 636 637 if (s == INVALID_SOCKET) { 638 return -1; 639 } 640 641 ret = shutdown(s, how); 642 if (ret < 0) { 643 errno = socket_error(); 644 } 645 return ret; 646 } 647 648 649 #undef ioctlsocket 650 int qemu_ioctlsocket_wrap(int fd, int req, void *val) 651 { 652 int ret; 653 SOCKET s = _get_osfhandle(fd); 654 655 if (s == INVALID_SOCKET) { 656 return -1; 657 } 658 659 ret = ioctlsocket(s, req, val); 660 if (ret < 0) { 661 errno = socket_error(); 662 } 663 return ret; 664 } 665 666 667 #undef getsockopt 668 int qemu_getsockopt_wrap(int sockfd, int level, int optname, 669 void *optval, socklen_t *optlen) 670 { 671 int ret; 672 SOCKET s = _get_osfhandle(sockfd); 673 674 if (s == INVALID_SOCKET) { 675 return -1; 676 } 677 678 ret = getsockopt(s, level, optname, optval, optlen); 679 if (ret < 0) { 680 errno = socket_error(); 681 } 682 return ret; 683 } 684 685 686 #undef setsockopt 687 int qemu_setsockopt_wrap(int sockfd, int level, int optname, 688 const void *optval, socklen_t optlen) 689 { 690 int ret; 691 SOCKET s = _get_osfhandle(sockfd); 692 693 if (s == INVALID_SOCKET) { 694 return -1; 695 } 696 697 ret = setsockopt(s, level, optname, optval, optlen); 698 if (ret < 0) { 699 errno = socket_error(); 700 } 701 return ret; 702 } 703 704 705 #undef getpeername 706 int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr, 707 socklen_t *addrlen) 708 { 709 int ret; 710 SOCKET s = _get_osfhandle(sockfd); 711 712 if (s == INVALID_SOCKET) { 713 return -1; 714 } 715 716 ret = getpeername(s, addr, addrlen); 717 if (ret < 0) { 718 errno = socket_error(); 719 } 720 return ret; 721 } 722 723 724 #undef getsockname 725 int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr, 726 socklen_t *addrlen) 727 { 728 int ret; 729 SOCKET s = _get_osfhandle(sockfd); 730 731 if (s == INVALID_SOCKET) { 732 return -1; 733 } 734 735 ret = getsockname(s, addr, addrlen); 736 if (ret < 0) { 737 errno = socket_error(); 738 } 739 return ret; 740 } 741 742 743 #undef send 744 ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags) 745 { 746 int ret; 747 SOCKET s = _get_osfhandle(sockfd); 748 749 if (s == INVALID_SOCKET) { 750 return -1; 751 } 752 753 ret = send(s, buf, len, flags); 754 if (ret < 0) { 755 errno = socket_error(); 756 } 757 return ret; 758 } 759 760 761 #undef sendto 762 ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags, 763 const struct sockaddr *addr, socklen_t addrlen) 764 { 765 int ret; 766 SOCKET s = _get_osfhandle(sockfd); 767 768 if (s == INVALID_SOCKET) { 769 return -1; 770 } 771 772 ret = sendto(s, buf, len, flags, addr, addrlen); 773 if (ret < 0) { 774 errno = socket_error(); 775 } 776 return ret; 777 } 778 779 780 #undef recv 781 ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags) 782 { 783 int ret; 784 SOCKET s = _get_osfhandle(sockfd); 785 786 if (s == INVALID_SOCKET) { 787 return -1; 788 } 789 790 ret = recv(s, buf, len, flags); 791 if (ret < 0) { 792 errno = socket_error(); 793 } 794 return ret; 795 } 796 797 798 #undef recvfrom 799 ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags, 800 struct sockaddr *addr, socklen_t *addrlen) 801 { 802 int ret; 803 SOCKET s = _get_osfhandle(sockfd); 804 805 if (s == INVALID_SOCKET) { 806 return -1; 807 } 808 809 ret = recvfrom(s, buf, len, flags, addr, addrlen); 810 if (ret < 0) { 811 errno = socket_error(); 812 } 813 return ret; 814 } 815 816 bool qemu_write_pidfile(const char *filename, Error **errp) 817 { 818 char buffer[128]; 819 int len; 820 HANDLE file; 821 OVERLAPPED overlap; 822 BOOL ret; 823 memset(&overlap, 0, sizeof(overlap)); 824 825 file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, 826 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 827 828 if (file == INVALID_HANDLE_VALUE) { 829 error_setg(errp, "Failed to create PID file"); 830 return false; 831 } 832 len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid()); 833 ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len, 834 NULL, &overlap); 835 CloseHandle(file); 836 if (ret == 0) { 837 error_setg(errp, "Failed to write PID file"); 838 return false; 839 } 840 return true; 841 } 842 843 size_t qemu_get_host_physmem(void) 844 { 845 MEMORYSTATUSEX statex; 846 statex.dwLength = sizeof(statex); 847 848 if (GlobalMemoryStatusEx(&statex)) { 849 return statex.ullTotalPhys; 850 } 851 return 0; 852 } 853 854 int qemu_msync(void *addr, size_t length, int fd) 855 { 856 /** 857 * Perform the sync based on the file descriptor 858 * The sync range will most probably be wider than the one 859 * requested - but it will still get the job done 860 */ 861 return qemu_fdatasync(fd); 862 } 863 864 void *qemu_win32_map_alloc(size_t size, HANDLE *h, Error **errp) 865 { 866 void *bits; 867 868 trace_win32_map_alloc(size); 869 870 *h = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 871 size, NULL); 872 if (*h == NULL) { 873 error_setg_win32(errp, GetLastError(), "Failed to CreateFileMapping"); 874 return NULL; 875 } 876 877 bits = MapViewOfFile(*h, FILE_MAP_ALL_ACCESS, 0, 0, size); 878 if (bits == NULL) { 879 error_setg_win32(errp, GetLastError(), "Failed to MapViewOfFile"); 880 CloseHandle(*h); 881 return NULL; 882 } 883 884 return bits; 885 } 886 887 void qemu_win32_map_free(void *ptr, HANDLE h, Error **errp) 888 { 889 trace_win32_map_free(ptr, h); 890 891 if (UnmapViewOfFile(ptr) == 0) { 892 error_setg_win32(errp, GetLastError(), "Failed to UnmapViewOfFile"); 893 } 894 CloseHandle(h); 895 } 896 897 int qemu_shm_alloc(size_t size, Error **errp) 898 { 899 error_setg(errp, "Shared memory is not supported."); 900 return -1; 901 } 902