Commit 223d4670a0cf539a0e8cc6a23aad28a8340dded8

Authored by ths
1 parent 50a9569b

Split block-raw.c into block-raw-posix.c and block-raw-win32.c, by

Anthony Liguori.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3814 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
... ... @@ -119,9 +119,16 @@ libqemu_common.a: $(OBJS)
119 119 rm -f $@
120 120 $(AR) rcs $@ $(OBJS)
121 121  
  122 +QEMU_IMG_BLOCK_OBJS = $(BLOCK_OBJS)
  123 +ifdef CONFIG_WIN32
  124 +QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-win32.o
  125 +else
  126 +QEMU_IMG_BLOCK_OBJS += qemu-img-block-raw-posix.o
  127 +endif
  128 +
122 129 ######################################################################
123 130  
124   -qemu-img$(EXESUF): qemu-img.o qemu-img-block.o qemu-img-block-raw.o $(BLOCK_OBJS)
  131 +qemu-img$(EXESUF): qemu-img.o qemu-img-block.o $(QEMU_IMG_BLOCK_OBJS)
125 132 $(CC) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)
126 133  
127 134 qemu-img-%.o: %.c
... ...
Makefile.target
... ... @@ -398,7 +398,11 @@ endif
398 398 # must use static linking to avoid leaving stuff in virtual address space
399 399 VL_OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o
400 400 # XXX: suppress QEMU_TOOL tests
401   -VL_OBJS+=block-raw.o
  401 +ifdef CONFIG_WIN32
  402 +VL_OBJS+=block-raw-win32.o
  403 +else
  404 +VL_OBJS+=block-raw-posix.o
  405 +endif
