int qemu_ftruncate64(int fd, int64_t length)
{
LARGE_INTEGER li;
+ DWORD dw;
LONG high;
HANDLE h;
BOOL res;
/* get current position, ftruncate do not change position */
li.HighPart = 0;
li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
- if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
+ if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
return -1;
+ }
high = length >> 32;
- if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
+ dw = SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN);
+ if (dw == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
return -1;
+ }
res = SetEndOfFile(h);
/* back to old position */
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
{
BDRVRawState *s = bs->opaque;
- int access_flags, create_flags;
+ int access_flags;
DWORD overlapped;
s->type = FTYPE_FILE;
- if ((flags & BDRV_O_ACCESS) == O_RDWR) {
+ if (flags & BDRV_O_RDWR) {
access_flags = GENERIC_READ | GENERIC_WRITE;
} else {
access_flags = GENERIC_READ;
}
- if (flags & BDRV_O_CREAT) {
- create_flags = CREATE_ALWAYS;
- } else {
- create_flags = OPEN_EXISTING;
- }
+
overlapped = FILE_ATTRIBUTE_NORMAL;
- if ((flags & BDRV_O_NOCACHE))
- overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
- else if (!(flags & BDRV_O_CACHE_WB))
+ if (flags & BDRV_O_NOCACHE)
+ overlapped |= FILE_FLAG_NO_BUFFERING;
+ if (!(flags & BDRV_O_CACHE_WB))
overlapped |= FILE_FLAG_WRITE_THROUGH;
s->hfile = CreateFile(filename, access_flags,
FILE_SHARE_READ, NULL,
- create_flags, overlapped, NULL);
+ OPEN_EXISTING, overlapped, NULL);
if (s->hfile == INVALID_HANDLE_VALUE) {
int err = GetLastError();
return ret_count;
}
-static void raw_flush(BlockDriverState *bs)
+static int raw_flush(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
- FlushFileBuffers(s->hfile);
+ int ret;
+
+ ret = FlushFileBuffers(s->hfile);
+ if (ret == 0) {
+ return -EIO;
+ }
+
+ return 0;
}
static void raw_close(BlockDriverState *bs)
return l.QuadPart;
}
-static int raw_create(const char *filename, int64_t total_size,
- const char *backing_file, int flags)
+static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
+{
+ typedef DWORD (WINAPI * get_compressed_t)(const char *filename,
+ DWORD * high);
+ get_compressed_t get_compressed;
+ struct _stati64 st;
+ const char *filename = bs->filename;
+ /* WinNT support GetCompressedFileSize to determine allocate size */
+ get_compressed =
+ (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"),
+ "GetCompressedFileSizeA");
+ if (get_compressed) {
+ DWORD high, low;
+ low = get_compressed(filename, &high);
+ if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR) {
+ return (((int64_t) high) << 32) + low;
+ }
+ }
+
+ if (_stati64(filename, &st) < 0) {
+ return -1;
+ }
+ return st.st_size;
+}
+
+static int raw_create(const char *filename, QEMUOptionParameter *options)
{
int fd;
+ int64_t total_size = 0;
- if (flags || backing_file)
- return -ENOTSUP;
+ /* Read out options */
+ while (options && options->name) {
+ if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
+ total_size = options->value.n / 512;
+ }
+ options++;
+ }
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
return 0;
}
-static BlockDriver bdrv_raw = {
- .format_name = "raw",
+static QEMUOptionParameter raw_create_options[] = {
+ {
+ .name = BLOCK_OPT_SIZE,
+ .type = OPT_SIZE,
+ .help = "Virtual disk size"
+ },
+ { NULL }
+};
+
+static BlockDriver bdrv_file = {
+ .format_name = "file",
+ .protocol_name = "file",
.instance_size = sizeof(BDRVRawState),
- .bdrv_open = raw_open,
+ .bdrv_file_open = raw_open,
.bdrv_close = raw_close,
.bdrv_create = raw_create,
- .bdrv_flush = raw_flush,
- .bdrv_read = raw_read,
- .bdrv_write = raw_write,
+
+ .bdrv_read = raw_read,
+ .bdrv_write = raw_write,
+ .bdrv_co_flush_to_disk = raw_flush,
+
.bdrv_truncate = raw_truncate,
.bdrv_getlength = raw_getlength,
+ .bdrv_get_allocated_file_size
+ = raw_get_allocated_file_size,
+
+ .create_options = raw_create_options,
};
/***********************************************/
}
}
+static int hdev_probe_device(const char *filename)
+{
+ if (strstart(filename, "/dev/cdrom", NULL))
+ return 100;
+ if (is_windows_drive(filename))
+ return 100;
+ return 0;
+}
+
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
{
BDRVRawState *s = bs->opaque;
}
s->type = find_device_type(bs, filename);
- if ((flags & BDRV_O_ACCESS) == O_RDWR) {
+ if (flags & BDRV_O_RDWR) {
access_flags = GENERIC_READ | GENERIC_WRITE;
} else {
access_flags = GENERIC_READ;
create_flags = OPEN_EXISTING;
overlapped = FILE_ATTRIBUTE_NORMAL;
- if ((flags & BDRV_O_NOCACHE))
- overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
- else if (!(flags & BDRV_O_CACHE_WB))
+ if (flags & BDRV_O_NOCACHE)
+ overlapped |= FILE_FLAG_NO_BUFFERING;
+ if (!(flags & BDRV_O_CACHE_WB))
overlapped |= FILE_FLAG_WRITE_THROUGH;
s->hfile = CreateFile(filename, access_flags,
FILE_SHARE_READ, NULL,
return 0;
}
-#if 0
-/***********************************************/
-/* removable device additional commands */
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
- return 1;
-}
-
-static int raw_media_changed(BlockDriverState *bs)
+static int hdev_has_zero_init(BlockDriverState *bs)
{
- return -ENOTSUP;
-}
-
-static int raw_eject(BlockDriverState *bs, int eject_flag)
-{
- DWORD ret_count;
-
- if (s->type == FTYPE_FILE)
- return -ENOTSUP;
- if (eject_flag) {
- DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
- NULL, 0, NULL, 0, &lpBytesReturned, NULL);
- } else {
- DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
- NULL, 0, NULL, 0, &lpBytesReturned, NULL);
- }
-}
-
-static int raw_set_locked(BlockDriverState *bs, int locked)
-{
- return -ENOTSUP;
+ return 0;
}
-#endif
static BlockDriver bdrv_host_device = {
.format_name = "host_device",
+ .protocol_name = "host_device",
.instance_size = sizeof(BDRVRawState),
- .bdrv_open = hdev_open,
+ .bdrv_probe_device = hdev_probe_device,
+ .bdrv_file_open = hdev_open,
.bdrv_close = raw_close,
- .bdrv_flush = raw_flush,
+ .bdrv_has_zero_init = hdev_has_zero_init,
+
+ .bdrv_read = raw_read,
+ .bdrv_write = raw_write,
+ .bdrv_co_flush_to_disk = raw_flush,
- .bdrv_read = raw_read,
- .bdrv_write = raw_write,
.bdrv_getlength = raw_getlength,
+ .bdrv_get_allocated_file_size
+ = raw_get_allocated_file_size,
};
-static void bdrv_raw_init(void)
+static void bdrv_file_init(void)
{
- bdrv_register(&bdrv_raw);
+ bdrv_register(&bdrv_file);
bdrv_register(&bdrv_host_device);
}
-block_init(bdrv_raw_init);
+block_init(bdrv_file_init);