TAR NTFS : le driver

 

Bien évidemenent nous avons été obligé d'écrire un driver pour les partitions NTFS . Ce driver permet la lecture et l'éciture.

Voici les prototypes et leur description des fonctions que nous avons développé, ainsi que les structures que nous utilisons

 

Les structures :

 

struct filename_attr
{
ntfs_u64 directory; /*le repertoire parent du fichier */
ntfs_u64 file_creation_time; /* date de création du fichier */
ntfs_u64 last_modification_time; /* date de la dernière modification du fichier */
ntfs_u64 last_record_modif_time; /* date de la dernier modification des file record décrivant le fichier */
ntfs_u64 last_access_time; /* data du dernier accès au fichier */
ntfs_u64 data_alloc_size; /* taille de la place disque allouée pour l'attribut data du fichier */
ntfs_u64 data_size; /* taille de m'attribut data du fichier autrement dit la taille du fichier */
ntfs_u64 dosflags; /* indique les différent flags dos (exemple hiden , system , archive , read only , directory )*/
ntfs_u8 name_length; /* nombre de caractèeres unicode du nom de fichier */
ntfs_u8 name_type; /* type du nom de fichier : c'est un champ de bits 0x1 pour les fichiers de type long nom, 0x2 pour les nom de type 8.3 du dos , 0x4 pour les nom au format Posix ) */
ntfs_u16 name[NAMEMAX+1];
};

struct direntry_info
{
ntfs_u64 mft_record_number; /* Inode du fichier */
ntfs_u16 size; /* taille de la direntry */
ntfs_u16 filename_size; /* taille de l'attribut indexe en l'occurence de l'attribut filename */
ntfs_u8 flags; /* peut prendre combinaison de dux valeur (1 : entry has subnode, 2 entry is last ) */
char unknown2[3]; /* Certainement des octet de bourrage c.a.d pour que la taille de la structture soit un multiple de 8 octets */
};

struct direntry
{
struct direntry_info info; /* entête de la direntry */
struct filename_attr filename; /* l'attribut indexé : ici un attribut filename, le seul géré par les volume ntfs 4.0 */
ntfs_u64 subnode; /* pointeur sur le buffer d'allocation d'autre entry dont les l'attributs indexés < l'attribut indéxé de cet entry. NB: n'apparêt que si le flag entry has subnode est positionné dans al direntry info */
};

struct volume_ntfs
{
struct stream *stream; /* structure permettant d'accédé au disque */
ntfs_u16 blocksize; /* taille du secteur */
ntfs_u8 cluster_factor; /* nombre de secteurs dans un cluster */
char mft_cluster_per_record; /* nombre de cluster dans u file record */
ntfs_u16 cluster_size; /* taille du cluster en octet = blocksize * cluster_factor */
ntfs_u16 mft_record_size; /* taille d'un file record en octet = cluster size * cluster_per_record */
ntfs_u64 mft_cluster; /* Numéro de cluster ou se trouve la MFT depuis le début du disque */
ntfs_u64 mft_start; /* offset de la MFT depuis le debut du disque = mft_cluster * cluster_size */
struct fichier *mft; /* le fichier MFT */
struct stream *mft_data; /* stream sur l'attribut data du fichier mft */
struct opened_file *mft_upcase; /* file descriptor du fichier $UPCASE pour la convertion des chaines unicodes */
};

 

struct directory
{
struct indexroot ir;
struct volume_ntfs *vol;
struct fichier *fichier;
struct stream *index_root;
struct stream *index_alloc;
struct buffer subnode;
struct liste *pile;
};

struct opened_file
{
struct fichier *fichier ;
struct stream *data;
};

 

Les fonctions :

 

stream *open_disque(char *dev, int rw);

open_disque retourne le 2ème paramètre de init_volume(); qui est un stream sur un volume

dev est le device du disque que l'on veut ouvrir, par exemple = /dev/hda1

rw prend les attributs standards pour les fonctions RW

 

volume_ntfs *init_volume(volume_ntfs *vntfs, stream *str);

init_volume initialise une structure qui contient outes les infos nécessaires sur la partition NTFS

 

finalize_volume();

Libère toutes les structures initialisées auparavant

 

opened_file *open_file(volume_ntfs *vntfs, char *name, int rw);

vntfs est la structure initialisé par init_volume

name est le nom complet du fichier depuis la racine

rw prend les attributs standards pour les fonctions RW

 

ntfs_u64 file_read(opened_file *file, void *buffer, ntfs_u64 size);

c'est trivial

 

file_lseek(opened_file *file, ntfs_u64 pos, int opt);

file c'est le descripteur de fichier ouvert par open_file

pos c'est l'offset ou l'on veut aller

opt représente soit SEEK_SET soit SEEK_CUR

 

file_close(opened_file *file);

c'est trivial

 

ntfs_u64 find_file(volume_ntfs *vntfs, char *name, filename_attr *fattr);

vntfs volume sur lequel on cherche

name nomdu répertoire que l'on cherche

rempli la structure filename_attr ret retourne l'inode du fichier

 

directory *open_directory(volume_ntfs *vntfs, char *name);

vntfs volume sur lequel on cherche

name nom du directory

retourne un pointeur sur une structure directory

 

int directory_rewind(directory *dir);

retourne au premier direntry

ne renvoie rien, éxécuté par open_directory()

 

int get_next_direntry(directory *dir, direntry *dirent );

remplit la strucure dirnetrye, deja mallocée

retourne 1 si dirent a été effectivement initialisé, 0 sinon.

 

int directory_free(directory *dir);

libère toute la mémoire allouée pour la gestion de ce directory.