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 void qemu_socket_set_block(int fd) 181 { 182 unsigned long opt = 0; 183 qemu_socket_unselect(fd, NULL); 184 ioctlsocket(fd, FIONBIO, &opt); 185 } 186 187 int qemu_socket_try_set_nonblock(int fd) 188 { 189 unsigned long opt = 1; 190 if (ioctlsocket(fd, FIONBIO, &opt) != NO_ERROR) { 191 return -socket_error(); 192 } 193 return 0; 194 } 195 196 void qemu_socket_set_nonblock(int fd) 197 { 198 (void)qemu_socket_try_set_nonblock(fd); 199 } 200 201 int socket_set_fast_reuse(int fd) 202 { 203 /* Enabling the reuse of an endpoint that was used by a socket still in 204 * TIME_WAIT state is usually performed by setting SO_REUSEADDR. On Windows 205 * fast reuse is the default and SO_REUSEADDR does strange things. So we 206 * don't have to do anything here. More info can be found at: 207 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms740621.aspx */ 208 return 0; 209 } 210 211 int inet_aton(const char *cp, struct in_addr *ia) 212 { 213 uint32_t addr = inet_addr(cp); 214 if (addr == 0xffffffff) { 215 return 0; 216 } 217 ia->s_addr = addr; 218 return 1; 219 } 220 221 void qemu_set_cloexec(int fd) 222 { 223 } 224 225 int qemu_get_thread_id(void) 226 { 227 return GetCurrentThreadId(); 228 } 229 230 char * 231 qemu_get_local_state_dir(void) 232 { 233 const char * const *data_dirs = g_get_system_data_dirs(); 234 235 g_assert(data_dirs && data_dirs[0]); 236 237 return g_strdup(data_dirs[0]); 238 } 239 240 void qemu_set_tty_echo(int fd, bool echo) 241 { 242 HANDLE handle = (HANDLE)_get_osfhandle(fd); 243 DWORD dwMode = 0; 244 245 if (handle == INVALID_HANDLE_VALUE) { 246 return; 247 } 248 249 GetConsoleMode(handle, &dwMode); 250 251 if (echo) { 252 SetConsoleMode(handle, dwMode | ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT); 253 } else { 254 SetConsoleMode(handle, 255 dwMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT)); 256 } 257 } 258 259 int getpagesize(void) 260 { 261 SYSTEM_INFO system_info; 262 263 GetSystemInfo(&system_info); 264 return system_info.dwPageSize; 265 } 266 267 bool qemu_prealloc_mem(int fd, char *area, size_t sz, int max_threads, 268 ThreadContext *tc, bool async, Error **errp) 269 { 270 int i; 271 size_t pagesize = qemu_real_host_page_size(); 272 273 sz = (sz + pagesize - 1) & -pagesize; 274 for (i = 0; i < sz / pagesize; i++) { 275 memset(area + pagesize * i, 0, 1); 276 } 277 278 return true; 279 } 280 281 bool qemu_finish_async_prealloc_mem(Error **errp) 282 { 283 /* async prealloc not supported, there is nothing to finish */ 284 return true; 285 } 286 287 char *qemu_get_pid_name(pid_t pid) 288 { 289 /* XXX Implement me */ 290 abort(); 291 } 292 293 294 bool qemu_socket_select(int sockfd, WSAEVENT hEventObject, 295 long lNetworkEvents, Error **errp) 296 { 297 SOCKET s = _get_osfhandle(sockfd); 298 299 if (errp == NULL) { 300 errp = &error_warn; 301 } 302 303 if (s == INVALID_SOCKET) { 304 error_setg(errp, "invalid socket fd=%d", sockfd); 305 return false; 306 } 307 308 if (WSAEventSelect(s, hEventObject, lNetworkEvents) != 0) { 309 error_setg_win32(errp, WSAGetLastError(), "failed to WSAEventSelect()"); 310 return false; 311 } 312 313 return true; 314 } 315 316 bool qemu_socket_unselect(int sockfd, Error **errp) 317 { 318 return qemu_socket_select(sockfd, NULL, 0, errp); 319 } 320 321 int qemu_socketpair(int domain, int type, int protocol, int sv[2]) 322 { 323 struct sockaddr_un addr = { 324 0, 325 }; 326 socklen_t socklen; 327 int listener = -1; 328 int client = -1; 329 int server = -1; 330 g_autofree char *path = NULL; 331 int tmpfd; 332 u_long arg; 333 int ret = -1; 334 335 g_return_val_if_fail(sv != NULL, -1); 336 337 addr.sun_family = AF_UNIX; 338 socklen = sizeof(addr); 339 340 tmpfd = g_file_open_tmp(NULL, &path, NULL); 341 if (tmpfd == -1 || !path) { 342 errno = EACCES; 343 goto out; 344 } 345 346 close(tmpfd); 347 348 if (strlen(path) >= sizeof(addr.sun_path)) { 349 errno = EINVAL; 350 goto out; 351 } 352 353 strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1); 354 355 listener = socket(domain, type, protocol); 356 if (listener == -1) { 357 goto out; 358 } 359 360 if (DeleteFile(path) == 0 && GetLastError() != ERROR_FILE_NOT_FOUND) { 361 errno = EACCES; 362 goto out; 363 } 364 g_clear_pointer(&path, g_free); 365 366 if (bind(listener, (struct sockaddr *)&addr, socklen) == -1) { 367 goto out; 368 } 369 370 if (listen(listener, 1) == -1) { 371 goto out; 372 } 373 374 client = socket(domain, type, protocol); 375 if (client == -1) { 376 goto out; 377 } 378 379 arg = 1; 380 if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) { 381 goto out; 382 } 383 384 if (connect(client, (struct sockaddr *)&addr, socklen) == -1 && 385 WSAGetLastError() != WSAEWOULDBLOCK) { 386 goto out; 387 } 388 389 server = accept(listener, NULL, NULL); 390 if (server == -1) { 391 goto out; 392 } 393 394 arg = 0; 395 if (ioctlsocket(client, FIONBIO, &arg) != NO_ERROR) { 396 goto out; 397 } 398 399 arg = 0; 400 if (ioctlsocket(client, SIO_AF_UNIX_GETPEERPID, &arg) != NO_ERROR) { 401 goto out; 402 } 403 404 if (arg != GetCurrentProcessId()) { 405 errno = EPERM; 406 goto out; 407 } 408 409 sv[0] = server; 410 server = -1; 411 sv[1] = client; 412 client = -1; 413 ret = 0; 414 415 out: 416 if (listener != -1) { 417 close(listener); 418 } 419 if (client != -1) { 420 close(client); 421 } 422 if (server != -1) { 423 close(server); 424 } 425 if (path) { 426 DeleteFile(path); 427 } 428 return ret; 429 } 430 431 #undef connect 432 int qemu_connect_wrap(int sockfd, const struct sockaddr *addr, 433 socklen_t addrlen) 434 { 435 int ret; 436 SOCKET s = _get_osfhandle(sockfd); 437 438 if (s == INVALID_SOCKET) { 439 return -1; 440 } 441 442 ret = connect(s, addr, addrlen); 443 if (ret < 0) { 444 if (WSAGetLastError() == WSAEWOULDBLOCK) { 445 errno = EINPROGRESS; 446 } else { 447 errno = socket_error(); 448 } 449 } 450 return ret; 451 } 452 453 454 #undef listen 455 int qemu_listen_wrap(int sockfd, int backlog) 456 { 457 int ret; 458 SOCKET s = _get_osfhandle(sockfd); 459 460 if (s == INVALID_SOCKET) { 461 return -1; 462 } 463 464 ret = listen(s, backlog); 465 if (ret < 0) { 466 errno = socket_error(); 467 } 468 return ret; 469 } 470 471 472 #undef bind 473 int qemu_bind_wrap(int sockfd, const struct sockaddr *addr, 474 socklen_t addrlen) 475 { 476 int ret; 477 SOCKET s = _get_osfhandle(sockfd); 478 479 if (s == INVALID_SOCKET) { 480 return -1; 481 } 482 483 ret = bind(s, addr, addrlen); 484 if (ret < 0) { 485 errno = socket_error(); 486 } 487 return ret; 488 } 489 490 QEMU_USED EXCEPTION_DISPOSITION 491 win32_close_exception_handler(struct _EXCEPTION_RECORD *exception_record, 492 void *registration, struct _CONTEXT *context, 493 void *dispatcher) 494 { 495 return EXCEPTION_EXECUTE_HANDLER; 496 } 497 498 #undef close 499 int qemu_close_socket_osfhandle(int fd) 500 { 501 SOCKET s = _get_osfhandle(fd); 502 DWORD flags = 0; 503 504 /* 505 * If we were to just call _close on the descriptor, it would close the 506 * HANDLE, but it wouldn't free any of the resources associated to the 507 * SOCKET, and we can't call _close after calling closesocket, because 508 * closesocket has already closed the HANDLE, and _close would attempt to 509 * close the HANDLE again, resulting in a double free. We can however 510 * protect the HANDLE from actually being closed long enough to close the 511 * file descriptor, then close the socket itself. 512 */ 513 if (!GetHandleInformation((HANDLE)s, &flags)) { 514 errno = EACCES; 515 return -1; 516 } 517 518 if (!SetHandleInformation((HANDLE)s, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE)) { 519 errno = EACCES; 520 return -1; 521 } 522 523 __try1(win32_close_exception_handler) { 524 /* 525 * close() returns EBADF since we PROTECT_FROM_CLOSE the underlying 526 * handle, but the FD is actually freed 527 */ 528 if (close(fd) < 0 && errno != EBADF) { 529 return -1; 530 } 531 } 532 __except1 { 533 } 534 535 if (!SetHandleInformation((HANDLE)s, flags, flags)) { 536 errno = EACCES; 537 return -1; 538 } 539 540 return 0; 541 } 542 543 int qemu_close_wrap(int fd) 544 { 545 SOCKET s = INVALID_SOCKET; 546 int ret = -1; 547 548 if (!fd_is_socket(fd)) { 549 return close(fd); 550 } 551 552 s = _get_osfhandle(fd); 553 qemu_close_socket_osfhandle(fd); 554 555 ret = closesocket(s); 556 if (ret < 0) { 557 errno = socket_error(); 558 } 559 560 return ret; 561 } 562 563 564 #undef socket 565 int qemu_socket_wrap(int domain, int type, int protocol) 566 { 567 SOCKET s; 568 int fd; 569 570 s = socket(domain, type, protocol); 571 if (s == -1) { 572 errno = socket_error(); 573 return -1; 574 } 575 576 fd = _open_osfhandle(s, _O_BINARY); 577 if (fd < 0) { 578 closesocket(s); 579 /* _open_osfhandle may not set errno, and closesocket() may override it */ 580 errno = ENOMEM; 581 } 582 583 return fd; 584 } 585 586 587 #undef accept 588 int qemu_accept_wrap(int sockfd, struct sockaddr *addr, 589 socklen_t *addrlen) 590 { 591 int fd; 592 SOCKET s = _get_osfhandle(sockfd); 593 594 if (s == INVALID_SOCKET) { 595 return -1; 596 } 597 598 s = accept(s, addr, addrlen); 599 if (s == -1) { 600 errno = socket_error(); 601 return -1; 602 } 603 604 fd = _open_osfhandle(s, _O_BINARY); 605 if (fd < 0) { 606 closesocket(s); 607 /* _open_osfhandle may not set errno, and closesocket() may override it */ 608 errno = ENOMEM; 609 } 610 611 return fd; 612 } 613 614 615 #undef shutdown 616 int qemu_shutdown_wrap(int sockfd, int how) 617 { 618 int ret; 619 SOCKET s = _get_osfhandle(sockfd); 620 621 if (s == INVALID_SOCKET) { 622 return -1; 623 } 624 625 ret = shutdown(s, how); 626 if (ret < 0) { 627 errno = socket_error(); 628 } 629 return ret; 630 } 631 632 633 #undef ioctlsocket 634 int qemu_ioctlsocket_wrap(int fd, int req, void *val) 635 { 636 int ret; 637 SOCKET s = _get_osfhandle(fd); 638 639 if (s == INVALID_SOCKET) { 640 return -1; 641 } 642 643 ret = ioctlsocket(s, req, val); 644 if (ret < 0) { 645 errno = socket_error(); 646 } 647 return ret; 648 } 649 650 651 #undef getsockopt 652 int qemu_getsockopt_wrap(int sockfd, int level, int optname, 653 void *optval, socklen_t *optlen) 654 { 655 int ret; 656 SOCKET s = _get_osfhandle(sockfd); 657 658 if (s == INVALID_SOCKET) { 659 return -1; 660 } 661 662 ret = getsockopt(s, level, optname, optval, optlen); 663 if (ret < 0) { 664 errno = socket_error(); 665 } 666 return ret; 667 } 668 669 670 #undef setsockopt 671 int qemu_setsockopt_wrap(int sockfd, int level, int optname, 672 const void *optval, socklen_t optlen) 673 { 674 int ret; 675 SOCKET s = _get_osfhandle(sockfd); 676 677 if (s == INVALID_SOCKET) { 678 return -1; 679 } 680 681 ret = setsockopt(s, level, optname, optval, optlen); 682 if (ret < 0) { 683 errno = socket_error(); 684 } 685 return ret; 686 } 687 688 689 #undef getpeername 690 int qemu_getpeername_wrap(int sockfd, struct sockaddr *addr, 691 socklen_t *addrlen) 692 { 693 int ret; 694 SOCKET s = _get_osfhandle(sockfd); 695 696 if (s == INVALID_SOCKET) { 697 return -1; 698 } 699 700 ret = getpeername(s, addr, addrlen); 701 if (ret < 0) { 702 errno = socket_error(); 703 } 704 return ret; 705 } 706 707 708 #undef getsockname 709 int qemu_getsockname_wrap(int sockfd, struct sockaddr *addr, 710 socklen_t *addrlen) 711 { 712 int ret; 713 SOCKET s = _get_osfhandle(sockfd); 714 715 if (s == INVALID_SOCKET) { 716 return -1; 717 } 718 719 ret = getsockname(s, addr, addrlen); 720 if (ret < 0) { 721 errno = socket_error(); 722 } 723 return ret; 724 } 725 726 727 #undef send 728 ssize_t qemu_send_wrap(int sockfd, const void *buf, size_t len, int flags) 729 { 730 int ret; 731 SOCKET s = _get_osfhandle(sockfd); 732 733 if (s == INVALID_SOCKET) { 734 return -1; 735 } 736 737 ret = send(s, buf, len, flags); 738 if (ret < 0) { 739 errno = socket_error(); 740 } 741 return ret; 742 } 743 744 745 #undef sendto 746 ssize_t qemu_sendto_wrap(int sockfd, const void *buf, size_t len, int flags, 747 const struct sockaddr *addr, socklen_t addrlen) 748 { 749 int ret; 750 SOCKET s = _get_osfhandle(sockfd); 751 752 if (s == INVALID_SOCKET) { 753 return -1; 754 } 755 756 ret = sendto(s, buf, len, flags, addr, addrlen); 757 if (ret < 0) { 758 errno = socket_error(); 759 } 760 return ret; 761 } 762 763 764 #undef recv 765 ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags) 766 { 767 int ret; 768 SOCKET s = _get_osfhandle(sockfd); 769 770 if (s == INVALID_SOCKET) { 771 return -1; 772 } 773 774 ret = recv(s, buf, len, flags); 775 if (ret < 0) { 776 errno = socket_error(); 777 } 778 return ret; 779 } 780 781 782 #undef recvfrom 783 ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags, 784 struct sockaddr *addr, socklen_t *addrlen) 785 { 786 int ret; 787 SOCKET s = _get_osfhandle(sockfd); 788 789 if (s == INVALID_SOCKET) { 790 return -1; 791 } 792 793 ret = recvfrom(s, buf, len, flags, addr, addrlen); 794 if (ret < 0) { 795 errno = socket_error(); 796 } 797 return ret; 798 } 799 800 bool qemu_write_pidfile(const char *filename, Error **errp) 801 { 802 char buffer[128]; 803 int len; 804 HANDLE file; 805 OVERLAPPED overlap; 806 BOOL ret; 807 memset(&overlap, 0, sizeof(overlap)); 808 809 file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL, 810 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 811 812 if (file == INVALID_HANDLE_VALUE) { 813 error_setg(errp, "Failed to create PID file"); 814 return false; 815 } 816 len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", (pid_t)getpid()); 817 ret = WriteFile(file, (LPCVOID)buffer, (DWORD)len, 818 NULL, &overlap); 819 CloseHandle(file); 820 if (ret == 0) { 821 error_setg(errp, "Failed to write PID file"); 822 return false; 823 } 824 return true; 825 } 826 827 size_t qemu_get_host_physmem(void) 828 { 829 MEMORYSTATUSEX statex; 830 statex.dwLength = sizeof(statex); 831 832 if (GlobalMemoryStatusEx(&statex)) { 833 return statex.ullTotalPhys; 834 } 835 return 0; 836 } 837 838 int qemu_msync(void *addr, size_t length, int fd) 839 { 840 /** 841 * Perform the sync based on the file descriptor 842 * The sync range will most probably be wider than the one 843 * requested - but it will still get the job done 844 */ 845 return qemu_fdatasync(fd); 846 } 847 848 void *qemu_win32_map_alloc(size_t size, HANDLE *h, Error **errp) 849 { 850 void *bits; 851 852 trace_win32_map_alloc(size); 853 854 *h = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 855 size, NULL); 856 if (*h == NULL) { 857 error_setg_win32(errp, GetLastError(), "Failed to CreateFileMapping"); 858 return NULL; 859 } 860 861 bits = MapViewOfFile(*h, FILE_MAP_ALL_ACCESS, 0, 0, size); 862 if (bits == NULL) { 863 error_setg_win32(errp, GetLastError(), "Failed to MapViewOfFile"); 864 CloseHandle(*h); 865 return NULL; 866 } 867 868 return bits; 869 } 870 871 void qemu_win32_map_free(void *ptr, HANDLE h, Error **errp) 872 { 873 trace_win32_map_free(ptr, h); 874 875 if (UnmapViewOfFile(ptr) == 0) { 876 error_setg_win32(errp, GetLastError(), "Failed to UnmapViewOfFile"); 877 } 878 CloseHandle(h); 879 } 880