18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Block driver for RAW files (win32)
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2006 Fabrice Bellard
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions:
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software.
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE.
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-common.h"
257a78db75ad42aea283f5073f51891464104a9fc3David 'Digit' Turner#include "qemu/timer.h"
26e1e03df288d5a44bfbffbd86588395c7cbbc27dfDavid 'Digit' Turner#include "block/block_int.h"
27e90d665cd63a0bc5c3306e1ee3e98ad362546b16David 'Digit' Turner#include "qemu/module.h"
285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <windows.h>
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <winioctl.h>
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define FTYPE_FILE 0
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define FTYPE_CD     1
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define FTYPE_HARDDISK 2
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct BDRVRawState {
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    HANDLE hfile;
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int type;
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char drive_path[16]; /* format: "d:\" */
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} BDRVRawState;
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint qemu_ftruncate64(int fd, int64_t length)
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    LARGE_INTEGER li;
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    LONG high;
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    HANDLE h;
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BOOL res;
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return -1;
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    h = (HANDLE)_get_osfhandle(fd);
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* get current position, ftruncate do not change position */
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    li.HighPart = 0;
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return -1;
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    high = length >> 32;
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return -1;
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res = SetEndOfFile(h);
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* back to old position */
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res ? 0 : -1;
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int set_sparse(int fd)
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DWORD returned;
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project				 NULL, 0, NULL, 0, &returned, NULL);
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int raw_open(BlockDriverState *bs, const char *filename, int flags)
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BDRVRawState *s = bs->opaque;
79cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    int access_flags;
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DWORD overlapped;
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->type = FTYPE_FILE;
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
84cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (flags & BDRV_O_RDWR) {
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        access_flags = GENERIC_READ | GENERIC_WRITE;
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        access_flags = GENERIC_READ;
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
89cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    overlapped = FILE_ATTRIBUTE_NORMAL;
915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ((flags & BDRV_O_NOCACHE))
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (!(flags & BDRV_O_CACHE_WB))
945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        overlapped |= FILE_FLAG_WRITE_THROUGH;
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->hfile = CreateFile(filename, access_flags,
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          FILE_SHARE_READ, NULL,
97cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner                          OPEN_EXISTING, overlapped, NULL);
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->hfile == INVALID_HANDLE_VALUE) {
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int err = GetLastError();
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (err == ERROR_ACCESS_DENIED)
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -EACCES;
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int raw_read(BlockDriverState *bs, int64_t sector_num,
1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    uint8_t *buf, int nb_sectors)
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BDRVRawState *s = bs->opaque;
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    OVERLAPPED ov;
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DWORD ret_count;
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t offset = sector_num * 512;
1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int count = nb_sectors * 512;
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(&ov, 0, sizeof(ov));
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ov.Offset = offset;
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ov.OffsetHigh = offset >> 32;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = ReadFile(s->hfile, buf, count, &ret_count, &ov);
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!ret)
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ret_count;
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret_count == count)
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret_count = 0;
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret_count;
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int raw_write(BlockDriverState *bs, int64_t sector_num,
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     const uint8_t *buf, int nb_sectors)
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BDRVRawState *s = bs->opaque;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    OVERLAPPED ov;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DWORD ret_count;
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t offset = sector_num * 512;
1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int count = nb_sectors * 512;
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(&ov, 0, sizeof(ov));
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ov.Offset = offset;
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ov.OffsetHigh = offset >> 32;
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = WriteFile(s->hfile, buf, count, &ret_count, &ov);
1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!ret)
1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return ret_count;
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (ret_count == count)
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret_count = 0;
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret_count;
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void raw_flush(BlockDriverState *bs)
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BDRVRawState *s = bs->opaque;
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FlushFileBuffers(s->hfile);
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void raw_close(BlockDriverState *bs)
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BDRVRawState *s = bs->opaque;
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CloseHandle(s->hfile);
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int raw_truncate(BlockDriverState *bs, int64_t offset)
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BDRVRawState *s = bs->opaque;
1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    LONG low, high;
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    low = offset;
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    high = offset >> 32;
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN))
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return -EIO;
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!SetEndOfFile(s->hfile))
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -EIO;
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int64_t raw_getlength(BlockDriverState *bs)
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BDRVRawState *s = bs->opaque;
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    LARGE_INTEGER l;
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ULARGE_INTEGER available, total, total_free;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DISK_GEOMETRY_EX dg;
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DWORD count;
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BOOL status;
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch(s->type) {
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case FTYPE_FILE:
1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        l.LowPart = GetFileSize(s->hfile, (PDWORD)&l.HighPart);
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (l.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -EIO;
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case FTYPE_CD:
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!GetDiskFreeSpaceEx(s->drive_path, &available, &total, &total_free))
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -EIO;
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        l.QuadPart = total.QuadPart;
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case FTYPE_HARDDISK:
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                 NULL, 0, &dg, sizeof(dg), &count, NULL);
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (status != 0) {
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            l = dg.DiskSize;
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -EIO;
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return l.QuadPart;
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int raw_create(const char *filename, QEMUOptionParameter *options)
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int fd;
2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int64_t total_size = 0;
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Read out options */
2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (options && options->name) {
2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            total_size = options->value.n / 512;
2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        options++;
2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              0644);
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fd < 0)
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -EIO;
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    set_sparse(fd);
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ftruncate(fd, total_size * 512);
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    close(fd);
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic QEMUOptionParameter raw_create_options[] = {
2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    {
2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        .name = BLOCK_OPT_SIZE,
2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        .type = OPT_SIZE,
2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        .help = "Virtual disk size"
2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    },
2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    { NULL }
2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
241cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic BlockDriver bdrv_file = {
242cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    .format_name	= "file",
243cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    .protocol_name	= "file",
2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .instance_size	= sizeof(BDRVRawState),
245cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    .bdrv_file_open	= raw_open,
2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_close		= raw_close,
2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_create	= raw_create,
2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_flush		= raw_flush,
2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_read		= raw_read,
2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_write		= raw_write,
2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_truncate	= raw_truncate,
2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_getlength	= raw_getlength,
2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .create_options = raw_create_options,
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/***********************************************/
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* host device */
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int find_cdrom(char *cdrom_name, int cdrom_name_size)
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char drives[256], *pdrv = drives;
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    UINT type;
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    memset(drives, 0, sizeof(drives));
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    GetLogicalDriveStrings(sizeof(drives), drives);
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while(pdrv[0] != '\0') {
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        type = GetDriveType(pdrv);
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(type) {
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case DRIVE_CDROM:
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            snprintf(cdrom_name, cdrom_name_size, "\\\\.\\%c:", pdrv[0]);
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        pdrv += lstrlen(pdrv) + 1;
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -1;
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int find_device_type(BlockDriverState *bs, const char *filename)
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BDRVRawState *s = bs->opaque;
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    UINT type;
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *p;
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strstart(filename, "\\\\.\\", &p) ||
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strstart(filename, "//./", &p)) {
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (stristart(p, "PhysicalDrive", NULL))
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return FTYPE_HARDDISK;
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        type = GetDriveType(s->drive_path);
2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (type) {
2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case DRIVE_REMOVABLE:
2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case DRIVE_FIXED:
2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return FTYPE_HARDDISK;
2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case DRIVE_CDROM:
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return FTYPE_CD;
2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default:
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return FTYPE_FILE;
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return FTYPE_FILE;
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int hdev_probe_device(const char *filename)
3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
3085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strstart(filename, "/dev/cdrom", NULL))
3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 100;
3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (is_windows_drive(filename))
3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 100;
3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int hdev_open(BlockDriverState *bs, const char *filename, int flags)
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    BDRVRawState *s = bs->opaque;
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int access_flags, create_flags;
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DWORD overlapped;
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char device_name[64];
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strstart(filename, "/dev/cdrom", NULL)) {
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (find_cdrom(device_name, sizeof(device_name)) < 0)
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -ENOENT;
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        filename = device_name;
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* transform drive letters into device name */
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (((filename[0] >= 'a' && filename[0] <= 'z') ||
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             (filename[0] >= 'A' && filename[0] <= 'Z')) &&
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            filename[1] == ':' && filename[2] == '\0') {
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            snprintf(device_name, sizeof(device_name), "\\\\.\\%c:", filename[0]);
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            filename = device_name;
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->type = find_device_type(bs, filename);
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
337cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    if (flags & BDRV_O_RDWR) {
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        access_flags = GENERIC_READ | GENERIC_WRITE;
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        access_flags = GENERIC_READ;
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    create_flags = OPEN_EXISTING;
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    overlapped = FILE_ATTRIBUTE_NORMAL;
3455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ((flags & BDRV_O_NOCACHE))
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        overlapped |= FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH;
3475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (!(flags & BDRV_O_CACHE_WB))
3485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        overlapped |= FILE_FLAG_WRITE_THROUGH;
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->hfile = CreateFile(filename, access_flags,
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          FILE_SHARE_READ, NULL,
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          create_flags, overlapped, NULL);
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->hfile == INVALID_HANDLE_VALUE) {
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        int err = GetLastError();
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (err == ERROR_ACCESS_DENIED)
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -EACCES;
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/***********************************************/
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* removable device additional commands */
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int raw_is_inserted(BlockDriverState *bs)
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int raw_media_changed(BlockDriverState *bs)
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -ENOTSUP;
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int raw_eject(BlockDriverState *bs, int eject_flag)
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DWORD ret_count;
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->type == FTYPE_FILE)
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -ENOTSUP;
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (eject_flag) {
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DeviceIoControl(s->hfile, IOCTL_STORAGE_EJECT_MEDIA,
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        NULL, 0, NULL, 0, &lpBytesReturned, NULL);
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DeviceIoControl(s->hfile, IOCTL_STORAGE_LOAD_MEDIA,
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        NULL, 0, NULL, 0, &lpBytesReturned, NULL);
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int raw_set_locked(BlockDriverState *bs, int locked)
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return -ENOTSUP;
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
397cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic int hdev_has_zero_init(BlockDriverState *bs)
398cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner{
399cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    return 0;
400cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner}
401cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner
4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic BlockDriver bdrv_host_device = {
4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .format_name	= "host_device",
404cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    .protocol_name	= "host_device",
4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .instance_size	= sizeof(BDRVRawState),
4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_probe_device	= hdev_probe_device,
407cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    .bdrv_file_open	= hdev_open,
4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_close		= raw_close,
4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_flush		= raw_flush,
410cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    .bdrv_has_zero_init = hdev_has_zero_init,
4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_read		= raw_read,
4135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_write	        = raw_write,
4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    .bdrv_getlength	= raw_getlength,
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
4165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
417cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerstatic void bdrv_file_init(void)
4185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
419cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turner    bdrv_register(&bdrv_file);
4205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    bdrv_register(&bdrv_host_device);
4215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
423cb42a1b1461e02efb034582ac5d8f71534723b92David 'Digit' Turnerblock_init(bdrv_file_init);
424