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
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;
};
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.