version 30 does have some problems, but they should be fixed with this patch (apply it with 'patch vdfuse.c vdfuse.patch'):
Code: Select all
--- a/vdfuse.c 2009-02-16 17:20:01.000000000 -0800
+++ b/vdfuse.c 2009-03-15 14:06:15.663444369 -0700
@@ -78,10 +78,48 @@
#define IN_RING3
+#define PNAMESIZE 15
+
+// Partition table information
+
+typedef struct { // See http://en.wikipedia.org/wiki/Master_boot_record
+ uint8_t status; // status[7] (0x80 = bootable, 0x00 = non-bootable,other = invalid[8])
+ // ** CHS address of first block **
+ uint8_t shead; // first head
+ uint8_t ssector; // first sector is in bits 5-0; bits 9-8 of cylinder are in bits 7-6
+ uint8_t sbits; // first bits 7-0 of cylinder
+ uint8_t type; // partition type
+ // ** CHS address of last block **
+ uint8_t ehead; // last head
+ uint8_t esector; // last sector is in bits 5-0; bits 9-8 of cylinder are in bits 7-6
+ uint8_t ebits; // last bits 7-0 of cylinder
+ uint32_t offset; // LBA of first sector in the partition
+ uint32_t size; // number of blocks in partition, in little-endian format
+} MBRentry;
+
+#define MBR_START 446
+#define EBR_START MBR_START
+
+typedef struct { // See http://en.wikipedia.org/wiki/Extended_boot_record for details
+ MBRentry descriptor;
+ MBRentry chain;
+ MBRentry fill1, fill2;
+ uint16_t signature;
+} EBRentry;
+
+typedef struct {
+ char name[PNAMESIZE+1];// name of partition
+ off_t offset; // offset into disk in bytes
+ uint64_t size; // size of partiton in bytes
+ int no; // partition number
+ MBRentry descriptor; // copy of MBR / EBR descriptor that defines the partion
+} Partition;
+
void usageAndExit (char *optFormat, ...);
void vbprintf (const char *format, ...);
void vdErrorCallback(void *pvUser, int rc, const char *file, unsigned iLine, const char *function, const char *format, va_list va);
void initialisePartitionTable(void);
+void printPartition (Partition *p);
int findPartition (const char* filename);
int detectDiskType (char **disktype, char *filename);
static int VD_open (const char *c, struct fuse_file_info *i);
@@ -122,41 +160,6 @@
#define PARTTYPE_IS_EXTENDED(x) ((x) == 0x05 || (x) == 0x0f || (x) == 0x85)
#define HOSTPARTITION_MAX 100
// large enough for EntireDisk or Partition99
-#define PNAMESIZE 15
-
-// Partition table information
-
-typedef struct { // See http://en.wikipedia.org/wiki/Master_boot_record
- uint8_t status; // status[7] (0x80 = bootable, 0x00 = non-bootable,other = invalid[8])
- // ** CHS address of first block **
- uint8_t shead; // first head
- uint8_t ssector; // first sector is in bits 5-0; bits 9-8 of cylinder are in bits 7-6
- uint8_t sbits; // first bits 7-0 of cylinder
- uint8_t type; // partition type
- // ** CHS address of last block **
- uint8_t ehead; // last head
- uint8_t esector; // last sector is in bits 5-0; bits 9-8 of cylinder are in bits 7-6
- uint8_t ebits; // last bits 7-0 of cylinder
- uint32_t offset; // LBA of first sector in the partition
- uint32_t size; // number of blocks in partition, in little-endian format
-} MBRentry;
-
-#define MBR_START 446
-typedef struct {
- char name[PNAMESIZE+1];// name of partition
- off_t offset; // offset into disk in bytes
- size_t size; // size of partiton in bytes
- int no; // partition number
- MBRentry descriptor; // copy of MBR / EBR descriptor that defines the partion
-} Partition;
-
-#define EBR_START 446
-typedef struct { // See http://en.wikipedia.org/wiki/Extended_boot_record for details
- MBRentry descriptor;
- MBRentry chain;
- MBRentry fill1, fill2;
- uint16_t signature;
-} EBRentry;
Partition partitionTable[HOSTPARTITION_MAX+1]; // Note the partitionTable[0] is reserved for the EntireDisk descriptor
static int lastPartition = 0;
@@ -230,7 +233,6 @@
if (stat(imagefilename, &VDfile_stat)<0) usageAndExit("cannot access imagefile");
if (access (imagefilename, F_OK | R_OK | ((!readonly) ? W_OK : 0))
> 0) usageAndExit("cannot access imagefile");
- if (!debug) verbose = 0;
#define IS_TYPE(s) (strcmp (s, diskType) == 0)
if ( !(IS_TYPE("auto") || IS_TYPE("VDI" ) || IS_TYPE("VMDK") || IS_TYPE("VHD" ) ||
@@ -288,8 +290,8 @@
"\t-a\tallow all users to read disk\n"
"\t-w\tallow all users to read and write to disk\n"
"\t-g\trun in foreground\n"
- "\t-v\tverbose\n"
- "\t-d\tdebug\n", processName);
+ "\t-v\tverbose output\n"
+ "\t-d\tdebug info from FUSE\n", processName);
exit(1);
}
@@ -336,6 +338,8 @@
if (MBRsignature == 0x0000) return; // an unformated disk is allowed but only EntireDisk is defined
if (MBRsignature != 0xaa55) usageAndExit("Invalid MBR found on image with signature 0x%04hX", MBRsignature);
+ vbprintf (">>> Parsing Partition Table ...");
+
//
// Process the four physical partition entires in the MBR
//
@@ -350,9 +354,12 @@
} else {
lastPartition = i;
p->no = i;
- p->offset = (off_t)((p->descriptor).offset) * BLOCKSIZE;
- p->size = (off_t)((p->descriptor).size) * BLOCKSIZE;
+ p->offset = (uint64_t)((p->descriptor).offset);
+ p->offset *= BLOCKSIZE;
+ p->size = (uint64_t)((p->descriptor).size);
+ p->size *= BLOCKSIZE;
sprintf(p->name, "Partition%d", i);
+ printPartition (p);
}
}
//
@@ -381,12 +388,25 @@
p->offset = uStart + uOffset + (off_t)((ebr.descriptor).offset) * BLOCKSIZE;
p->size = (off_t)((ebr.descriptor).size) * BLOCKSIZE;
sprintf(p->name, "Partition%d", i);
+ printPartition (p);
if (ebr.chain.type == 0) break;
if (!PARTTYPE_IS_EXTENDED(ebr.chain.type)) usageAndExit("Logical partition chain broken");
uOffset = (ebr.chain).offset;
}
}
+
+ vbprintf (">>> Done Parsing Partition Table.");
+}
+
+void printPartition (Partition *p) {
+ vbprintf (
+ "Partiton %d:\n"
+ "\tOffset: %lld\n"
+ "\tSize: %lld",
+
+ p->no, p->offset, p->size
+ );
}
int findPartition (const char* filename) {
@@ -411,7 +431,7 @@
else if (strncmp (buf, "<<<", 3) == 0) *disktype = "VDI";
else usageAndExit("cannot autodetect disk type");
- vbprintf ("disktype is %s", *disktype);
+ vbprintf (">>> Disk Type: %s", *disktype);
return 0;
close(fd);
}
@@ -469,8 +489,8 @@
static int VD_open(const char *cName, struct fuse_file_info *i) {
vbprintf ("open: %s, %lld", cName, i->fh);
int n = findPartition(cName);
- if ((n == -1) || (entireDiskOpened && n > 0) || (partitionOpened & n == 0)) return -ENOENT;
- if (readonly && ((i->flags & (O_WRONLY | O_RDWR) != 0))) return -EROFS;
+ if ((n == -1) || (entireDiskOpened && n > 0) || ((partitionOpened & n) == 0)) return -ENOENT;
+ if (readonly && (((i->flags & (O_WRONLY | O_RDWR)) != 0))) return -EROFS;
if (n == 0) entireDiskOpened = 1;
else partitionOpened = 1;
@@ -487,8 +507,8 @@
Partition *p = &(partitionTable[n]);
// if (offset >= p->size) return 0;
// if (offset + len> p->size) len = p->size - offset;
- if (offset >= p->size) return 0;
- if ((offset + len) > p->size) len = p->size - offset;
+ if ((uint64_t)offset >= p->size) return 0;
+ if ((uint64_t)(offset + len) > p->size) len = p->size - offset;
pthread_mutex_lock (&disk_mutex);
int ret = DISKread(offset + p->offset, out, len);
@@ -516,8 +536,8 @@
if (n<0) return -ENOENT;
if ((n == 0) ? partitionOpened : entireDiskOpened) return -EIO;
Partition *p = &(partitionTable[n]);
- if (offset >= p->size) return 0;
- if ((offset + len) > p->size) len = p->size - offset;
+ if ((uint64_t)offset >= p->size) return 0;
+ if ((uint64_t)(offset + len) > p->size) len = p->size - offset;
pthread_mutex_lock (&disk_mutex);
int ret = DISKwrite(offset + p->offset, in, len);