#define stderr STDERR
FILE* stderr = NULL;
-static void checkpoint();
+static void checkpoint(void);
#ifdef __MINGW32__
void nonono(const char* file, int line, const char* msg) {
/* does not automatically grow */
static inline void* array_get(array_t* array,unsigned int index) {
- assert(index >= 0);
assert(index < array->next);
return array->pointer + index * array->item_size;
}
{
if((index + 1) * array->item_size > array->size) {
int new_size = (index + 32) * array->item_size;
- array->pointer = realloc(array->pointer, new_size);
+ array->pointer = qemu_realloc(array->pointer, new_size);
if (!array->pointer)
return -1;
array->size = new_size;
static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
if((array->next+count)*array->item_size>array->size) {
int increment=count*array->item_size;
- array->pointer=realloc(array->pointer,array->size+increment);
+ array->pointer=qemu_realloc(array->pointer,array->size+increment);
if(!array->pointer)
return 0;
array->size+=increment;
is=array->item_size;
from=array->pointer+index_from*is;
to=array->pointer+index_to*is;
- buf=malloc(is*count);
+ buf=qemu_malloc(is*count);
memcpy(buf,from,is*count);
if(index_to<index_from)
static int array_index(array_t* array, void* pointer)
{
size_t offset = (char*)pointer - array->pointer;
- assert(offset >= 0);
assert((offset % array->item_size) == 0);
assert(offset/array->item_size < array->next);
return offset/array->item_size;
/* direntry functions */
/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */
-static inline int short2long_name(unsigned char* dest,const char* src)
+static inline int short2long_name(char* dest,const char* src)
{
int i;
+ int len;
for(i=0;i<129 && src[i];i++) {
dest[2*i]=src[i];
dest[2*i+1]=0;
}
+ len=2*i;
dest[2*i]=dest[2*i+1]=0;
for(i=2*i+2;(i%26);i++)
dest[i]=0xff;
- return i;
+ return len;
}
static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename)
entry->begin=0;
entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
}
- for(i=0;i<length;i++) {
+ for(i=0;i<26*number_of_entries;i++) {
int offset=(i%26);
if(offset<10) offset=1+offset;
else if(offset<22) offset=14+offset-10;
static char is_free(const direntry_t* direntry)
{
- /* return direntry->name[0]==0 ; */
- return direntry->attributes == 0 || direntry->name[0]==0xe5;
+ return direntry->name[0]==0xe5 || direntry->name[0]==0x00;
}
static char is_volume_label(const direntry_t* direntry)
uint16_t* entry=array_get(&(s->fat),cluster);
return le16_to_cpu(*entry);
} else {
- const uint8_t* x=s->fat.pointer+cluster*3/2;
+ const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
}
}
entry=array_get_next(&(s->directory));
memset(entry->name,0x20,11);
- strncpy(entry->name,filename,i);
+ memcpy(entry->name, filename, i);
if(j > 0)
for (i = 0; i < 3 && filename[j+1+i]; i++)
if(first_cluster == 0 && (is_dotdot || is_dot))
continue;
- buffer=(char*)malloc(length);
- assert(buffer);
+ buffer=(char*)qemu_malloc(length);
snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
if(stat(buffer,&st)<0) {
memset(&(s->first_sectors[0]),0,0x40*0x200);
s->cluster_size=s->sectors_per_cluster*0x200;
- s->cluster_buffer=malloc(s->cluster_size);
- assert(s->cluster_buffer);
+ s->cluster_buffer=qemu_malloc(s->cluster_size);
/*
* The formula: sc = spf+1+spf*spc*(512*8/fat_type),
{
direntry_t* entry=array_get_next(&(s->directory));
entry->attributes=0x28; /* archive | volume label */
- snprintf(entry->name,11,"QEMU VVFAT");
+ snprintf((char*)entry->name,11,"QEMU VVFAT");
}
/* Now build FAT, and write back information into directory */
s->path = mapping->path;
for (i = 0, cluster = 0; i < s->mapping.next; i++) {
- int j;
/* MS-DOS expects the FAT to be 0 for the root directory
* (except for the media byte). */
/* LATER TODO: still true for FAT32? */
assert(mapping->begin < mapping->end);
+ /* next free cluster */
+ cluster = mapping->end;
+
+ if(cluster > s->cluster_count) {
+ fprintf(stderr,"Directory does not fit in FAT%d (capacity %s)\n",
+ s->fat_type,
+ s->fat_type == 12 ? s->sector_count == 2880 ? "1.44 MB"
+ : "2.88 MB"
+ : "504MB");
+ return -EINVAL;
+ }
+
/* fix fat for entry */
if (fix_fat) {
+ int j;
for(j = mapping->begin; j < mapping->end - 1; j++)
fat_set(s, j, j+1);
fat_set(s, mapping->end - 1, s->max_fat_value);
}
-
- /* next free cluster */
- cluster = mapping->end;
-
- if(cluster > s->cluster_count) {
- fprintf(stderr,"Directory does not fit in FAT%d\n",s->fat_type);
- return -1;
- }
}
mapping = array_get(&(s->mapping), 0);
i = strrchr(dirname, ':') - dirname;
assert(i >= 3);
- if (dirname[i-2] == ':' && isalpha(dirname[i-1]))
+ if (dirname[i-2] == ':' && qemu_isalpha(dirname[i-1]))
/* workaround for DOS drive names */
dirname += i-1;
else
s->current_mapping = mapping;
read_cluster_directory:
offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
- s->cluster = s->directory.pointer+offset
+ s->cluster = (unsigned char*)s->directory.pointer+offset
+ 0x20*s->current_mapping->info.dir.first_dir_index;
assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
unsigned char* c=(unsigned char*)direntry;
int i;
for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
-#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = '°'; j++;}
+#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
ADD_CHAR(c[i]);
for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
ADD_CHAR(c[i]);
}
typedef struct {
- unsigned char name[1024];
+ /*
+ * Since the sequence number is at most 0x3f, and the filename
+ * length is at most 13 times the sequence number, the maximal
+ * filename length is 0x3f * 13 bytes.
+ */
+ unsigned char name[0x3f * 13 + 1];
int checksum, len;
int sequence_number;
} long_file_name;
lfn->sequence_number = pointer[0] & 0x3f;
lfn->checksum = pointer[13];
lfn->name[0] = 0;
+ lfn->name[lfn->sequence_number * 13] = 0;
} else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
return -1;
else if (pointer[13] != lfn->checksum)
}
if (pointer[0] & 0x40)
- lfn->len = offset + strlen(lfn->name + offset);
+ lfn->len = offset + strlen((char*)lfn->name + offset);
return 0;
}
if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
return -1;
else if (s->downcase_short_names)
- lfn->name[i] = tolower(direntry->name[i]);
+ lfn->name[i] = qemu_tolower(direntry->name[i]);
else
lfn->name[i] = direntry->name[i];
}
if (direntry->extension[j] <= ' ' || direntry->extension[j] > 0x7f)
return -2;
else if (s->downcase_short_names)
- lfn->name[i + j] = tolower(direntry->extension[j]);
+ lfn->name[i + j] = qemu_tolower(direntry->extension[j]);
else
lfn->name[i + j] = direntry->extension[j];
}
} else
lfn->name[i + j + 1] = '\0';
- lfn->len = strlen(lfn->name);
+ lfn->len = strlen((char*)lfn->name);
return 0;
}
int cluster_num, const char* path)
{
int ret = 0;
- unsigned char* cluster = malloc(s->cluster_size);
+ unsigned char* cluster = qemu_malloc(s->cluster_size);
direntry_t* direntries = (direntry_t*)cluster;
mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
char path2[PATH_MAX];
assert(path_len < PATH_MAX); /* len was tested before! */
- strcpy(path2, path);
+ pstrcpy(path2, sizeof(path2), path);
path2[path_len] = '/';
path2[path_len + 1] = '\0';
fprintf(stderr, "Error in short name (%d)\n", subret);
goto fail;
}
- if (subret > 0 || !strcmp(lfn.name, ".")
- || !strcmp(lfn.name, ".."))
+ if (subret > 0 || !strcmp((char*)lfn.name, ".")
+ || !strcmp((char*)lfn.name, ".."))
continue;
}
lfn.checksum = 0x100; /* cannot use long name twice */
fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
goto fail;
}
- strcpy(path2 + path_len + 1, lfn.name);
+ pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
+ (char*)lfn.name);
if (is_directory(direntries + i)) {
if (begin_of_direntry(direntries + i) == 0) {
*/
if (s->fat2 == NULL) {
int size = 0x200 * s->sectors_per_fat;
- s->fat2 = malloc(size);
+ s->fat2 = qemu_malloc(size);
memcpy(s->fat2, s->fat.pointer, size);
}
check = vvfat_read(s->bs,
uint32_t first_cluster = c;
mapping_t* mapping = find_mapping_for_cluster(s, c);
uint32_t size = filesize_of_direntry(direntry);
- char* cluster = malloc(s->cluster_size);
+ char* cluster = qemu_malloc(s->cluster_size);
uint32_t i;
int fd = 0;
assert((size - offset == 0 && fat_eof(s, c)) ||
(size > offset && c >=2 && !fat_eof(s, c)));
- assert(size >= 0);
ret = vvfat_read(s->bs, cluster2sector(s, c),
- cluster, (rest_size + 0x1ff) / 0x200);
+ (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
if (ret < 0)
return ret;
mapping_t* m = find_mapping_for_cluster(s,
begin_of_direntry(d));
int l = strlen(m->path);
- char* new_path = malloc(l + diff + 1);
+ char* new_path = qemu_malloc(l + diff + 1);
assert(!strncmp(m->path, mapping->path, l2));
- strcpy(new_path, mapping->path);
- strcpy(new_path + l1, m->path + l2);
+ pstrcpy(new_path, l + diff + 1, mapping->path);
+ pstrcpy(new_path + l1, l + diff + 1 - l1,
+ m->path + l2);
schedule_rename(s, m->begin, new_path);
}
array_init(&(s->commits), sizeof(commit_t));
- s->qcow_filename = malloc(1024);
+ s->qcow_filename = qemu_malloc(1024);
get_tmp_filename(s->qcow_filename, 1024);
if (bdrv_create(&bdrv_qcow,
s->qcow_filename, s->sector_count, "fat:", 0) < 0)
};
#ifdef DEBUG
-static void checkpoint() {
+static void checkpoint(void) {
assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
check1(vvv);
check2(vvv);
print_direntry(NULL);
}
#endif
-