/* floppy2.c
* Stefano Salvi - 25/9/02
* Programma che legge il boot sector di un disco (floppy o hard disk) con file system FAT,
* ne stampa le caratteristiche e stampa la root directory
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/types.h>
#include <linux/msdos_fs.h>
// Descrittore del disco
struct disco {
int fd; // File Descriptor per il dispositivo
int rootDir; // posizione in byte della root Directory
int rootDirSize; // Dimensione in 'entries' della root directory
};
// Struttura con i campi di bit che descrive la 'data' in formato MS-DOS
struct date {
unsigned int giorno:5;
unsigned int mese:4;
unsigned int anno:7;
};
// Struttura con i campi di bit che descrive l' 'ora' in formato MS-DOS
struct time {
unsigned int sec:5;
unsigned int min:6;
unsigned int ora:5; //perchè si tengono solo i pari
};
int openDevice (char *device, struct disco *d); // apre il device, legge boot rec
void readRootDir (struct disco *d); // Legge l'albero delle directory
int printDirEntry (struct disco *d, int pos); // Stampa un'entry di dir.
int main(int argc, char **argv)
{
struct disco d; // Descrittore del dispositivo
char *device = "/dev/fd0"; // Nome del file (dispositivo) da aprire
if (argc > 1) // Se c'e' almeno un parametro
{
device = argv [1]; // Prende il primo parametro e lo usa come 'dispositivo'
}
if(openDevice(device, &d)) // Apre il dispositivo
{
return 1;
}
readRootDir (&d);
}
/* printDirEntry
* Stampa un'entry di directory.
* Riceve il descrittore del dispositivo (d) e la posizione in byte dell'entry.
* Ritorna la posizione della prossima direntry, oppure 0 se incontra l'ultima
* direntry (nome che comincia con byte 0x00).
* Operazioni:
* - Si posiziona sul record
* - Legge una 'dir entry'
* - Se la 'dir entry' ha nome che comincia per 0x00, ritorna 0
* - Se l'entry non e' 'hidden' o cancellata, la stampa
* - Ritorna la posizione della prossima dir entry.
* Non stampa le entry cancellate (che cominciano per 0xe5) o con gli attributi
* 'hidden,system,readonly,label' (sono nomi estesi, quindi non stampabili)
*/
int printDirEntry (struct disco *d, int pos)
{
struct msdos_dir_entry dirEntry;// Buffer per il record di directory
struct date *p; // Record per visualizzare le date
struct time *t; // Record per visualizzare le ore
int i;
// Posizionamento sulla dir entry
if (lseek(d->fd, pos, SEEK_SET) < 0)
{
printf ("Errore nel posizionamento al byte %d\n",pos);
return 0;
}
// Lettura dir entry
if (read(d->fd,&dirEntry,sizeof(dirEntry)) != sizeof(dirEntry))
{
printf ("Errore nella lettura della DirEntry al byte %d\n",pos);
return 0;
}
if (dirEntry.name[0] == 0) // Entry terminatrice della Directory
{
return 0; // Termina il 'chiamante'
}
/* Se il file non e' 'hidden,system,readonly,label' (nomi estesi) o comincia
*con 0xe5 (file cancellati)
*/
if (dirEntry.attr != (ATTR_HIDDEN | ATTR_RO | ATTR_SYS | ATTR_VOLUME) &&
(dirEntry.name[0] & 0xff) != 0xe5)
{
/* Analizza bit per bit gli 'attr' e per ognuno stampa una lettera */
if(dirEntry.attr & ATTR_RO)
{
printf("R");
}
else
{
printf("-");
}
if(dirEntry.attr&ATTR_HIDDEN)
{
printf("H");
}
else
{
printf("-");
}
if(dirEntry.attr&ATTR_SYS)
{
printf("S");
}
else
{
printf("-");
}
if(dirEntry.attr&ATTR_VOLUME)
{
printf("L");
}
else
{
printf("-");
}
if(dirEntry.attr&ATTR_DIR)
{
printf("D");
}
else
{
printf("-");
}
if(dirEntry.attr&ATTR_ARCH)
{
printf("A ");
}
else
{
printf("- ");
}
/*informazioni sul file*/
for(i=0;i<8;i++) // Otto cratteri del nome
{
printf("%c",dirEntry.name[i]);
}
printf (".");
for(i=0;i<3;i++) // Tre caratteri dell'estensione
{
printf("%c",dirEntry.ext[i]);
}
p=(struct date *)&(dirEntry.date); // Sovrappone 'date' a data
printf(" %d/%02d/%04d ",p->giorno,p->mese,p->anno+1980);
t=(struct time *)&(dirEntry.time); // Sovrappone 'time' a time
printf(" %d:%02d:%02d",t->ora,t->min,t->sec);
printf(" %d\n",(__u32)dirEntry.size);
}
return pos + sizeof (dirEntry);
}
/* readRootDir
* Stampa la root directory del disco.
* Riceve come parametro il descrittore del disco.
* Stampa 'd -> rootDirSize' elementi.
* Se 'printDirEntry' indica che la directory e' teminata, finisce prima.
*/
void readRootDir (struct disco *d)
{
int pos = d -> rootDir; // Posizione della directory
int i; // Contatore entries
for (i = 0; i < d -> rootDirSize; i++) // quante ce ne sono al massimo
{
if ((pos = printDirEntry (d, pos)) == 0) // Stampa una dir entry
{
break; // Se e' l'untima, termina
}
}
}
/* openDevice
* Apre il file 'device', ne legge il boot record, compilando il descrittore
* puntato da 'd'.
* Ritorna 0 se tutto questo funziona.
* Ritorna 1 se c'e' un errore.
*/
int openDevice (char *device, struct disco *d)
{
struct fat_boot_sector boot; // Record nel quale leggere il primo settore
if((d->fd=open(device,O_RDONLY))==-1) // Apre il dispositivo
{
printf("Errore di apertura! Forse mancano i diritti sul dispositivo\n");
return 1;
}
read(d->fd,&boot,sizeof(boot)); // Legge il boot sector
// Compila il descrittore del dispositivo
d->rootDir= (boot.reserved + boot.fats * boot.fat_length) *
*(__u16 *)boot.sector_size; // posizione in byte della root Directory
d->rootDirSize=*(__u16 *)boot.dir_entries; // Dimensione in 'entries' della root directory
// Stampa le caratteristiche interessanti
printf("\nNum\t\t Description\t\t\t Variabile\n");
printf("%s\t Volume Name\t\t\t (system_id[8])\n",boot.system_id);
printf("%d\t\t bytes per logical sector\t (sector_size[2])\n",
*(__u16 *)boot.sector_size); //dimensione settore
printf("%d\t\t sectors/cluster\t\t (cluster_size)\n",boot.cluster_size); //settori per cluster
printf("%d\t\t reserved sectors\t\t (reserved)\n",boot.reserved);
printf("%d\t\t number of FATs\t\t\t (fats)\n",boot.fats);
printf("%d\t\t root directory entries\t\t (dir_entries)\n",*(__u16 *)boot.dir_entries);
printf("%d\t\t number of sectors\t\t (sectors[2])\n",*(__u16*)boot.sectors);
printf("%d\t\t media code\t\t\t (media)\n",boot.media);
printf("%d\t\t sectors/FAT\t\t\t (fat_length)\n",boot.fat_length);
printf("%d\t\t Start in bytes of ROOT dir\n",d->rootDir);
printf("%d\t\t sectors per track\t\t (secs_track)\n",(__u16)boot.secs_track);
printf("%d\t\t number of heads\t\t (heads)\n",boot.heads);
printf("%d\t\t hidden sectors\t\t\t (hidden)\n",boot.hidden);
printf("%d\t\t number of sectors\t\t (total_sect)\n\n",boot.total_sect);
return 0;
}
|