Random bug fixes from code inspection, by Wang Cheng Yeh.
[qemu] / block-raw.c
index 8cf1988..29882e1 100644 (file)
@@ -838,6 +838,7 @@ BlockDriver bdrv_host_device = {
 
 #define FTYPE_FILE 0
 #define FTYPE_CD     1
+#define FTYPE_HARDDISK 2
 
 typedef struct BDRVRawState {
     HANDLE hfile;
@@ -913,8 +914,13 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
     s->hfile = CreateFile(filename, access_flags, 
                           FILE_SHARE_READ, NULL,
                           create_flags, overlapped, NULL);
-    if (s->hfile == INVALID_HANDLE_VALUE) 
+    if (s->hfile == INVALID_HANDLE_VALUE) {
+        int err = GetLastError();
+
+        if (err == ERROR_ACCESS_DENIED)
+            return -EACCES;
         return -1;
+    }
     return 0;
 }
 
@@ -1098,6 +1104,9 @@ static int64_t raw_getlength(BlockDriverState *bs)
     BDRVRawState *s = bs->opaque;
     LARGE_INTEGER l;
     ULARGE_INTEGER available, total, total_free; 
+    DISK_GEOMETRY dg;
+    DWORD count;
+    BOOL status;
 
     switch(s->type) {
     case FTYPE_FILE:
@@ -1110,6 +1119,14 @@ static int64_t raw_getlength(BlockDriverState *bs)
             return -EIO;
         l.QuadPart = total.QuadPart;
         break;
+    case FTYPE_HARDDISK:
+        status = DeviceIoControl(s->hfile, IOCTL_DISK_GET_DRIVE_GEOMETRY,
+                                 NULL, 0, &dg, sizeof(dg), &count, NULL);
+        if (status != FALSE) {
+            l.QuadPart = dg.Cylinders.QuadPart * dg.TracksPerCylinder
+                * dg.SectorsPerTrack * dg.BytesPerSector;
+        }
+        break;
     default:
         return -EIO;
     }
@@ -1216,6 +1233,8 @@ static int find_device_type(BlockDriverState *bs, const char *filename)
 
     if (strstart(filename, "\\\\.\\", &p) ||
         strstart(filename, "//./", &p)) {
+        if (stristart(p, "PhysicalDrive", NULL))
+            return FTYPE_HARDDISK;
         snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
         type = GetDriveType(s->drive_path);
         if (type == DRIVE_CDROM)
@@ -1248,7 +1267,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
         }
     }
     s->type = find_device_type(bs, filename);
-
+    
     if ((flags & BDRV_O_ACCESS) == O_RDWR) {
         access_flags = GENERIC_READ | GENERIC_WRITE;
     } else {
@@ -1264,8 +1283,13 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
     s->hfile = CreateFile(filename, access_flags, 
                           FILE_SHARE_READ, NULL,
                           create_flags, overlapped, NULL);
-    if (s->hfile == INVALID_HANDLE_VALUE) 
+    if (s->hfile == INVALID_HANDLE_VALUE) {
+        int err = GetLastError();
+
+        if (err == ERROR_ACCESS_DENIED)
+            return -EACCES;
         return -1;
+    }
     return 0;
 }