static void dump_boot(DOS_FS *fs,struct boot_sector *b,unsigned lss) { unsigned short sectors; printf("Boot sector contents:\n"); if (!atari_format) { char id[9]; strncpy(id,b->system_id,8); id[8] = 0; printf("System ID \"%s\"\n",id); } else { /* On Atari, a 24 bit serial number is stored at offset 8 of the boot * sector */ printf("Serial number 0x%x\n", b->system_id[5] | (b->system_id[6]<<8) | (b->system_id[7]<<16)); } printf("Media byte 0x%02x (%s)\n",b->media,get_media_descr(b->media)); printf("%10d bytes per logical sector\n",GET_UNALIGNED_W(b->sector_size)); printf("%10d bytes per cluster\n",fs->cluster_size); printf("%10d reserved sector%s\n",CF_LE_W(b->reserved), CF_LE_W(b->reserved) == 1 ? "" : "s"); printf("First FAT starts at byte %llu (sector %llu)\n", (unsigned long long)fs->fat_start, (unsigned long long)fs->fat_start/lss); printf("%10d FATs, %d bit entries\n",b->fats,fs->fat_bits); printf("%10d bytes per FAT (= %u sectors)\n",fs->fat_size, fs->fat_size/lss); if (!fs->root_cluster) { printf("Root directory starts at byte %llu (sector %llu)\n", (unsigned long long)fs->root_start, (unsigned long long)fs->root_start/lss); printf("%10d root directory entries\n",fs->root_entries); } else { printf( "Root directory start at cluster %lu (arbitrary size)\n", fs->root_cluster); } printf("Data area starts at byte %llu (sector %llu)\n", (unsigned long long)fs->data_start, (unsigned long long)fs->data_start/lss); printf("%10lu data clusters (%llu bytes)\n",fs->clusters, (unsigned long long)fs->clusters*fs->cluster_size); printf("%u sectors/track, %u heads\n",CF_LE_W(b->secs_track), CF_LE_W(b->heads)); printf("%10u hidden sectors\n", atari_format ? /* On Atari, the hidden field is only 16 bit wide and unused */ (((unsigned char *)&b->hidden)[0] | ((unsigned char *)&b->hidden)[1] << 8) : CF_LE_L(b->hidden)); sectors = GET_UNALIGNED_W( b->sectors ); printf("%10u sectors total\n", sectors ? sectors : CF_LE_L(b->total_sect)); }
static void get_fat(FAT_ENTRY *entry,void *fat,unsigned long cluster,DOS_FS *fs) { unsigned char *ptr; switch(fs->fat_bits) { case 12: ptr = &((unsigned char *) fat)[cluster*3/2]; entry->value = 0xfff & (cluster & 1 ? (ptr[0] >> 4) | (ptr[1] << 4) : (ptr[0] | ptr[1] << 8)); break; case 16: entry->value = CF_LE_W(((unsigned short *) fat)[cluster]); break; case 32: /* According to M$, the high 4 bits of a FAT32 entry are reserved and * are not part of the cluster number. So we cut them off. */ { unsigned long e = CF_LE_L(((unsigned long *) fat)[cluster]); entry->value = e & 0xfffffff; entry->reserved = e >> 28; } break; default: die("Bad FAT entry size: %d bits.",fs->fat_bits); } entry->owner = NULL; }
/* msdos_find_name -- * Find the node which correspondes to the name, open fat-file which * correspondes to the found node and close fat-file which correspondes * to the node we searched in. * * PARAMETERS: * parent_loc - parent node description * name - name to find * * RETURNS: * RC_OK and updated 'parent_loc' on success, or -1 if error * occured (errno set apropriately) * */ int msdos_find_name( rtems_filesystem_location_info_t *parent_loc, char *name ) { int rc = RC_OK; msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info; fat_file_fd_t *fat_fd = NULL; fat_auxiliary_t aux; unsigned short time_val = 0; unsigned short date = 0; char node_entry[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; memset(node_entry, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); /* * find the node which correspondes to the name in the directory pointed by * 'parent_loc' */ rc = msdos_get_name_node(parent_loc, name, &aux, node_entry); if (rc != RC_OK) return rc; /* open fat-file corresponded to the found node */ rc = fat_file_open(parent_loc->mt_entry, aux.cln, aux.ofs, &fat_fd); if (rc != RC_OK) return rc; /* * I don't like this if, but: we should do it , or should write new file * size and first cluster num to the disk after each write operation * (even if one byte is written - that is TOO non-optimize) because * otherwise real values of these fields stored in fat-file descriptor * may be accidentely rewritten with wrong values stored on the disk */ if (fat_fd->links_num == 1) { fat_fd->info_cln = aux.cln; fat_fd->info_ofs = aux.ofs; fat_fd->cln = MSDOS_EXTRACT_CLUSTER_NUM(node_entry); fat_fd->first_char = *MSDOS_DIR_NAME(node_entry); time_val = *MSDOS_DIR_WRITE_TIME(node_entry); date = *MSDOS_DIR_WRITE_DATE(node_entry); fat_fd->mtime = msdos_date_dos2unix(CF_LE_W(time_val), CF_LE_W(date)); if ((*MSDOS_DIR_ATTR(node_entry)) & MSDOS_ATTR_DIRECTORY) { fat_fd->fat_file_type = FAT_DIRECTORY; fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT; rc = fat_file_size(parent_loc->mt_entry, fat_fd); if (rc != RC_OK) { fat_file_close(parent_loc->mt_entry, fat_fd); return rc; } } else { fat_fd->fat_file_size = CF_LE_L(*MSDOS_DIR_FILE_SIZE(node_entry)); fat_fd->fat_file_type = FAT_FILE; fat_fd->size_limit = MSDOS_MAX_FILE_SIZE; } /* these data is not actual for zero-length fat-file */ fat_fd->map.file_cln = 0; fat_fd->map.disk_cln = fat_fd->cln; if ((fat_fd->fat_file_size != 0) && (fat_fd->fat_file_size <= fs_info->fat.vol.bpc)) { fat_fd->map.last_cln = fat_fd->cln; } else { fat_fd->map.last_cln = FAT_UNDEFINED_VALUE; } } /* close fat-file corresponded to the node we searched in */ rc = fat_file_close(parent_loc->mt_entry, parent_loc->node_access); if (rc != RC_OK) { fat_file_close(parent_loc->mt_entry, fat_fd); return rc; } /* update node_info_ptr field */ parent_loc->node_access = fat_fd; return rc; }