for(i=0;i<11;i++) {
unsigned char c;
- c = (i <= 8) ? entry->name[i] : entry->extension[i-8];
+ c = (i < 8) ? entry->name[i] : entry->extension[i-8];
chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0)) + c;
}
if (st.st_size > 0x7fffffff) {
fprintf(stderr, "File %s is larger than 2GB\n", buffer);
free(buffer);
+ closedir(dir);
return -2;
}
direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);
{
direntry_t* entry=array_get_next(&(s->directory));
entry->attributes=0x28; /* archive | volume label */
- snprintf((char*)entry->name,11,"QEMU VVFAT");
+ memcpy(entry->name,"QEMU VVF",8);
+ memcpy(entry->extension,"AT ",3);
}
/* Now build FAT, and write back information into directory */
mapping->dir_index = 0;
mapping->info.dir.parent_mapping_index = -1;
mapping->first_mapping_index = -1;
- mapping->path = strdup(dirname);
+ mapping->path = qemu_strdup(dirname);
i = strlen(mapping->path);
if (i > 0 && mapping->path[i - 1] == '/')
mapping->path[i - 1] = '\0';
*/
static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
{
- int index3=index1+1;
while(1) {
+ int index3;
mapping_t* mapping;
index3=(index1+index2)/2;
mapping=array_get(&(s->mapping),index3);
int j = 0;
char buffer[1024];
- fprintf(stderr, "direntry 0x%x: ", (int)direntry);
+ fprintf(stderr, "direntry %p: ", direntry);
if(!direntry)
return;
if(is_long_name(direntry)) {
static void print_mapping(const mapping_t* mapping)
{
- fprintf(stderr, "mapping (0x%x): begin, end = %d, %d, dir_index = %d, first_mapping_index = %d, name = %s, mode = 0x%x, " , (int)mapping, mapping->begin, mapping->end, mapping->dir_index, mapping->first_mapping_index, mapping->path, mapping->mode);
+ fprintf(stderr, "mapping (%p): begin, end = %d, %d, dir_index = %d, "
+ "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
+ mapping, mapping->begin, mapping->end, mapping->dir_index,
+ mapping->first_mapping_index, mapping->path, mapping->mode);
+
if (mapping->mode & MODE_DIRECTORY)
fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
else
/* rename */
if (strcmp(basename, basename2))
- schedule_rename(s, cluster_num, strdup(path));
+ schedule_rename(s, cluster_num, qemu_strdup(path));
} else if (is_file(direntry))
/* new file */
- schedule_new_file(s, strdup(path), cluster_num);
+ schedule_new_file(s, qemu_strdup(path), cluster_num);
else {
- assert(0);
+ abort();
return 0;
}
}
if (offset != mapping->info.file.offset + s->cluster_size
* (cluster_num - mapping->begin)) {
/* offset of this cluster in file chain has changed */
- assert(0);
+ abort();
copy_it = 1;
} else if (offset == 0) {
const char* basename = get_basename(mapping->path);
if (mapping->first_mapping_index != first_mapping_index
&& mapping->info.file.offset > 0) {
- assert(0);
+ abort();
copy_it = 1;
}
mapping->mode &= ~MODE_DELETED;
if (strcmp(basename, basename2))
- schedule_rename(s, cluster_num, strdup(path));
+ schedule_rename(s, cluster_num, qemu_strdup(path));
} else
/* new directory */
- schedule_mkdir(s, cluster_num, strdup(path));
+ schedule_mkdir(s, cluster_num, qemu_strdup(path));
lfn_init(&lfn);
do {
goto fail;
}
} else
- assert(0); /* cluster_count = 0; */
+ abort(); /* cluster_count = 0; */
ret += cluster_count;
}
c = c1;
}
- ftruncate(fd, size);
+ if (ftruncate(fd, size)) {
+ perror("ftruncate()");
+ close(fd);
+ return -4;
+ }
close(fd);
return commit_mappings(s, first_cluster, dir_index);
fprintf(stderr, "deleted\n");
continue;
}
- assert(mapping->dir_index >= 0);
assert(mapping->dir_index < s->directory.next);
direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
commit_t* commit = array_get(&(s->commits), i);
switch(commit->action) {
case ACTION_RENAME: case ACTION_MKDIR:
- assert(0);
+ abort();
fail = -2;
break;
case ACTION_WRITEOUT: {
+#ifndef NDEBUG
+ /* these variables are only used by assert() below */
direntry_t* entry = array_get(&(s->directory),
commit->param.writeout.dir_index);
uint32_t begin = begin_of_direntry(entry);
mapping_t* mapping = find_mapping_for_cluster(s, begin);
+#endif
assert(mapping);
assert(mapping->begin == begin);
break;
}
default:
- assert(0);
+ abort();
}
}
if (i > 0 && array_remove_slice(&(s->commits), 0, i))
ret = handle_renames_and_mkdirs(s);
if (ret) {
fprintf(stderr, "Error handling renames (%d)\n", ret);
- assert(0);
+ abort();
return ret;
}
ret = commit_direntries(s, 0, -1);
if (ret) {
fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
- assert(0);
+ abort();
return ret;
}
ret = handle_commits(s);
if (ret) {
fprintf(stderr, "Error handling commits (%d)\n", ret);
- assert(0);
+ abort();
return ret;
}
ret = handle_deletes(s);
if (ret) {
fprintf(stderr, "Error deleting\n");
- assert(0);
+ abort();
return ret;
}
DLOG(checkpoint());
+ /* Check if we're operating in read-only mode */
+ if (s->qcow == NULL) {
+ return -EACCES;
+ }
+
vvfat_close_current_file(s);
/*
static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
const uint8_t* buffer, int nb_sectors) {
- BDRVVVFATState* s = bs->opaque;
+ BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
return try_commit(s);
}
static void write_target_close(BlockDriverState *bs) {
- BDRVVVFATState* s = bs->opaque;
+ BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
bdrv_delete(s->qcow);
free(s->qcow_filename);
}
{
BlockDriver *bdrv_qcow;
QEMUOptionParameter *options;
+ int ret;
int size = sector2cluster(s, s->sector_count);
s->used_clusters = calloc(size, 1);
if (bdrv_create(bdrv_qcow, s->qcow_filename, options) < 0)
return -1;
+
s->qcow = bdrv_new("");
- if (s->qcow == NULL || bdrv_open(s->qcow, s->qcow_filename, 0) < 0)
- return -1;
+ if (s->qcow == NULL) {
+ return -1;
+ }
+
+ ret = bdrv_open(s->qcow, s->qcow_filename,
+ BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow);
+ if (ret < 0) {
+ return ret;
+ }
#ifndef _WIN32
unlink(s->qcow_filename);
s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1);
s->bs->backing_hd->drv = &vvfat_write_target;
- s->bs->backing_hd->opaque = s;
+ s->bs->backing_hd->opaque = qemu_malloc(sizeof(void*));
+ *(void**)s->bs->backing_hd->opaque = s;
return 0;
}
static BlockDriver bdrv_vvfat = {
.format_name = "vvfat",
.instance_size = sizeof(BDRVVVFATState),
- .bdrv_open = vvfat_open,
+ .bdrv_file_open = vvfat_open,
.bdrv_read = vvfat_read,
.bdrv_write = vvfat_write,
.bdrv_close = vvfat_close,
return;
/* avoid compiler warnings: */
hexdump(NULL, 100);
- remove_mapping(vvv, NULL);
+ remove_mapping(vvv, 0);
print_mapping(NULL);
print_direntry(NULL);
}