Commit 223d4670a0cf539a0e8cc6a23aad28a8340dded8
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
Showing
4 changed files
with
558 additions
and
523 deletions
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 | +}; | ... | ... |