qemu

Форк
0
/
oslib-win32.c 
879 строк · 19.2 Кб
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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.