Check ELF binaries for machine type and endianness.
[qemu] / block-raw.c
1 /*
2  * Block driver for RAW files
3  * 
4  * Copyright (c) 2006 Fabrice Bellard
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "vl.h"
25 #include "block_int.h"
26 #include <assert.h>
27 #ifndef _WIN32
28 #include <aio.h>
29
30 #ifndef QEMU_TOOL
31 #include "exec-all.h"
32 #endif
33
34 #ifdef CONFIG_COCOA
35 #include <paths.h>
36 #include <sys/param.h>
37 #include <IOKit/IOKitLib.h>
38 #include <IOKit/IOBSD.h>
39 #include <IOKit/storage/IOMediaBSDClient.h>
40 #include <IOKit/storage/IOMedia.h>
41 #include <IOKit/storage/IOCDMedia.h>
42 //#include <IOKit/storage/IOCDTypes.h>
43 #include <CoreFoundation/CoreFoundation.h>
44 #endif
45
46 #ifdef __sun__
47 #include <sys/dkio.h>
48 #endif
49 #ifdef __linux__
50 #include <sys/ioctl.h>
51 #include <linux/cdrom.h>
52 #include <linux/fd.h>
53 #endif
54 #ifdef __FreeBSD__
55 #include <sys/disk.h>
56 #endif
57
58 //#define DEBUG_FLOPPY
59
60 #define FTYPE_FILE   0
61 #define FTYPE_CD     1
62 #define FTYPE_FD     2
63
64 /* if the FD is not accessed during that time (in ms), we try to
65    reopen it to see if the disk has been changed */
66 #define FD_OPEN_TIMEOUT 1000
67
68 typedef struct BDRVRawState {
69     int fd;
70     int type;
71 #if defined(__linux__)
72     /* linux floppy specific */
73     int fd_open_flags;
74     int64_t fd_open_time;
75     int64_t fd_error_time;
76     int fd_got_error;
77     int fd_media_changed;
78 #endif
79 } BDRVRawState;
80
81 static int fd_open(BlockDriverState *bs);
82
83 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
84 {
85     BDRVRawState *s = bs->opaque;
86     int fd, open_flags, ret;
87
88     open_flags = O_BINARY;
89     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
90         open_flags |= O_RDWR;
91     } else {
92         open_flags |= O_RDONLY;
93         bs->read_only = 1;
94     }
95     if (flags & BDRV_O_CREAT)
96         open_flags |= O_CREAT | O_TRUNC;
97
98     s->type = FTYPE_FILE;
99
100     fd = open(filename, open_flags, 0644);
101     if (fd < 0) {
102         ret = -errno;
103         if (ret == -EROFS)
104             ret = -EACCES;
105         return ret;
106     }
107     s->fd = fd;
108     return 0;
109 }
110
111 /* XXX: use host sector size if necessary with:
112 #ifdef DIOCGSECTORSIZE
113         {
114             unsigned int sectorsize = 512;
115             if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
116                 sectorsize > bufsize)
117                 bufsize = sectorsize;
118         }
119 #endif
120 #ifdef CONFIG_COCOA
121         u_int32_t   blockSize = 512;
122         if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
123             bufsize = blockSize;
124         }
125 #endif
126 */
127
128 static int raw_pread(BlockDriverState *bs, int64_t offset, 
129                      uint8_t *buf, int count)
130 {
131     BDRVRawState *s = bs->opaque;
132     int ret;
133     
134     ret = fd_open(bs);
135     if (ret < 0)
136         return ret;
137
138     lseek(s->fd, offset, SEEK_SET);
139     ret = read(s->fd, buf, count);
140     return ret;
141 }
142
143 static int raw_pwrite(BlockDriverState *bs, int64_t offset, 
144                       const uint8_t *buf, int count)
145 {
146     BDRVRawState *s = bs->opaque;
147     int ret;
148     
149     ret = fd_open(bs);
150     if (ret < 0)
151         return ret;
152
153     lseek(s->fd, offset, SEEK_SET);
154     ret = write(s->fd, buf, count);
155     return ret;
156 }
157
158 /***********************************************************/
159 /* Unix AIO using POSIX AIO */
160
161 typedef struct RawAIOCB {
162     BlockDriverAIOCB common;
163     struct aiocb aiocb;
164     struct RawAIOCB *next;
165 } RawAIOCB;
166
167 static int aio_sig_num = SIGUSR2;
168 static RawAIOCB *first_aio; /* AIO issued */
169 static int aio_initialized = 0;
170
171 static void aio_signal_handler(int signum)
172 {
173 #ifndef QEMU_TOOL
174     CPUState *env = cpu_single_env;
175     if (env) {
176         /* stop the currently executing cpu because a timer occured */
177         cpu_interrupt(env, CPU_INTERRUPT_EXIT);
178 #ifdef USE_KQEMU
179         if (env->kqemu_enabled) {
180             kqemu_cpu_interrupt(env);
181         }
182 #endif
183     }
184 #endif
185 }
186
187 void qemu_aio_init(void)
188 {
189     struct sigaction act;
190
191     aio_initialized = 1;
192     
193     sigfillset(&act.sa_mask);
194     act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
195     act.sa_handler = aio_signal_handler;
196     sigaction(aio_sig_num, &act, NULL);
197
198 #if defined(__GLIBC__) && defined(__linux__)
199     {
200         /* XXX: aio thread exit seems to hang on RedHat 9 and this init
201            seems to fix the problem. */
202         struct aioinit ai;
203         memset(&ai, 0, sizeof(ai));
204         ai.aio_threads = 1;
205         ai.aio_num = 1;
206         ai.aio_idle_time = 365 * 100000;
207         aio_init(&ai);
208     }
209 #endif
210 }
211
212 void qemu_aio_poll(void)
213 {
214     RawAIOCB *acb, **pacb;
215     int ret;
216
217     for(;;) {
218         pacb = &first_aio;
219         for(;;) {
220             acb = *pacb;
221             if (!acb)
222                 goto the_end;
223             ret = aio_error(&acb->aiocb);
224             if (ret == ECANCELED) {
225                 /* remove the request */
226                 *pacb = acb->next;
227                 qemu_aio_release(acb);
228             } else if (ret != EINPROGRESS) {
229                 /* end of aio */
230                 if (ret == 0) {
231                     ret = aio_return(&acb->aiocb);
232                     if (ret == acb->aiocb.aio_nbytes)
233                         ret = 0;
234                     else
235                         ret = -EINVAL;
236                 } else {
237                     ret = -ret;
238                 }
239                 /* remove the request */
240                 *pacb = acb->next;
241                 /* call the callback */
242                 acb->common.cb(acb->common.opaque, ret);
243                 qemu_aio_release(acb);
244                 break;
245             } else {
246                 pacb = &acb->next;
247             }
248         }
249     }
250  the_end: ;
251 }
252
253 /* Wait for all IO requests to complete.  */
254 void qemu_aio_flush(void)
255 {
256     qemu_aio_wait_start();
257     qemu_aio_poll();
258     while (first_aio) {
259         qemu_aio_wait();
260     }
261     qemu_aio_wait_end();
262 }
263
264 /* wait until at least one AIO was handled */
265 static sigset_t wait_oset;
266
267 void qemu_aio_wait_start(void)
268 {
269     sigset_t set;
270
271     if (!aio_initialized)
272         qemu_aio_init();
273     sigemptyset(&set);
274     sigaddset(&set, aio_sig_num);
275     sigprocmask(SIG_BLOCK, &set, &wait_oset);
276 }
277
278 void qemu_aio_wait(void)
279 {
280     sigset_t set;
281     int nb_sigs;
282
283 #ifndef QEMU_TOOL
284     if (qemu_bh_poll())
285         return;
286 #endif
287     sigemptyset(&set);
288     sigaddset(&set, aio_sig_num);
289     sigwait(&set, &nb_sigs);
290     qemu_aio_poll();
291 }
292
293 void qemu_aio_wait_end(void)
294 {
295     sigprocmask(SIG_SETMASK, &wait_oset, NULL);
296 }
297
298 static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
299         int64_t sector_num, uint8_t *buf, int nb_sectors,
300         BlockDriverCompletionFunc *cb, void *opaque)
301 {
302     BDRVRawState *s = bs->opaque;
303     RawAIOCB *acb;
304
305     if (fd_open(bs) < 0)
306         return NULL;
307
308     acb = qemu_aio_get(bs, cb, opaque);
309     if (!acb)
310         return NULL;
311     acb->aiocb.aio_fildes = s->fd;
312     acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
313     acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
314     acb->aiocb.aio_buf = buf;
315     acb->aiocb.aio_nbytes = nb_sectors * 512;
316     acb->aiocb.aio_offset = sector_num * 512;
317     acb->next = first_aio;
318     first_aio = acb;
319     return acb;
320 }
321
322 static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
323         int64_t sector_num, uint8_t *buf, int nb_sectors,
324         BlockDriverCompletionFunc *cb, void *opaque)
325 {
326     RawAIOCB *acb;
327
328     acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
329     if (!acb)
330         return NULL;
331     if (aio_read(&acb->aiocb) < 0) {
332         qemu_aio_release(acb);
333         return NULL;
334     } 
335     return &acb->common;
336 }
337
338 static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
339         int64_t sector_num, const uint8_t *buf, int nb_sectors,
340         BlockDriverCompletionFunc *cb, void *opaque)
341 {
342     RawAIOCB *acb;
343
344     acb = raw_aio_setup(bs, sector_num, (uint8_t*)buf, nb_sectors, cb, opaque);
345     if (!acb)
346         return NULL;
347     if (aio_write(&acb->aiocb) < 0) {
348         qemu_aio_release(acb);
349         return NULL;
350     } 
351     return &acb->common;
352 }
353
354 static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
355 {
356     int ret;
357     RawAIOCB *acb = (RawAIOCB *)blockacb;
358     RawAIOCB **pacb;
359
360     ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
361     if (ret == AIO_NOTCANCELED) {
362         /* fail safe: if the aio could not be canceled, we wait for
363            it */
364         while (aio_error(&acb->aiocb) == EINPROGRESS);
365     }
366
367     /* remove the callback from the queue */
368     pacb = &first_aio;
369     for(;;) {
370         if (*pacb == NULL) {
371             break;
372         } else if (*pacb == acb) {
373             *pacb = acb->next;
374             qemu_aio_release(acb);
375             break;
376         }
377         pacb = &acb->next;
378     }
379 }
380
381 static void raw_close(BlockDriverState *bs)
382 {
383     BDRVRawState *s = bs->opaque;
384     if (s->fd >= 0) {
385         close(s->fd);
386         s->fd = -1;
387     }
388 }
389
390 static int raw_truncate(BlockDriverState *bs, int64_t offset)
391 {
392     BDRVRawState *s = bs->opaque;
393     if (s->type != FTYPE_FILE)
394         return -ENOTSUP;
395     if (ftruncate(s->fd, offset) < 0)
396         return -errno;
397     return 0;
398 }
399
400 static int64_t  raw_getlength(BlockDriverState *bs)
401 {
402     BDRVRawState *s = bs->opaque;
403     int fd = s->fd;
404     int64_t size;
405 #ifdef _BSD
406     struct stat sb;
407 #endif
408 #ifdef __sun__
409     struct dk_minfo minfo;
410     int rv;
411 #endif
412     int ret;
413
414     ret = fd_open(bs);
415     if (ret < 0)
416         return ret;
417
418 #ifdef _BSD
419     if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
420 #ifdef DIOCGMEDIASIZE
421         if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
422 #endif
423 #ifdef CONFIG_COCOA
424         size = LONG_LONG_MAX;
425 #else
426         size = lseek(fd, 0LL, SEEK_END);
427 #endif
428     } else
429 #endif
430 #ifdef __sun__
431     /*
432      * use the DKIOCGMEDIAINFO ioctl to read the size.
433      */
434     rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
435     if ( rv != -1 ) {
436         size = minfo.dki_lbsize * minfo.dki_capacity;
437     } else /* there are reports that lseek on some devices
438               fails, but irc discussion said that contingency
439               on contingency was overkill */
440 #endif
441     {
442         size = lseek(fd, 0, SEEK_END);
443     }
444     return size;
445 }
446
447 static int raw_create(const char *filename, int64_t total_size,
448                       const char *backing_file, int flags)
449 {
450     int fd;
451
452     if (flags || backing_file)
453         return -ENOTSUP;
454
455     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 
456               0644);
457     if (fd < 0)
458         return -EIO;
459     ftruncate(fd, total_size * 512);
460     close(fd);
461     return 0;
462 }
463
464 static void raw_flush(BlockDriverState *bs)
465 {
466     BDRVRawState *s = bs->opaque;
467     fsync(s->fd);
468 }
469
470 BlockDriver bdrv_raw = {
471     "raw",
472     sizeof(BDRVRawState),
473     NULL, /* no probe for protocols */
474     raw_open,
475     NULL,
476     NULL,
477     raw_close,
478     raw_create,
479     raw_flush,
480     
481     .bdrv_aio_read = raw_aio_read,
482     .bdrv_aio_write = raw_aio_write,
483     .bdrv_aio_cancel = raw_aio_cancel,
484     .aiocb_size = sizeof(RawAIOCB),
485     .protocol_name = "file",
486     .bdrv_pread = raw_pread,
487     .bdrv_pwrite = raw_pwrite,
488     .bdrv_truncate = raw_truncate,
489     .bdrv_getlength = raw_getlength,
490 };
491
492 /***********************************************/
493 /* host device */
494
495 #ifdef CONFIG_COCOA
496 static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
497 static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
498
499 kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
500 {
501     kern_return_t       kernResult; 
502     mach_port_t     masterPort;
503     CFMutableDictionaryRef  classesToMatch;
504
505     kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
506     if ( KERN_SUCCESS != kernResult ) {
507         printf( "IOMasterPort returned %d\n", kernResult );
508     }
509     
510     classesToMatch = IOServiceMatching( kIOCDMediaClass ); 
511     if ( classesToMatch == NULL ) {
512         printf( "IOServiceMatching returned a NULL dictionary.\n" );
513     } else {
514     CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
515     }
516     kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
517     if ( KERN_SUCCESS != kernResult )
518     {
519         printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
520     }
521     
522     return kernResult;
523 }
524
525 kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
526 {
527     io_object_t     nextMedia;
528     kern_return_t   kernResult = KERN_FAILURE;
529     *bsdPath = '\0';
530     nextMedia = IOIteratorNext( mediaIterator );
531     if ( nextMedia )
532     {
533         CFTypeRef   bsdPathAsCFString;
534     bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
535         if ( bsdPathAsCFString ) {
536             size_t devPathLength;
537             strcpy( bsdPath, _PATH_DEV );
538             strcat( bsdPath, "r" );
539             devPathLength = strlen( bsdPath );
540             if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
541                 kernResult = KERN_SUCCESS;
542             }
543             CFRelease( bsdPathAsCFString );
544         }
545         IOObjectRelease( nextMedia );
546     }
547     
548     return kernResult;
549 }
550
551 #endif
552
553 static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
554 {
555     BDRVRawState *s = bs->opaque;
556     int fd, open_flags, ret;
557
558 #ifdef CONFIG_COCOA
559     if (strstart(filename, "/dev/cdrom", NULL)) {
560         kern_return_t kernResult;
561         io_iterator_t mediaIterator;
562         char bsdPath[ MAXPATHLEN ];
563         int fd;
564  
565         kernResult = FindEjectableCDMedia( &mediaIterator );
566         kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
567     
568         if ( bsdPath[ 0 ] != '\0' ) {
569             strcat(bsdPath,"s0");
570             /* some CDs don't have a partition 0 */
571             fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
572             if (fd < 0) {
573                 bsdPath[strlen(bsdPath)-1] = '1';
574             } else {
575                 close(fd);
576             }
577             filename = bsdPath;
578         }
579         
580         if ( mediaIterator )
581             IOObjectRelease( mediaIterator );
582     }
583 #endif
584     open_flags = O_BINARY;
585     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
586         open_flags |= O_RDWR;
587     } else {
588         open_flags |= O_RDONLY;
589         bs->read_only = 1;
590     }
591
592     s->type = FTYPE_FILE;
593 #if defined(__linux__)
594     if (strstart(filename, "/dev/cd", NULL)) {
595         /* open will not fail even if no CD is inserted */
596         open_flags |= O_NONBLOCK;
597         s->type = FTYPE_CD;
598     } else if (strstart(filename, "/dev/fd", NULL)) {
599         s->type = FTYPE_FD;
600         s->fd_open_flags = open_flags;
601         /* open will not fail even if no floppy is inserted */
602         open_flags |= O_NONBLOCK;
603     }
604 #endif
605     fd = open(filename, open_flags, 0644);
606     if (fd < 0) {
607         ret = -errno;
608         if (ret == -EROFS)
609             ret = -EACCES;
610         return ret;
611     }
612     s->fd = fd;
613 #if defined(__linux__)
614     /* close fd so that we can reopen it as needed */
615     if (s->type == FTYPE_FD) {
616         close(s->fd);
617         s->fd = -1;
618         s->fd_media_changed = 1;
619     }
620 #endif
621     return 0;
622 }
623
624 #if defined(__linux__) && !defined(QEMU_TOOL)
625
626 /* Note: we do not have a reliable method to detect if the floppy is
627    present. The current method is to try to open the floppy at every
628    I/O and to keep it opened during a few hundreds of ms. */
629 static int fd_open(BlockDriverState *bs)
630 {
631     BDRVRawState *s = bs->opaque;
632     int last_media_present;
633
634     if (s->type != FTYPE_FD)
635         return 0;
636     last_media_present = (s->fd >= 0);
637     if (s->fd >= 0 && 
638         (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
639         close(s->fd);
640         s->fd = -1;
641 #ifdef DEBUG_FLOPPY
642         printf("Floppy closed\n");
643 #endif
644     }
645     if (s->fd < 0) {
646         if (s->fd_got_error && 
647             (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
648 #ifdef DEBUG_FLOPPY
649             printf("No floppy (open delayed)\n");
650 #endif
651             return -EIO;
652         }
653         s->fd = open(bs->filename, s->fd_open_flags);
654         if (s->fd < 0) {
655             s->fd_error_time = qemu_get_clock(rt_clock);
656             s->fd_got_error = 1;
657             if (last_media_present)
658                 s->fd_media_changed = 1;
659 #ifdef DEBUG_FLOPPY
660             printf("No floppy\n");
661 #endif
662             return -EIO;
663         }
664 #ifdef DEBUG_FLOPPY
665         printf("Floppy opened\n");
666 #endif
667     }
668     if (!last_media_present)
669         s->fd_media_changed = 1;
670     s->fd_open_time = qemu_get_clock(rt_clock);
671     s->fd_got_error = 0;
672     return 0;
673 }
674 #else
675 static int fd_open(BlockDriverState *bs)
676 {
677     return 0;
678 }
679 #endif
680
681 #if defined(__linux__)
682
683 static int raw_is_inserted(BlockDriverState *bs)
684 {
685     BDRVRawState *s = bs->opaque;
686     int ret;
687
688     switch(s->type) {
689     case FTYPE_CD:
690         ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
691         if (ret == CDS_DISC_OK)
692             return 1;
693         else
694             return 0;
695         break;
696     case FTYPE_FD:
697         ret = fd_open(bs);
698         return (ret >= 0);
699     default:
700         return 1;
701     }
702 }
703
704 /* currently only used by fdc.c, but a CD version would be good too */
705 static int raw_media_changed(BlockDriverState *bs)
706 {
707     BDRVRawState *s = bs->opaque;
708
709     switch(s->type) {
710     case FTYPE_FD:
711         {
712             int ret;
713             /* XXX: we do not have a true media changed indication. It
714                does not work if the floppy is changed without trying
715                to read it */
716             fd_open(bs);
717             ret = s->fd_media_changed;
718             s->fd_media_changed = 0;
719 #ifdef DEBUG_FLOPPY
720             printf("Floppy changed=%d\n", ret);
721 #endif
722             return ret;
723         }
724     default:
725         return -ENOTSUP;
726     }
727 }
728
729 static int raw_eject(BlockDriverState *bs, int eject_flag)
730 {
731     BDRVRawState *s = bs->opaque;
732
733     switch(s->type) {
734     case FTYPE_CD:
735         if (eject_flag) {
736             if (ioctl (s->fd, CDROMEJECT, NULL) < 0)
737                 perror("CDROMEJECT");
738         } else {
739             if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)
740                 perror("CDROMEJECT");
741         }
742         break;
743     case FTYPE_FD:
744         {
745             int fd;
746             if (s->fd >= 0) {
747                 close(s->fd);
748                 s->fd = -1;
749             }
750             fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);
751             if (fd >= 0) {
752                 if (ioctl(fd, FDEJECT, 0) < 0)
753                     perror("FDEJECT");
754                 close(fd);
755             }
756         }
757         break;
758     default:
759         return -ENOTSUP;
760     }
761     return 0;
762 }
763
764 static int raw_set_locked(BlockDriverState *bs, int locked)
765 {
766     BDRVRawState *s = bs->opaque;
767
768     switch(s->type) {
769     case FTYPE_CD:
770         if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {
771             /* Note: an error can happen if the distribution automatically
772                mounts the CD-ROM */
773             //        perror("CDROM_LOCKDOOR");
774         }
775         break;
776     default:
777         return -ENOTSUP;
778     }
779     return 0;
780 }
781
782 #else
783
784 static int raw_is_inserted(BlockDriverState *bs)
785 {
786     return 1;
787 }
788
789 static int raw_media_changed(BlockDriverState *bs)
790 {
791     return -ENOTSUP;
792 }
793
794 static int raw_eject(BlockDriverState *bs, int eject_flag)
795 {
796     return -ENOTSUP;
797 }
798
799 static int raw_set_locked(BlockDriverState *bs, int locked)
800 {
801     return -ENOTSUP;
802 }
803
804 #endif /* !linux */
805
806 BlockDriver bdrv_host_device = {
807     "host_device",
808     sizeof(BDRVRawState),
809     NULL, /* no probe for protocols */
810     hdev_open,
811     NULL,
812     NULL,
813     raw_close,
814     NULL,
815     raw_flush,
816     
817     .bdrv_aio_read = raw_aio_read,
818     .bdrv_aio_write = raw_aio_write,
819     .bdrv_aio_cancel = raw_aio_cancel,
820     .aiocb_size = sizeof(RawAIOCB),
821     .bdrv_pread = raw_pread,
822     .bdrv_pwrite = raw_pwrite,
823     .bdrv_getlength = raw_getlength,
824
825     /* removable device support */
826     .bdrv_is_inserted = raw_is_inserted,
827     .bdrv_media_changed = raw_media_changed,
828     .bdrv_eject = raw_eject,
829     .bdrv_set_locked = raw_set_locked,
830 };
831
832 #else /* _WIN32 */
833
834 /* XXX: use another file ? */
835 #include <winioctl.h>
836
837 #define FTYPE_FILE 0
838 #define FTYPE_CD     1
839
840 typedef struct BDRVRawState {
841     HANDLE hfile;
842     int type;
843     char drive_path[16]; /* format: "d:\" */
844 } BDRVRawState;
845
846 typedef struct RawAIOCB {
847     BlockDriverAIOCB common;
848     HANDLE hEvent;
849     OVERLAPPED ov;
850     int count;
851 } RawAIOCB;
852
853 int qemu_ftruncate64(int fd, int64_t length)
854 {
855     LARGE_INTEGER li;
856     LONG high;
857     HANDLE h;
858     BOOL res;
859
860     if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
861         return -1;
862
863     h = (HANDLE)_get_osfhandle(fd);
864
865     /* get current position, ftruncate do not change position */
866     li.HighPart = 0;
867     li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
868     if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
869         return -1;
870
871     high = length >> 32;
872     if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
873         return -1;
874     res = SetEndOfFile(h);
875
876     /* back to old position */
877     SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
878     return res ? 0 : -1;
879 }
880
881 static int set_sparse(int fd)
882 {
883     DWORD returned;
884     return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
885                                  NULL, 0, NULL, 0, &returned, NULL);
886 }
887
888 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
889 {
890     BDRVRawState *s = bs->opaque;
891     int access_flags, create_flags;
892     DWORD overlapped;
893
894     s->type = FTYPE_FILE;
895
896     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
897         access_flags = GENERIC_READ | GENERIC_WRITE;
898     } else {
899         access_flags = GENERIC_READ;
900     }
901     if (flags & BDRV_O_CREAT) {
902         create_flags = CREATE_ALWAYS;
903     } else {
904         create_flags = OPEN_EXISTING;
905     }
906 #ifdef QEMU_TOOL
907     overlapped = 0;
908 #else
909     overlapped = FILE_FLAG_OVERLAPPED;
910 #endif
911     s->hfile = CreateFile(filename, access_flags, 
912                           FILE_SHARE_READ, NULL,
913                           create_flags, overlapped, 0);
914     if (s->hfile == INVALID_HANDLE_VALUE) 
915         return -1;
916     return 0;
917 }
918
919 static int raw_pread(BlockDriverState *bs, int64_t offset, 
920                      uint8_t *buf, int count)
921 {
922     BDRVRawState *s = bs->opaque;
923     OVERLAPPED ov;
924     DWORD ret_count;
925     int ret;
926     
927     memset(&ov, 0, sizeof(ov));
928     ov.Offset = offset;
929     ov.OffsetHigh = offset >> 32;
930     ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
931     if (!ret) {
932         ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
933         if (!ret)
934             return -EIO;
935         else
936             return ret_count;
937     }
938     return ret_count;
939 }
940
941 static int raw_pwrite(BlockDriverState *bs, int64_t offset, 
942                       const uint8_t *buf, int count)
943 {
944     BDRVRawState *s = bs->opaque;
945     OVERLAPPED ov;
946     DWORD ret_count;
947     int ret;
948     
949     memset(&ov, 0, sizeof(ov));
950     ov.Offset = offset;
951     ov.OffsetHigh = offset >> 32;
952     ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
953     if (!ret) {
954         ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
955         if (!ret)
956             return -EIO;
957         else
958             return ret_count;
959     }
960     return ret_count;
961 }
962
963 #ifndef QEMU_TOOL
964 static void raw_aio_cb(void *opaque)
965 {
966     RawAIOCB *acb = opaque;
967     BlockDriverState *bs = acb->common.bs;
968     BDRVRawState *s = bs->opaque;
969     DWORD ret_count;
970     int ret;
971
972     ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE);
973     if (!ret || ret_count != acb->count) {
974         acb->common.cb(acb->common.opaque, -EIO);
975     } else {
976         acb->common.cb(acb->common.opaque, 0);
977     }
978 }
979 #endif
980
981 static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
982         int64_t sector_num, uint8_t *buf, int nb_sectors,
983         BlockDriverCompletionFunc *cb, void *opaque)
984 {
985     RawAIOCB *acb;
986     int64_t offset;
987
988     acb = qemu_aio_get(bs, cb, opaque);
989     if (acb->hEvent) {
990         acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
991         if (!acb->hEvent) {
992             qemu_aio_release(acb);
993             return NULL;
994         }
995     }
996     memset(&acb->ov, 0, sizeof(acb->ov));
997     offset = sector_num * 512;
998     acb->ov.Offset = offset;
999     acb->ov.OffsetHigh = offset >> 32;
1000     acb->ov.hEvent = acb->hEvent;
1001     acb->count = nb_sectors * 512;
1002 #ifndef QEMU_TOOL
1003     qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
1004 #endif
1005     return acb;
1006 }
1007
1008 static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
1009         int64_t sector_num, uint8_t *buf, int nb_sectors,
1010         BlockDriverCompletionFunc *cb, void *opaque)
1011 {
1012     BDRVRawState *s = bs->opaque;
1013     RawAIOCB *acb;
1014     int ret;
1015
1016     acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
1017     if (!acb)
1018         return NULL;
1019     ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov);
1020     if (!ret) {
1021         qemu_aio_release(acb);
1022         return NULL;
1023     }
1024 #ifdef QEMU_TOOL
1025     qemu_aio_release(acb);
1026 #endif
1027     return (BlockDriverAIOCB *)acb;
1028 }
1029
1030 static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
1031         int64_t sector_num, uint8_t *buf, int nb_sectors,
1032         BlockDriverCompletionFunc *cb, void *opaque)
1033 {
1034     BDRVRawState *s = bs->opaque;
1035     RawAIOCB *acb;
1036     int ret;
1037
1038     acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
1039     if (!acb)
1040         return NULL;
1041     ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov);
1042     if (!ret) {
1043         qemu_aio_release(acb);
1044         return NULL;
1045     }
1046 #ifdef QEMU_TOOL
1047     qemu_aio_release(acb);
1048 #endif
1049     return (BlockDriverAIOCB *)acb;
1050 }
1051
1052 static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
1053 {
1054 #ifndef QEMU_TOOL
1055     RawAIOCB *acb = (RawAIOCB *)blockacb;
1056     BlockDriverState *bs = acb->common.bs;
1057     BDRVRawState *s = bs->opaque;
1058
1059     qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
1060     /* XXX: if more than one async I/O it is not correct */
1061     CancelIo(s->hfile);
1062     qemu_aio_release(acb);
1063 #endif
1064 }
1065
1066 static void raw_flush(BlockDriverState *bs)
1067 {
1068     /* XXX: add it */
1069 }
1070
1071 static void raw_close(BlockDriverState *bs)
1072 {
1073     BDRVRawState *s = bs->opaque;
1074     CloseHandle(s->hfile);
1075 }
1076
1077 static int raw_truncate(BlockDriverState *bs, int64_t offset)
1078 {
1079     BDRVRawState *s = bs->opaque;
1080     DWORD low, high;
1081
1082     low = offset;
1083     high = offset >> 32;
1084     if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN))
1085         return -EIO;
1086     if (!SetEndOfFile(s->hfile))
1087         return -EIO;
1088     return 0;
1089 }
1090
1091 static int64_t raw_getlength(BlockDriverState *bs)
1092 {
1093     BDRVRawState *s = bs->opaque;
1094     LARGE_INTEGER l;
1095     ULARGE_INTEGER available, total, total_free; 
1096
1097     switch(s->type) {
1098     case FTYPE_FILE:
1099         l.LowPart = GetFileSize(s->hfile, &l.HighPart);
1100         if (l.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
1101             return -EIO;
1102         break;
1103     case FTYPE_CD:
1104         if (!GetDiskFreeSpaceEx(s->drive_path, &available, &total, &total_free))
1105             return -EIO;
1106         l.QuadPart = total.QuadPart;
1107         break;
1108     default:
1109         return -EIO;
1110     }
1111     return l.QuadPart;
1112 }
1113
1114 static int raw_create(const char *filename, int64_t total_size,
1115                       const char *backing_file, int flags)
1116 {
1117     int fd;
1118
1119     if (flags || backing_file)
1120         return -ENOTSUP;
1121
1122     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 
1123               0644);
1124     if (fd < 0)
1125         return -EIO;
1126     set_sparse(fd);
1127     ftruncate(fd, total_size * 512);
1128     close(fd);
1129     return 0;
1130 }
1131
1132 void qemu_aio_init(void)
1133 {
1134 }
1135
1136 void qemu_aio_poll(void)
1137 {
1138 }
1139
1140 void qemu_aio_flush(void)
1141 {
1142 }
1143
1144 void qemu_aio_wait_start(void)
1145 {
1146 }
1147
1148 void qemu_aio_wait(void)
1149 {
1150 #ifndef QEMU_TOOL
1151     qemu_bh_poll();
1152 #endif
1153 }
1154
1155 void qemu_aio_wait_end(void)
1156 {
1157 }
1158
1159 BlockDriver bdrv_raw = {
1160     "raw",
1161     sizeof(BDRVRawState),
1162     NULL, /* no probe for protocols */
1163     raw_open,
1164     NULL,
1165     NULL,
1166     raw_close,
1167     raw_create,
1168     raw_flush,
1169     
1170 #if 0
1171     .bdrv_aio_read = raw_aio_read,
1172     .bdrv_aio_write = raw_aio_write,
1173     .bdrv_aio_cancel = raw_aio_cancel,
1174     .aiocb_size = sizeof(RawAIOCB);
1175 #endif
1176     .protocol_name = "file",
1177     .bdrv_pread = raw_pread,
1178     .bdrv_pwrite = raw_pwrite,
1179     .bdrv_truncate = raw_truncate,
1180     .bdrv_getlength = raw_getlength,
1181 };
1182
1183 /***********************************************/
1184 /* host device */
1185
1186 static int find_cdrom(char *cdrom_name, int cdrom_name_size)
1187 {
1188     char drives[256], *pdrv = drives;
1189     UINT type;
1190
1191     memset(drives, 0, sizeof(drives));
1192     GetLogicalDriveStrings(sizeof(drives), drives);
1193     while(pdrv[0] != '\0') {
1194         type = GetDriveType(pdrv);
1195         switch(type) {
1196         case DRIVE_CDROM:
1197             snprintf(cdrom_name, cdrom_name_size, "\\\\.\\%c:", pdrv[0]);
1198             return 0;
1199             break;
1200         }
1201         pdrv += lstrlen(pdrv) + 1;
1202     }
1203     return -1;
1204 }
1205
1206 static int find_device_type(BlockDriverState *bs, const char *filename)
1207 {
1208     BDRVRawState *s = bs->opaque;
1209     UINT type;
1210     const char *p;
1211
1212     if (strstart(filename, "\\\\.\\", &p) ||
1213         strstart(filename, "//./", &p)) {
1214         snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
1215         type = GetDriveType(s->drive_path);
1216         if (type == DRIVE_CDROM)
1217             return FTYPE_CD;
1218         else
1219             return FTYPE_FILE;
1220     } else {
1221         return FTYPE_FILE;
1222     }
1223 }
1224
1225 static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
1226 {
1227     BDRVRawState *s = bs->opaque;
1228     int access_flags, create_flags;
1229     DWORD overlapped;
1230     char device_name[64];
1231
1232     if (strstart(filename, "/dev/cdrom", NULL)) {
1233         if (find_cdrom(device_name, sizeof(device_name)) < 0)
1234             return -ENOENT;
1235         filename = device_name;
1236     } else {
1237         /* transform drive letters into device name */
1238         if (((filename[0] >= 'a' && filename[0] <= 'z') ||
1239              (filename[0] >= 'A' && filename[0] <= 'Z')) &&
1240             filename[1] == ':' && filename[2] == '\0') {
1241             snprintf(device_name, sizeof(device_name), "\\\\.\\%c:", filename[0]);
1242             filename = device_name;
1243         }
1244     }
1245     s->type = find_device_type(bs, filename);
1246
1247     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
1248         access_flags = GENERIC_READ | GENERIC_WRITE;
1249     } else {
1250         access_flags = GENERIC_READ;
1251     }
1252     create_flags = OPEN_EXISTING;
1253
1254 #ifdef QEMU_TOOL
1255     overlapped = 0;
1256 #else
1257     overlapped = FILE_FLAG_OVERLAPPED;
1258 #endif
1259     s->hfile = CreateFile(filename, access_flags, 
1260                           FILE_SHARE_READ, NULL,
1261                           create_flags, overlapped, 0);
1262     if (s->hfile == INVALID_HANDLE_VALUE) 
1263         return -1;
1264     return 0;
1265 }
1266
1267 #if 0
1268 /***********************************************/
1269 /* removable device additionnal commands */
1270
1271 static int raw_is_inserted(BlockDriverState *bs)
1272 {
1273     return 1;
1274 }
1275
1276 static int raw_media_changed(BlockDriverState *bs)
1277 {
1278     return -ENOTSUP;
1279 }
1280
1281 static int raw_eject(BlockDriverState *bs, int eject_flag)
1282 {
1283     DWORD ret_count;
1284
1285     if (s->type == FTYPE_FILE)
1286         return -ENOTSUP;
1287     if (eject_flag) {
1288         DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA, 
1289                         NULL, 0, NULL, 0, &lpBytesReturned, NULL);
1290     } else {
1291         DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA, 
1292                         NULL, 0, NULL, 0, &lpBytesReturned, NULL);
1293     }
1294 }
1295
1296 static int raw_set_locked(BlockDriverState *bs, int locked)
1297 {
1298     return -ENOTSUP;
1299 }
1300 #endif
1301
1302 BlockDriver bdrv_host_device = {
1303     "host_device",
1304     sizeof(BDRVRawState),
1305     NULL, /* no probe for protocols */
1306     hdev_open,
1307     NULL,
1308     NULL,
1309     raw_close,
1310     NULL,
1311     raw_flush,
1312     
1313 #if 0
1314     .bdrv_aio_read = raw_aio_read,
1315     .bdrv_aio_write = raw_aio_write,
1316     .bdrv_aio_cancel = raw_aio_cancel,
1317     .aiocb_size = sizeof(RawAIOCB);
1318 #endif
1319     .bdrv_pread = raw_pread,
1320     .bdrv_pwrite = raw_pwrite,
1321     .bdrv_getlength = raw_getlength,
1322 };
1323 #endif /* _WIN32 */