402 406  
403 407 ifdef CONFIG_ALSA
404 408 LIBS += -lasound
... ...
block-raw.c renamed to block-raw-posix.c
1 1 /*
2   - * Block driver for RAW files
  2 + * Block driver for RAW files (posix)
3 3 *
4 4 * Copyright (c) 2006 Fabrice Bellard
5 5 *
... ... @@ -28,7 +28,6 @@
28 28 #endif
29 29 #include "block_int.h"
30 30 #include <assert.h>
31   -#ifndef _WIN32
32 31 #include <aio.h>
33 32  
34 33 #ifdef CONFIG_COCOA
... ... @@ -900,522 +899,3 @@ BlockDriver bdrv_host_device = {
900 899 .bdrv_eject = raw_eject,
901 900 .bdrv_set_locked = raw_set_locked,
902 901 };
903   -
904   -#else /* _WIN32 */
905   -
906   -/* XXX: use another file ? */
907   -#include <winioctl.h>
908   -
909   -#define FTYPE_FILE 0
910   -#define FTYPE_CD 1
911   -#define FTYPE_HARDDISK 2
912   -
913   -typedef struct BDRVRawState {
914   - HANDLE hfile;
915   - int type;
916   - char drive_path[16]; /* format: "d:\" */
917   -} BDRVRawState;
918   -
919   -typedef struct RawAIOCB {
920   - BlockDriverAIOCB common;
921   - HANDLE hEvent;
922   - OVERLAPPED ov;
923   - int count;
924   -} RawAIOCB;
925   -
926   -int qemu_ftruncate64(int fd, int64_t length)
927   -{
928   - LARGE_INTEGER li;
929   - LONG high;
930   - HANDLE h;
931   - BOOL res;
932   -
933   - if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
934   - return -1;
935   -
936   - h = (HANDLE)_get_osfhandle(fd);
937   -
938   - /* get current position, ftruncate do not change position */
939   - li.HighPart = 0;
940   - li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
941   - if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
942   - return -1;
943   -
944   - high = length >> 32;
945   - if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
946   - return -1;
947   - res = SetEndOfFile(h);
948   -
949   - /* back to old position */
950   - SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
951   - return res ? 0 : -1;
952   -}
953   -
954   -static int set_sparse(int fd)
955   -{
956   - DWORD returned;
957   - return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
958   - NULL, 0, NULL, 0, &returned, NULL);
959   -}
960   -
961   -static int raw_open(BlockDriverState *bs, const char *filename, int flags)
962   -{
963   - BDRVRawState *s = bs->opaque;
964   - int access_flags, create_flags;
965   - DWORD overlapped;
966   -
967   - s->type = FTYPE_FILE;
968   -
969   - if ((flags & BDRV_O_ACCESS) == O_RDWR) {
970   - access_flags = GENERIC_READ | GENERIC_WRITE;
971   - } else {
972   - access_flags = GENERIC_READ;
973   - }
974   - if (flags & BDRV_O_CREAT) {
975   - create_flags = CREATE_ALWAYS;
976   - } else {
977   - create_flags = OPEN_EXISTING;
978   - }
979   -#ifdef QEMU_IMG
980   - overlapped = FILE_ATTRIBUTE_NORMAL;
981   -#else
982   - overlapped = FILE_FLAG_OVERLAPPED;
983   -#endif
984   - s->hfile = CreateFile(filename, access_flags,
985   - FILE_SHARE_READ, NULL,
986   - create_flags, overlapped, NULL);
987   - if (s->hfile == INVALID_HANDLE_VALUE) {
988   - int err = GetLastError();
989   -
990   - if (err == ERROR_ACCESS_DENIED)
991   - return -EACCES;
992   - return -1;
993   - }
994   - return 0;
995   -}
996   -
997   -static int raw_pread(BlockDriverState *bs, int64_t offset,
998   - uint8_t *buf, int count)
999   -{
1000   - BDRVRawState *s = bs->opaque;
1001   - OVERLAPPED ov;
1002   - DWORD ret_count;
1003   - int ret;
1004   -
1005   - memset(&ov, 0, sizeof(ov));
1006   - ov.Offset = offset;
1007   - ov.OffsetHigh = offset >> 32;
1008   - ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
1009   - if (!ret) {
1010   - ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
1011   - if (!ret)
1012   - return -EIO;
1013   - else
1014   - return ret_count;
1015   - }
1016   - return ret_count;
1017   -}
1018   -
1019   -static int raw_pwrite(BlockDriverState *bs, int64_t offset,
1020   - const uint8_t *buf, int count)
1021   -{
1022   - BDRVRawState *s = bs->opaque;
1023   - OVERLAPPED ov;
1024   - DWORD ret_count;
1025   - int ret;
1026   -
1027   - memset(&ov, 0, sizeof(ov));
1028   - ov.Offset = offset;
1029   - ov.OffsetHigh = offset >> 32;
1030   - ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
1031   - if (!ret) {
1032   - ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
1033   - if (!ret)
1034   - return -EIO;
1035   - else
1036   - return ret_count;
1037   - }
1038   - return ret_count;
1039   -}
1040   -
1041   -#if 0
1042   -#ifndef QEMU_IMG
1043   -static void raw_aio_cb(void *opaque)
1044   -{
1045   - RawAIOCB *acb = opaque;
1046   - BlockDriverState *bs = acb->common.bs;
1047   - BDRVRawState *s = bs->opaque;
1048   - DWORD ret_count;
1049   - int ret;
1050   -
1051   - ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE);
1052   - if (!ret || ret_count != acb->count) {
1053   - acb->common.cb(acb->common.opaque, -EIO);
1054   - } else {
1055   - acb->common.cb(acb->common.opaque, 0);
1056   - }
1057   -}
1058   -#endif
1059   -
1060   -static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
1061   - int64_t sector_num, uint8_t *buf, int nb_sectors,
1062   - BlockDriverCompletionFunc *cb, void *opaque)
1063   -{
1064   - RawAIOCB *acb;
1065   - int64_t offset;
1066   -
1067   - acb = qemu_aio_get(bs, cb, opaque);
1068   - if (acb->hEvent) {
1069   - acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1070   - if (!acb->hEvent) {
1071   - qemu_aio_release(acb);
1072   - return NULL;
1073   - }
1074   - }
1075   - memset(&acb->ov, 0, sizeof(acb->ov));
1076   - offset = sector_num * 512;
1077   - acb->ov.Offset = offset;
1078   - acb->ov.OffsetHigh = offset >> 32;
1079   - acb->ov.hEvent = acb->hEvent;
1080   - acb->count = nb_sectors * 512;
1081   -#ifndef QEMU_IMG
1082   - qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
1083   -#endif
1084   - return acb;
1085   -}
1086   -
1087   -static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
1088   - int64_t sector_num, uint8_t *buf, int nb_sectors,
1089   - BlockDriverCompletionFunc *cb, void *opaque)
1090   -{
1091   - BDRVRawState *s = bs->opaque;
1092   - RawAIOCB *acb;
1093   - int ret;
1094   -
1095   - acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
1096   - if (!acb)
1097   - return NULL;
1098   - ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov);
1099   - if (!ret) {
1100   - qemu_aio_release(acb);
1101   - return NULL;
1102   - }
1103   -#ifdef QEMU_IMG
1104   - qemu_aio_release(acb);
1105   -#endif
1106   - return (BlockDriverAIOCB *)acb;
1107   -}
1108   -
1109   -static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
1110   - int64_t sector_num, uint8_t *buf, int nb_sectors,
1111   - BlockDriverCompletionFunc *cb, void *opaque)
1112   -{
1113   - BDRVRawState *s = bs->opaque;
1114   - RawAIOCB *acb;
1115   - int ret;
1116   -
1117   - acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
1118   - if (!acb)
1119   - return NULL;
1120   - ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov);
1121   - if (!ret) {
1122   - qemu_aio_release(acb);
1123   - return NULL;
1124   - }
1125   -#ifdef QEMU_IMG
1126   - qemu_aio_release(acb);
1127   -#endif
1128   - return (BlockDriverAIOCB *)acb;
1129   -}
1130   -
1131   -static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
1132   -{
1133   -#ifndef QEMU_IMG
1134   - RawAIOCB *acb = (RawAIOCB *)blockacb;
1135   - BlockDriverState *bs = acb->common.bs;
1136   - BDRVRawState *s = bs->opaque;
1137   -
1138   - qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
1139   - /* XXX: if more than one async I/O it is not correct */
1140   - CancelIo(s->hfile);
1141   - qemu_aio_release(acb);
1142   -#endif
1143   -}
1144   -#endif /* #if 0 */
1145   -
1146   -static void raw_flush(BlockDriverState *bs)
1147   -{
1148   - BDRVRawState *s = bs->opaque;
1149   - FlushFileBuffers(s->hfile);
1150   -}
1151   -
1152   -static void raw_close(BlockDriverState *bs)
1153   -{
1154   - BDRVRawState *s = bs->opaque;
1155   - CloseHandle(s->hfile);
1156   -}
1157   -
1158   -static int raw_truncate(BlockDriverState *bs, int64_t offset)
1159   -{
1160   - BDRVRawState *s = bs->opaque;
1161   - DWORD low, high;
1162   -
1163   - low = offset;
1164   - high = offset >> 32;
1165   - if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN))
1166   - return -EIO;
1167   - if (!SetEndOfFile(s->hfile))
1168   - return -EIO;
1169   - return 0;
1170   -}
1171   -
1172   -static int64_t raw_getlength(BlockDriverState *bs)
1173   -{
1174   - BDRVRawState *s = bs->opaque;
1175   - LARGE_INTEGER l;
1176   - ULARGE_INTEGER available, total, total_free;
1177   - DISK_GEOMETRY_EX dg;
1178   - DWORD count;
1179   - BOOL status;
1180   -
1181   - switch(s->type) {
1182   - case FTYPE_FILE:
1183   - l.LowPart = GetFileSize(s->hfile, &l.HighPart);
1184   - if (l.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
1185   - return -EIO;
1186   - break;
1187   - case FTYPE_CD:
1188   - if (!GetDiskFreeSpaceEx(s->drive_path, &available, &total, &total_free))
1189   - return -EIO;
1190   - l.QuadPart = total.QuadPart;
1191   - break;
1192   - case FTYPE_HARDDISK:
1193   - status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
1194   - NULL, 0, &dg, sizeof(dg), &count, NULL);
1195   - if (status != 0) {
1196   - l = dg.DiskSize;
1197   - }
1198   - break;
1199   - default:
1200   - return -EIO;
1201   - }
1202   - return l.QuadPart;
1203   -}
1204   -
1205   -static int raw_create(const char *filename, int64_t total_size,
1206   - const char *backing_file, int flags)
1207   -{
1208   - int fd;
1209   -
1210   - if (flags || backing_file)
1211   - return -ENOTSUP;
1212   -
1213   - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
1214   - 0644);
1215   - if (fd < 0)
1216   - return -EIO;
1217   - set_sparse(fd);
1218   - ftruncate(fd, total_size * 512);
1219   - close(fd);
1220   - return 0;
1221   -}
1222   -
1223   -void qemu_aio_init(void)
1224   -{
1225   -}
1226   -
1227   -void qemu_aio_poll(void)
1228   -{
1229   -}
1230   -
1231   -void qemu_aio_flush(void)
1232   -{
1233   -}
1234   -
1235   -void qemu_aio_wait_start(void)
1236   -{
1237   -}
1238   -
1239   -void qemu_aio_wait(void)
1240   -{
1241   -#ifndef QEMU_IMG
1242   - qemu_bh_poll();
1243   -#endif
1244   -}
1245   -
1246   -void qemu_aio_wait_end(void)
1247   -{
1248   -}
1249   -
1250   -BlockDriver bdrv_raw = {
1251   - "raw",
1252   - sizeof(BDRVRawState),
1253   - NULL, /* no probe for protocols */
1254   - raw_open,
1255   - NULL,
1256   - NULL,
1257   - raw_close,
1258   - raw_create,
1259   - raw_flush,
1260   -
1261   -#if 0
1262   - .bdrv_aio_read = raw_aio_read,
1263   - .bdrv_aio_write = raw_aio_write,
1264   - .bdrv_aio_cancel = raw_aio_cancel,
1265   - .aiocb_size = sizeof(RawAIOCB);
1266   -#endif
1267   - .protocol_name = "file",
1268   - .bdrv_pread = raw_pread,
1269   - .bdrv_pwrite = raw_pwrite,
1270   - .bdrv_truncate = raw_truncate,
1271   - .bdrv_getlength = raw_getlength,
1272   -};
1273   -
1274   -/***********************************************/
1275   -/* host device */
1276   -
1277   -static int find_cdrom(char *cdrom_name, int cdrom_name_size)
1278   -{
1279   - char drives[256], *pdrv = drives;
1280   - UINT type;
1281   -
1282   - memset(drives, 0, sizeof(drives));
1283   - GetLogicalDriveStrings(sizeof(drives), drives);
1284   - while(pdrv[0] != '\0') {
1285   - type = GetDriveType(pdrv);
1286   - switch(type) {
1287   - case DRIVE_CDROM:
1288   - snprintf(cdrom_name, cdrom_name_size, "\\\\.\\%c:", pdrv[0]);
1289   - return 0;
1290   - break;
1291   - }
1292   - pdrv += lstrlen(pdrv) + 1;
1293   - }
1294   - return -1;
1295   -}
1296   -
1297   -static int find_device_type(BlockDriverState *bs, const char *filename)
1298   -{
1299   - BDRVRawState *s = bs->opaque;
1300   - UINT type;
1301   - const char *p;
1302   -
1303   - if (strstart(filename, "\\\\.\\", &p) ||
1304   - strstart(filename, "//./", &p)) {
1305   - if (stristart(p, "PhysicalDrive", NULL))
1306   - return FTYPE_HARDDISK;
1307   - snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
1308   - type = GetDriveType(s->drive_path);
1309   - if (type == DRIVE_CDROM)
1310   - return FTYPE_CD;
1311   - else
1312   - return FTYPE_FILE;
1313   - } else {
1314   - return FTYPE_FILE;
1315   - }
1316   -}
1317   -
1318   -static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
1319   -{
1320   - BDRVRawState *s = bs->opaque;
1321   - int access_flags, create_flags;
1322   - DWORD overlapped;
1323   - char device_name[64];
1324   -
1325   - if (strstart(filename, "/dev/cdrom", NULL)) {
1326   - if (find_cdrom(device_name, sizeof(device_name)) < 0)
1327   - return -ENOENT;
1328   - filename = device_name;
1329   - } else {
1330   - /* transform drive letters into device name */
1331   - if (((filename[0] >= 'a' && filename[0] <= 'z') ||
1332   - (filename[0] >= 'A' && filename[0] <= 'Z')) &&
1333   - filename[1] == ':' && filename[2] == '\0') {
1334   - snprintf(device_name, sizeof(device_name), "\\\\.\\%c:", filename[0]);
1335   - filename = device_name;
1336   - }
1337   - }
1338   - s->type = find_device_type(bs, filename);
1339   -
1340   - if ((flags & BDRV_O_ACCESS) == O_RDWR) {
1341   - access_flags = GENERIC_READ | GENERIC_WRITE;
1342   - } else {
1343   - access_flags = GENERIC_READ;
1344   - }
1345   - create_flags = OPEN_EXISTING;
1346   -
1347   -#ifdef QEMU_IMG
1348   - overlapped = FILE_ATTRIBUTE_NORMAL;
1349   -#else
1350   - overlapped = FILE_FLAG_OVERLAPPED;
1351   -#endif
1352   - s->hfile = CreateFile(filename, access_flags,
1353   - FILE_SHARE_READ, NULL,
1354   - create_flags, overlapped, NULL);
1355   - if (s->hfile == INVALID_HANDLE_VALUE) {
1356   - int err = GetLastError();
1357   -
1358   - if (err == ERROR_ACCESS_DENIED)
1359   - return -EACCES;
1360   - return -1;
1361   - }
1362   - return 0;
1363   -}
1364   -
1365   -#if 0
1366   -/***********************************************/
1367   -/* removable device additional commands */
1368   -
1369   -static int raw_is_inserted(BlockDriverState *bs)
1370   -{
1371   - return 1;
1372   -}
1373   -
1374   -static int raw_media_changed(BlockDriverState *bs)
1375   -{
1376   - return -ENOTSUP;
1377   -}
1378   -
1379   -static int raw_eject(BlockDriverState *bs, int eject_flag)
1380   -{
1381   - DWORD ret_count;
1382   -
1383   - if (s->type == FTYPE_FILE)
1384   - return -ENOTSUP;
1385   - if (eject_flag) {
1386   - DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
1387   - NULL, 0, NULL, 0, &lpBytesReturned, NULL);
1388   - } else {
1389   - DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
1390   - NULL, 0, NULL, 0, &lpBytesReturned, NULL);
1391   - }
1392   -}
1393   -
1394   -static int raw_set_locked(BlockDriverState *bs, int locked)
1395   -{
1396   - return -ENOTSUP;
1397   -}
1398   -#endif
1399   -
1400   -BlockDriver bdrv_host_device = {
1401   - "host_device",
1402   - sizeof(BDRVRawState),
1403   - NULL, /* no probe for protocols */
1404   - hdev_open,
1405   - NULL,
1406   - NULL,
1407   - raw_close,
1408   - NULL,
1409   - raw_flush,
1410   -
1411   -#if 0
1412   - .bdrv_aio_read = raw_aio_read,
1413   - .bdrv_aio_write = raw_aio_write,
1414   - .bdrv_aio_cancel = raw_aio_cancel,
1415   - .aiocb_size = sizeof(RawAIOCB);
1416   -#endif
1417   - .bdrv_pread = raw_pread,
1418   - .bdrv_pwrite = raw_pwrite,
1419   - .bdrv_getlength = raw_getlength,
1420   -};
1421   -#endif /* _WIN32 */
... ...
block-raw-win32.c 0 โ†’ 100644
  1 +/*
  2 + * Block driver for RAW files (win32)
  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 "qemu-common.h"
  25 +#ifndef QEMU_IMG
  26 +#include "qemu-timer.h"
  27 +#include "exec-all.h"
  28 +#endif
  29 +#include "block_int.h"
  30 +#include <assert.h>
  31 +#include <winioctl.h>
  32 +
  33 +#define FTYPE_FILE 0
  34 +#define FTYPE_CD 1
  35 +#define FTYPE_HARDDISK 2
  36 +
  37 +typedef struct BDRVRawState {
  38 + HANDLE hfile;
  39 + int type;
  40 + char drive_path[16]; /* format: "d:\" */
  41 +} BDRVRawState;
  42 +
  43 +typedef struct RawAIOCB {
  44 + BlockDriverAIOCB common;
  45 + HANDLE hEvent;
  46 + OVERLAPPED ov;
  47 + int count;
  48 +} RawAIOCB;
  49 +
  50 +int qemu_ftruncate64(int fd, int64_t length)
  51 +{
  52 + LARGE_INTEGER li;
  53 + LONG high;
  54 + HANDLE h;
  55 + BOOL res;
  56 +
  57 + if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
  58 + return -1;
  59 +
  60 + h = (HANDLE)_get_osfhandle(fd);
  61 +
  62 + /* get current position, ftruncate do not change position */
  63 + li.HighPart = 0;
  64 + li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
  65 + if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
  66 + return -1;
  67 +
  68 + high = length >> 32;
  69 + if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
  70 + return -1;
  71 + res = SetEndOfFile(h);
  72 +
  73 + /* back to old position */
  74 + SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
  75 + return res ? 0 : -1;
  76 +}
  77 +
  78 +static int set_sparse(int fd)
  79 +{
  80 + DWORD returned;
  81 + return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
  82 + NULL, 0, NULL, 0, &returned, NULL);
  83 +}
  84 +
  85 +static int raw_open(BlockDriverState *bs, const char *filename, int flags)
  86 +{
  87 + BDRVRawState *s = bs->opaque;
  88 + int access_flags, create_flags;
  89 + DWORD overlapped;
  90 +
  91 + s->type = FTYPE_FILE;
  92 +
  93 + if ((flags & BDRV_O_ACCESS) == O_RDWR) {
  94 + access_flags = GENERIC_READ | GENERIC_WRITE;
  95 + } else {
  96 + access_flags = GENERIC_READ;
  97 + }
  98 + if (flags & BDRV_O_CREAT) {
  99 + create_flags = CREATE_ALWAYS;
  100 + } else {
  101 + create_flags = OPEN_EXISTING;
  102 + }
  103 +#ifdef QEMU_IMG
  104 + overlapped = FILE_ATTRIBUTE_NORMAL;
  105 +#else
  106 + overlapped = FILE_FLAG_OVERLAPPED;
  107 +#endif
  108 + s->hfile = CreateFile(filename, access_flags,
  109 + FILE_SHARE_READ, NULL,
  110 + create_flags, overlapped, NULL);
  111 + if (s->hfile == INVALID_HANDLE_VALUE) {
  112 + int err = GetLastError();
  113 +
  114 + if (err == ERROR_ACCESS_DENIED)
  115 + return -EACCES;
  116 + return -1;
  117 + }
  118 + return 0;
  119 +}
  120 +
  121 +static int raw_pread(BlockDriverState *bs, int64_t offset,
  122 + uint8_t *buf, int count)
  123 +{
  124 + BDRVRawState *s = bs->opaque;
  125 + OVERLAPPED ov;
  126 + DWORD ret_count;
  127 + int ret;
  128 +
  129 + memset(&ov, 0, sizeof(ov));
  130 + ov.Offset = offset;
  131 + ov.OffsetHigh = offset >> 32;
  132 + ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
  133 + if (!ret) {
  134 + ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
  135 + if (!ret)
  136 + return -EIO;
  137 + else
  138 + return ret_count;
  139 + }
  140 + return ret_count;
  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 + OVERLAPPED ov;
  148 + DWORD ret_count;
  149 + int ret;
  150 +
  151 + memset(&ov, 0, sizeof(ov));
  152 + ov.Offset = offset;
  153 + ov.OffsetHigh = offset >> 32;
  154 + ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
  155 + if (!ret) {
  156 + ret = GetOverlappedResult(s->hfile, &ov, &ret_count, TRUE);
  157 + if (!ret)
  158 + return -EIO;
  159 + else
  160 + return ret_count;
  161 + }
  162 + return ret_count;
  163 +}
  164 +
  165 +#if 0
  166 +#ifndef QEMU_IMG
  167 +static void raw_aio_cb(void *opaque)
  168 +{
  169 + RawAIOCB *acb = opaque;
  170 + BlockDriverState *bs = acb->common.bs;
  171 + BDRVRawState *s = bs->opaque;
  172 + DWORD ret_count;
  173 + int ret;
  174 +
  175 + ret = GetOverlappedResult(s->hfile, &acb->ov, &ret_count, TRUE);
  176 + if (!ret || ret_count != acb->count) {
  177 + acb->common.cb(acb->common.opaque, -EIO);
  178 + } else {
  179 + acb->common.cb(acb->common.opaque, 0);
  180 + }
  181 +}
  182 +#endif
  183 +
  184 +static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
  185 + int64_t sector_num, uint8_t *buf, int nb_sectors,
  186 + BlockDriverCompletionFunc *cb, void *opaque)
  187 +{
  188 + RawAIOCB *acb;
  189 + int64_t offset;
  190 +
  191 + acb = qemu_aio_get(bs, cb, opaque);
  192 + if (acb->hEvent) {
  193 + acb->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  194 + if (!acb->hEvent) {
  195 + qemu_aio_release(acb);
  196 + return NULL;
  197 + }
  198 + }
  199 + memset(&acb->ov, 0, sizeof(acb->ov));
  200 + offset = sector_num * 512;
  201 + acb->ov.Offset = offset;
  202 + acb->ov.OffsetHigh = offset >> 32;
  203 + acb->ov.hEvent = acb->hEvent;
  204 + acb->count = nb_sectors * 512;
  205 +#ifndef QEMU_IMG
  206 + qemu_add_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
  207 +#endif
  208 + return acb;
  209 +}
  210 +
  211 +static BlockDriverAIOCB *raw_aio_read(BlockDriverState *bs,
  212 + int64_t sector_num, uint8_t *buf, int nb_sectors,
  213 + BlockDriverCompletionFunc *cb, void *opaque)
  214 +{
  215 + BDRVRawState *s = bs->opaque;
  216 + RawAIOCB *acb;
  217 + int ret;
  218 +
  219 + acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
  220 + if (!acb)
  221 + return NULL;
  222 + ret = ReadFile(s->hfile, buf, acb->count, NULL, &acb->ov);
  223 + if (!ret) {
  224 + qemu_aio_release(acb);
  225 + return NULL;
  226 + }
  227 +#ifdef QEMU_IMG
  228 + qemu_aio_release(acb);
  229 +#endif
  230 + return (BlockDriverAIOCB *)acb;
  231 +}
  232 +
  233 +static BlockDriverAIOCB *raw_aio_write(BlockDriverState *bs,
  234 + int64_t sector_num, uint8_t *buf, int nb_sectors,
  235 + BlockDriverCompletionFunc *cb, void *opaque)
  236 +{
  237 + BDRVRawState *s = bs->opaque;
  238 + RawAIOCB *acb;
  239 + int ret;
  240 +
  241 + acb = raw_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
  242 + if (!acb)
  243 + return NULL;
  244 + ret = WriteFile(s->hfile, buf, acb->count, NULL, &acb->ov);
  245 + if (!ret) {
  246 + qemu_aio_release(acb);
  247 + return NULL;
  248 + }
  249 +#ifdef QEMU_IMG
  250 + qemu_aio_release(acb);
  251 +#endif
  252 + return (BlockDriverAIOCB *)acb;
  253 +}
  254 +
  255 +static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
  256 +{
  257 +#ifndef QEMU_IMG
  258 + RawAIOCB *acb = (RawAIOCB *)blockacb;
  259 + BlockDriverState *bs = acb->common.bs;
  260 + BDRVRawState *s = bs->opaque;
  261 +
  262 + qemu_del_wait_object(acb->ov.hEvent, raw_aio_cb, acb);
  263 + /* XXX: if more than one async I/O it is not correct */
  264 + CancelIo(s->hfile);
  265 + qemu_aio_release(acb);
  266 +#endif
  267 +}
  268 +#endif /* #if 0 */
  269 +
  270 +static void raw_flush(BlockDriverState *bs)
  271 +{
  272 + BDRVRawState *s = bs->opaque;
  273 + FlushFileBuffers(s->hfile);
  274 +}
  275 +
  276 +static void raw_close(BlockDriverState *bs)
  277 +{
  278 + BDRVRawState *s = bs->opaque;
  279 + CloseHandle(s->hfile);
  280 +}
  281 +
  282 +static int raw_truncate(BlockDriverState *bs, int64_t offset)
  283 +{
  284 + BDRVRawState *s = bs->opaque;
  285 + DWORD low, high;
  286 +
  287 + low = offset;
  288 + high = offset >> 32;
  289 + if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN))
  290 + return -EIO;
  291 + if (!SetEndOfFile(s->hfile))
  292 + return -EIO;
  293 + return 0;
  294 +}
  295 +
  296 +static int64_t raw_getlength(BlockDriverState *bs)
  297 +{
  298 + BDRVRawState *s = bs->opaque;
  299 + LARGE_INTEGER l;
  300 + ULARGE_INTEGER available, total, total_free;
  301 + DISK_GEOMETRY_EX dg;
  302 + DWORD count;
  303 + BOOL status;
  304 +
  305 + switch(s->type) {
  306 + case FTYPE_FILE:
  307 + l.LowPart = GetFileSize(s->hfile, &l.HighPart);
  308 + if (l.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
  309 + return -EIO;
  310 + break;
  311 + case FTYPE_CD:
  312 + if (!GetDiskFreeSpaceEx(s->drive_path, &available, &total, &total_free))
  313 + return -EIO;
  314 + l.QuadPart = total.QuadPart;
  315 + break;
  316 + case FTYPE_HARDDISK:
  317 + status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
  318 + NULL, 0, &dg, sizeof(dg), &count, NULL);
  319 + if (status != 0) {
  320 + l = dg.DiskSize;
  321 + }
  322 + break;
  323 + default:
  324 + return -EIO;
  325 + }
  326 + return l.QuadPart;
  327 +}
  328 +
  329 +static int raw_create(const char *filename, int64_t total_size,
  330 + const char *backing_file, int flags)
  331 +{
  332 + int fd;
  333 +
  334 + if (flags || backing_file)
  335 + return -ENOTSUP;
  336 +
  337 + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
  338 + 0644);
  339 + if (fd < 0)
  340 + return -EIO;
  341 + set_sparse(fd);
  342 + ftruncate(fd, total_size * 512);
  343 + close(fd);
  344 + return 0;
  345 +}
  346 +
  347 +void qemu_aio_init(void)
  348 +{
  349 +}
  350 +
  351 +void qemu_aio_poll(void)
  352 +{
  353 +}
  354 +
  355 +void qemu_aio_flush(void)
  356 +{
  357 +}
  358 +
  359 +void qemu_aio_wait_start(void)
  360 +{
  361 +}
  362 +
  363 +void qemu_aio_wait(void)
  364 +{
  365 +#ifndef QEMU_IMG
  366 + qemu_bh_poll();
  367 +#endif
  368 +}
  369 +
  370 +void qemu_aio_wait_end(void)
  371 +{
  372 +}
  373 +
  374 +BlockDriver bdrv_raw = {
  375 + "raw",
  376 + sizeof(BDRVRawState),
  377 + NULL, /* no probe for protocols */
  378 + raw_open,
  379 + NULL,
  380 + NULL,
  381 + raw_close,
  382 + raw_create,
  383 + raw_flush,
  384 +
  385 +#if 0
  386 + .bdrv_aio_read = raw_aio_read,
  387 + .bdrv_aio_write = raw_aio_write,
  388 + .bdrv_aio_cancel = raw_aio_cancel,
  389 + .aiocb_size = sizeof(RawAIOCB);
  390 +#endif
  391 + .protocol_name = "file",
  392 + .bdrv_pread = raw_pread,
  393 + .bdrv_pwrite = raw_pwrite,
  394 + .bdrv_truncate = raw_truncate,
  395 + .bdrv_getlength = raw_getlength,
  396 +};
  397 +
  398 +/***********************************************/
  399 +/* host device */
  400 +
  401 +static int find_cdrom(char *cdrom_name, int cdrom_name_size)
  402 +{
  403 + char drives[256], *pdrv = drives;
  404 + UINT type;
  405 +
  406 + memset(drives, 0, sizeof(drives));
  407 + GetLogicalDriveStrings(sizeof(drives), drives);
  408 + while(pdrv[0] != '\0') {
  409 + type = GetDriveType(pdrv);
  410 + switch(type) {
  411 + case DRIVE_CDROM:
  412 + snprintf(cdrom_name, cdrom_name_size, "\\\\.\\%c:", pdrv[0]);
  413 + return 0;
  414 + break;
  415 + }
  416 + pdrv += lstrlen(pdrv) + 1;
  417 + }
  418 + return -1;
  419 +}
  420 +
  421 +static int find_device_type(BlockDriverState *bs, const char *filename)
  422 +{
  423 + BDRVRawState *s = bs->opaque;
  424 + UINT type;
  425 + const char *p;
  426 +
  427 + if (strstart(filename, "\\\\.\\", &p) ||
  428 + strstart(filename, "//./", &p)) {
  429 + if (stristart(p, "PhysicalDrive", NULL))
  430 + return FTYPE_HARDDISK;
  431 + snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
  432 + type = GetDriveType(s->drive_path);
  433 + if (type == DRIVE_CDROM)
  434 + return FTYPE_CD;
  435 + else
  436 + return FTYPE_FILE;
  437 + } else {
  438 + return FTYPE_FILE;
  439 + }
  440 +}
  441 +
  442 +static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
  443 +{
  444 + BDRVRawState *s = bs->opaque;
  445 + int access_flags, create_flags;
  446 + DWORD overlapped;
  447 + char device_name[64];
  448 +
  449 + if (strstart(filename, "/dev/cdrom", NULL)) {
  450 + if (find_cdrom(device_name, sizeof(device_name)) < 0)
  451 + return -ENOENT;
  452 + filename = device_name;
  453 + } else {
  454 + /* transform drive letters into device name */
  455 + if (((filename[0] >= 'a' && filename[0] <= 'z') ||
  456 + (filename[0] >= 'A' && filename[0] <= 'Z')) &&
  457 + filename[1] == ':' && filename[2] == '\0') {
  458 + snprintf(device_name, sizeof(device_name), "\\\\.\\%c:", filename[0]);
  459 + filename = device_name;
  460 + }
  461 + }
  462 + s->type = find_device_type(bs, filename);
  463 +
  464 + if ((flags & BDRV_O_ACCESS) == O_RDWR) {
  465 + access_flags = GENERIC_READ | GENERIC_WRITE;
  466 + } else {
  467 + access_flags = GENERIC_READ;
  468 + }
  469 + create_flags = OPEN_EXISTING;
  470 +
  471 +#ifdef QEMU_IMG
  472 + overlapped = FILE_ATTRIBUTE_NORMAL;
  473 +#else
  474 + overlapped = FILE_FLAG_OVERLAPPED;
  475 +#endif
  476 + s->hfile = CreateFile(filename, access_flags,
  477 + FILE_SHARE_READ, NULL,
  478 + create_flags, overlapped, NULL);
  479 + if (s->hfile == INVALID_HANDLE_VALUE) {
  480 + int err = GetLastError();
  481 +
  482 + if (err == ERROR_ACCESS_DENIED)
  483 + return -EACCES;
  484 + return -1;
  485 + }
  486 + return 0;
  487 +}
  488 +
  489 +#if 0
  490 +/***********************************************/
  491 +/* removable device additional commands */
  492 +
  493 +static int raw_is_inserted(BlockDriverState *bs)
  494 +{
  495 + return 1;
  496 +}
  497 +
  498 +static int raw_media_changed(BlockDriverState *bs)
  499 +{
  500 + return -ENOTSUP;
  501 +}
  502 +
  503 +static int raw_eject(BlockDriverState *bs, int eject_flag)
  504 +{
  505 + DWORD ret_count;
  506 +
  507 + if (s->type == FTYPE_FILE)
  508 + return -ENOTSUP;
  509 + if (eject_flag) {
  510 + DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
  511 + NULL, 0, NULL, 0, &lpBytesReturned, NULL);
  512 + } else {
  513 + DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
  514 + NULL, 0, NULL, 0, &lpBytesReturned, NULL);
  515 + }
  516 +}
  517 +
  518 +static int raw_set_locked(BlockDriverState *bs, int locked)
  519 +{
  520 + return -ENOTSUP;
  521 +}
  522 +#endif
  523 +
  524 +BlockDriver bdrv_host_device = {
  525 + "host_device",
  526 + sizeof(BDRVRawState),
  527 + NULL, /* no probe for protocols */
  528 + hdev_open,
  529 + NULL,
  530 + NULL,
  531 + raw_close,
  532 + NULL,
  533 + raw_flush,
  534 +
  535 +#if 0
  536 + .bdrv_aio_read = raw_aio_read,
  537 + .bdrv_aio_write = raw_aio_write,
  538 + .bdrv_aio_cancel = raw_aio_cancel,
  539 + .aiocb_size = sizeof(RawAIOCB);
  540 +#endif
  541 + .bdrv_pread = raw_pread,
  542 + .bdrv_pwrite = raw_pwrite,
  543 + .bdrv_getlength = raw_getlength,
  544 +};
... ...