Capítulo – 15
PROGRAMAÇÃO PARA LIMPADORES DE DADOS
Introdução
Já discutimos que quando você exclui qualquer arquivo de um disco, as informações não são completamente apagadas do disco, mas são marcadas como disponíveis para gravar novos dados nele.
Quando formatamos um disco, todas as informações sobre os arquivos e diretórios do disco, como registros FAT e diretório raiz, são apagadas, mas a área de dados permanece inalterada e nada da área de dados do disco é apagado. Os dados excluídos ou formatados pelo sistema operacional permanecem na área de dados como estão e podem ser recuperados com alguns esforços de recuperação de dados e software de recuperação de dados.
Portanto, a necessidade de apagar completamente os dados do disco leva à necessidade de um programa que apague completamente os dados do disco. Para fazer isso, não basta simplesmente excluir arquivos ou simplesmente formatar o disco; os dados no disco devem ser substituídos por outros dados.
Programas usados para apagar completamente dados de um disco são conhecidos como programas de apagamento de dados. Esses programas gravam caracteres aleatórios na área de dados para sobrescrever os dados e apagar todas as informações armazenadas anteriormente no disco.
Quando os dados se tornam completamente irrecuperáveis
Para apagar dados, a área de dados no disco deve ser substituída por outros dados, mas o problema não termina aí. Para complicar ainda mais as coisas, a tendência dos discos magnéticos de lembrar dados que foram sobrescritos exige que os dados também sejam sobrescritos diversas vezes com sequências de dados aleatórias, de modo que não possam ser recuperados mesmo com ferramentas sofisticadas de recuperação de dados.
Isso ocorre porque hoje existem tecnologias disponíveis que permitem a recuperação de dados mesmo após o uso de algumas ferramentas simples de exclusão de dados.
Alguns produtos de eliminação de dados substituem dados com zeros binários e uns binários. Escrever uma série de zeros binários e uns binários proporciona o efeito de reescrita mais profundo, já que esses valores são os valores magnéticos mínimo e máximo, respectivamente.
Embora esta seja a teoria do programa ideal de eliminação de dados, geralmente, sobrescrever os dados com um caractere ASCII aleatório é suficiente. O motivo para dizer isso é que a recuperação com ferramentas e tecnologias sofisticadas não pode ser usada para recuperar dados de nenhuma organização para recuperação de dados de rotina, pois essas tecnologias são muito caras e custam milhões até mesmo para uma única recuperação. Além disso, essas tecnologias estão disponíveis apenas em alguns países do mundo.
Discutiremos apenas a substituição simples de dados para apagar dados do disco. No entanto, você pode modificar ainda mais os mesmos programas para escrever apenas caracteres aleatórios com um pouco de esforço. Os dados apagados por essa ideia também não podem ser recuperados por nenhum software de recuperação de dados.
Por que a exclusão de dados é tão importante?
Quando discutimos métodos de recuperação de dados, garantimos ao usuário que os dados podem ser recuperados com alguns esforços gerais ou especiais de recuperação de dados. Mas a recuperação de dados nem sempre é um recurso desejado e esperado por todos.
Pode haver muitas pessoas ou organizações que estão sempre prontas para apagar os dados em seus discos de tal forma que eles não possam ser recuperados de forma alguma. Nesses casos, o disco pode conter dados muito sensíveis que, se caírem em mãos erradas, podem causar danos à organização ou ao usuário devido ao uso indevido das informações.
Como sabemos, a necessidade de cada vez mais espaço no disco rígido cresce a cada dia. Como resultado, unidades antigas e de baixa capacidade estão sendo substituídas por unidades novas e de alta capacidade em grande escala todos os anos em quase todas as organizações. Se esses discos antigos caírem em mãos erradas, isso poderá criar um problema muito sério para esta organização.
De acordo com uma notícia publicada pelo CNET News.com em 16 de janeiro de 2003, os estudantes do MIT Simon Garfinkel e Abby Shelat estavam comprando discos rígidos antigos para fins de pesquisa na Internet e em outras vendas de discos usados para obter acesso a grandes quantidades de informações pessoais que as pessoas não se preocupam em excluir.
Depois de comprar 158 unidades por cerca de US$ 1.000, eles conseguiram coletar mais de 5.000 números de cartão de crédito, registros médicos, informações financeiras pessoais e corporativas detalhadas e vários gigabytes de e-mails, códigos-fonte e outras informações.
A dupla de estudantes compilou suas descobertas em um relatório intitulado "Lembrança de dados transmitidos: um estudo de higienização de discos", publicado na edição de fevereiro do IEEE Security and Privacy.
Os principais pontos que surgiram da pesquisa são que o mercado de discos rígidos de segunda mão está cheio de informações pessoais, o que torna muito fácil para um comprador mal-intencionado assumir a identidade de outra pessoa.
Escrevendo programa para limpador de dados não destrutivo
O limpador de dados não destrutivo é um tipo de programa de limpeza de dados com o qual podemos limpar todo o “espaço não alocado” do volume do disco, sem danificar os dados armazenados no disco, de forma alguma.
O escopo desse limpador de dados é nos casos em que você deseja limpar todo o espaço não alocado do volume do disco enquanto os dados alocados armazenados no volume devem permanecer intocados. Esse tipo de programa de limpeza de dados também limpa a área de dados de arquivos excluídos.
A codificação do programa para um tipo de programa de limpeza de dados não destrutivo foi fornecida a seguir:
///// Programa para um limpador de dados não destrutivo \\\\\
#incluir <stdio.h>
unsigned int file_num=0; /* Fornece número de arquivo
Durante a criação automática
de arquivos de dados temporários */
float status=0; /* Quanto espaço em disco é
ainda escrito */
static char dbuf[40000]; /* Buffer de dados para escrever
Arquivos temporários com */
char file_extension[5]=".ptt";/* Extensões exclusivas para
Arquivos Temporários */
char temp[5]; /* Número do arquivo convertido para
Corda */
char filename[40]; /* Nome do arquivo temporário */
vazio principal()
{
int sem sinal i=0;
clrscr();
enquanto(i<40000)
{
dbuf[i] = ' ';
eu++;
}
gotoxy(10,14);cprintf("MB ainda escrito...");
enquanto(1)
{
/* Lógica para criar arquivos temporários automaticamente com nome único */
strcpy(nome do arquivo,"TTPT");
itoa(número_do_arquivo,temp,10);
strcat(nome do arquivo,temp);
strcat(nome_do_arquivo,extensão_do_arquivo);
num_arquivo++;
write_to_temp(nome_do_arquivo);
}
} //// Fim do Main \\\\
///// Função para escrever os dados em arquivo temporário \\\\\
write_to_temp(char *nome_do_arquivo)
{
int sem sinal i, contagem=1;
flutuar buf_status=0;
ARQUIVO *tt;
if((tt=fopen(nome do arquivo,"wb"))==NULL)
{
fclose(tt);
printf("\n Ocorreu um erro ao criar temporário
arquivo, ");
printf("\n Removendo arquivos temporários após KEY BOARD
BATER");
obter();
remove_temp_file();/* Remover todos os arquivos temporários */
}
enquanto(1)
{
para(i=0;i<50;i++)
{
fprintf(tt,"%s",dbuf);
}
buf_status = (float)((40000*50*contagem)/512);
estado=estado+(40000*50);
contar++;
gotoxi(10,14);
cprintf("%.0f",(flutuante)(status/1000000));
se(kbhit())
{
fclose(tt);
printf("\n Removendo arquivos temporários, por favor
Espere...");
remover_arquivo_temp();
}
se(status_buf>=10000)
{
fclose(tt);
retornar;
}
}
}
/* Função para excluir arquivos temporários automaticamente */
remover_arquivo_temp()
{
int i=0;
para(i=0;i<=núm_do_arquivo;i++)
{
strcpy(nome do arquivo,"TTPT");
isto(i,temp,10);
strcat(nome do arquivo,temp);
strcat(nome_do_arquivo,extensão_do_arquivo);
remover(nome do arquivo);
}
saída(1);
retornar 0;
}
Comentários sobre a lógica e a codificação do programa:
Neste programa basicamente seguimos os dois passos seguintes para limpar o espaço não alocado do disco:
- Crie arquivos de dados temporários automaticamente: Primeiro, criamos arquivos temporários com nomes exclusivos e tendo alguns dados neles até que o volume do disco esteja cheio com esses arquivos de dados temporários. Ao fazer isso, toda a área de dados não alocada da unidade lógica é ocupada pelos dados dos arquivos temporários e todos os dados não alocados são sobrescritos.
Para fazer isso, escolhi os nomes dos arquivos temporários no formato TTPTxxxx.PTT, o que significa que os quatro primeiros caracteres dos arquivos temporários são TTPT e a extensão dos arquivos é .PTT. Isso é feito para fornecer aos arquivos temporários nomes de arquivo exclusivos.
Eu configurei o tamanho máximo do arquivo temporário único, equivalente a aproximadamente 11.718 setores de dados, mas você pode defini-lo de acordo com você. Eu escolhi o caractere de espaço “ ” (caractere ASCII 32) para preencher os dados em arquivos temporários. No entanto, caracteres aleatórios também podem ser usados em vez de espaço.
- Remover todos os arquivos temporários: Quando a unidade lógica estiver cheia com arquivos temporários, isso indica que toda a área de dados não alocada agora está sobrescrita. Agora, todos os arquivos temporários criados pelo programa são removidos automaticamente. E assim o espaço não alocado é eliminado.
Na codificação do programa, o array de caracteres filename armazena o nome do arquivo para gerar arquivos temporários automaticamente, com nomes diferentes.
A função write_to_temp(filename); preenche o arquivo temporário com até 11.718 setores (porque não há ocorrência de 10.000 setores no grupo especificado de gravação do buffer) de dados equivalentes com a ajuda do buffer de dados dbuf de 40.000 bytes. O buffer de dados é gravado 50 vezes por vez para acelerar a gravação.
Os arquivos temporários são criados até que o volume do disco fique cheio e ocorra um erro de criação de arquivo. A função remove_temp_file() remove todos os arquivos temporários criados pelo programa.
Dessa forma, todo o espaço não alocado é eliminado sem danificar os dados do volume do disco.
Programa de escrita para Destructive Data Wiper:
Programas destrutivos de limpeza de dados são aqueles que escrevem diretamente na superfície do disco. Esse tipo de programa de limpeza de dados funciona em um nível mais baixo do que o sistema de arquivos e o sistema operacional, o que significa que todos os dados e outras informações lógicas, incluindo SO, sistemas de arquivos, entrada de diretório e tudo o que está escrito no disco são apagados.
Esses programas de limpeza de dados limpam diretamente os setores da superfície do disco e apagam tudo o que está escrito nele. Como todos os dados do disco, incluindo o sistema operacional, são perdidos, esses programas são chamados de programas de limpeza de dados destrutivos.
Esses tipos de programas de limpeza são preferidos nesses casos, quando o usuário deseja sobrescrever tudo no disco, incluindo o sistema operacional e todos os dados do disco.
No entanto, há mais alguns benefícios desse tipo de programa de limpeza de dados. Como esses programas destrutivos de limpeza de dados funcionam completamente livres do SO e do sistema de arquivos e gravam diretamente na superfície do disco, eles são razoavelmente mais rápidos do que os limpadores de dados não destrutivos.
Além disso, se algum setor lógico defeituoso for criado no disco devido ao armazenamento ilegal de alguns dados aleatórios, esses setores lógicos defeituosos também serão completamente eliminados junto com os dados do disco.
A codificação para um programa de limpeza de dados destrutivo foi dada a seguir. O programa foi escrito para suportar discos de tamanho grande também. O programa limpa os dados do segundo disco rígido físico conectado ao computador.
///// Codificação para um programa destrutivo de limpeza de dados \\\\\
#incluir<stdio.h>
#include<dos.h>
/* Estrutura a ser usada pela função getdrivegeometry usando extensão INT 13H, número da função 0x48. */
geometria estrutural
{
unsigned int size ; /* (chamada) tamanho do Buffer */
unsigned int flags ; /* Sinalizadores de informação */
unsigned long cyl ; /* Número de cilindros físicos em
Dirigir */
cabeças longas não assinadas ;/* Número de cabeças físicas em
Dirigir */
unsigned long spt ; /* Número de setores físicos por
Acompanhar */
setores longos não assinados[2] ; /* Número total de
Setores em Drive */
unsigned int bps ; /* Bytes por setor */
} ;
/* Estrutura do formato do pacote de endereço de disco, a ser usado pela função writeabsolutesectors */
estrutura diskaddrpacket
{
char packetsize ; /* Tamanho do pacote,
geralmente 10H */
char reservado ; /* Reservado (0) */
int blockcount ; /* Número de blocos para
Transferir */
char far *bufferaddress ; /* endereço para transferência
Tampão */
unsigned long blocknumber[2] ; /* Iniciando Absoluto
Número do bloco */
} ;
///// Função para obter parâmetros de unidade \\\\\
unsigned long getdrivegeometry (unidade int)
{
união REGS i, o ;
estrutura SREGS s ;
geometria de estrutura g = { 26, 0, 0, 0, 0, 0, 0, 0 } ;
ihah = 0x48 ; /* Número da função 0x48 de INT 13H
Extensões */
ihdl = drive; /* Número da unidade */
ixsi = FP_OFF ( (void far*)&g ) ;
s.ds = FP_SEG ( (void far*)&g ) ;
/* Invoca o número de função especificado da extensão INT 13H com valores de registro de segmento */
int86x ( 0x13, &i, &o, &s ) ;
printf("\n Cabeça = %lu, Setores por Trilha = %lu, Cilindro =
%lu\n",
g.cabeças,g.spt,g.cil);
/* Se a função Geometry do get drive falhar, exibir mensagem de erro e sair */
se(g.spt==0)
{
printf("\n A função Obter geometria da unidade falha....");
printf("\n Extensões não suportadas, pressione qualquer tecla para
Saída...");
obter();
saída(1);
}
retornar *g.sectors; /* Retorna o número de
Setores em Drive */
}
vazio principal()
{
loop longo sem sinal=0, Setores_em_ HDD2=0;
unsigned char buffer[61440]; /* Buffer de dados de 61440
bytes Equivalente a
120 Setores */
sem sinal longo i=0;
escolha de char;
clrscr();
/* Se o número total de discos rígidos conectados for menor que dois, exibir mensagem de erro e sair. */
se(((char)peekb(0x0040, 0x0075))<2)
{
printf("\n\n Você deve ter pelo menos dois discos rígidos
Anexado ao seu computador para executar isto");
printf("\n Programa. Este programa foi desenvolvido
para limpar os dados do segundo disco rígido.");
printf("\n Pressione qualquer tecla para sair... ");
obter();
saída(1);
}
Setores_em_HDD2 = getdrivegeometry (0x81);
printf("Total de setores no segundo disco rígido =
%lu\n\n",
Setores_em_HDD2);
///// Primeiro confirme, depois prossiga \\\\\
printf("\n É um programa de limpeza de dados e escreve em
a Superfície do Disco,");
printf("\n Após executar este programa, os dados não podem
ser recuperado por qualquer Software,");
printf("\n Todos os dados no segundo disco rígido serão
perdido !!!");
printf("\n Pressione \'Y\' para continuar, senão qualquer tecla para
Saída... ");
escolha = getche();
switch(escolha)
{
caso 'y':
caso 'Y':
quebrar;
padrão:
saída(0);
}
gotoxy(10,15);cprintf("Inicializando, aguarde...");
para(i=0;i<61440;i++)
{
buffer[i]='\0';
}
gotoxi(10,15);cprintf(" ");
gotoxi(10,15);
printf("Atualmente limpando setor absoluto: ");
para(loop=0;loop<= Setores_em_HDD2;loop=loop+120)
{
escreversetoresabsolutos(0x81, loop, 120, buffer);
gotoxy(44,15); printf("%ld",loop);
se(kbhit())
{
saída(0);
}
///// Exibir mensagem quando concluído \\\\\
printf("\n\n A limpeza de dados foi concluída, todos os dados em
O segundo disco rígido agora é");
printf("\n Completamente apagado, pressione qualquer tecla para sair...");
obter();
}
//// Função para escrever setor(es) absoluto(s) \\\\
int writeabsolutesectors ( int drive, unsigned long sectornumber, int numofsectors, void *buffer )
{
união REGS i, o ;
estrutura SREGS s ;
estrutura diskaddrpacket pp;
pp.packetsize = 16 ; /* Tamanho do pacote = 10H */
pp.reserved = 0 ; /* Reservado = 0 */
pp.blockcount = numofsectors ;/* Número de setores para
ser escrito */
/* para buffer de dados */
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer));
pp.blocknumber[0] = sectornumber ; /* Número do setor
a ser escrito*/
pp.blocknumber[1] = 0 ; /* Número do bloco = 0 */
ihah = 0x43 ; /* Número da função */
ihal = 0x00 ; /* Escrever sinalizadores */
ihdl = drive ; /* Unidade física
número */
ixsi = FP_OFF ((void far*)&pp) ; /* ds:si para
Parâmetros do buffer */
s.ds = FP_SEG ( (void far*)&pp ) ; /* ds:dizer para
Parâmetros do buffer */
/* Invoca a função especificada de INT 13H com valores de registro de segmento */
int86x ( 0x13, &i, &o, &s ) ;
se (oxcflag==1)
retornar 0 ; //falha
outro
retornar 1 ; // sucesso
}
Comentários sobre codificação:
A geometria da estrutura é usada pela função getdrivegeometry usando a extensão INT 13H, número de função 0x48 para obter os vários parâmetros do disco.
A estrutura diskaddrpacket é para o formato de pacote de endereço de disco, a ser usado pela função writeabsolutesectors.
A função getdrivegeometry (int drive) é obter os parâmetros de unidade do disco especificado no número da unidade física drive. buffer [61440] é o buffer de dados de 61440 bytes, equivalente a 120 setores.
(char) peekb(0x0040, 0x0075) é usado para encontrar o número de discos rígidos conectados ao computador, armazenados no local de memória representado pelo segmento 0040H:offset 0075H. Se o número total de discos rígidos conectados for menor que dois, exiba uma mensagem de erro e saia.
A função writeabsolutesectors (0x81, loop, 120, buffer) é usada para gravar os dados do buffer de dados em 120 setores por vez, começando pelo número absoluto do setor especificado pelo loop.
Eu escolhi '\0' (caractere NULL, código ASCII 0) para escrever nos setores para sobrescrever os dados. No entanto, você pode usar caracteres aleatórios para sobrescrever os dados.
Para uma descrição detalhada das funções writeabsolutesectors e getdrivegeometry, consulte os capítulos fornecidos anteriormente neste livro.
Limpando a área de dados de um arquivo específico
Discutimos sobre os programas de limpeza de dados que limpam os dados do espaço não alocado do disco ou limpam o disco inteiro. Mas se o usuário estiver disposto a limpar os dados toda vez que ele os exclui, pode ser um processo demorado limpar todo o espaço não alocado do disco.
Precisamos desse tipo de programa de limpeza de dados para limpar a área de dados ocupada apenas por aquele arquivo em particular. Para fazer isso, obtemos ajuda das entradas do diretório FAT e Root, para encontrar a área de dados ocupada por aquele arquivo em particular
Mesmo no caso de disquete, se os dados não estiverem fragmentados, podemos fazer isso apenas com a ajuda das informações do diretório raiz. A tabela a seguir mostra as informações armazenadas por uma entrada de diretório raiz com 32 bytes, para qualquer arquivo:

Como vemos na tabela de conteúdo da entrada do diretório raiz, somos capazes de encontrar o cluster inicial e final dos arquivos. O primeiro Byte do nome do arquivo também pode conter algumas informações importantes sobre o arquivo. As informações fornecidas por este byte podem ser uma das fornecidas abaixo:

Vamos tentar essas informações para limpar os dados de qualquer arquivo armazenado em um disquete de 1,44 Mb, 3 ½ polegadas, com a ajuda das informações do diretório raiz. Supondo que os dados no disquete não estejam fragmentados, o programa fornecido a seguir limpa os dados do arquivo especificado de sua área de dados:
/* Programa para limpar a área de dados do arquivo especificado no disquete */
#incluir<stdio.h>
#include<dos.h>
///// Estrutura para ler 32 bytes de entrada de arquivo no diretório raiz \\\\\
estrutura raiz
{
unsigned char filename[8]; /* Nome do arquivo Entrada de
8 bytes */
unsigned char extension[3]; /* Extensão do arquivo de
3 bytes */
unsigned char attribute; /* Byte de atributo de arquivo */
unsigned char reservado[10]; /* Bytes reservados 10 */
unsigned int time; /* Tempo, 2 Bytes */
unsigned int data; /* Data, 2 Bytes */
unsigned int starting_cluster;/* Iniciando Cluster de Arquivo,
2 bytes */
unsigned long file_size; /* Tamanho do arquivo em bytes,
4 bytes */
};
/* Deve ser usado para ler todas as entradas do diretório raiz */
//struct entrada raiz[224];
/* Estrutura para ler todas as 16 entradas de arquivo em um setor do diretório raiz */
estrutura um_setor_raiz
{
estrutura entrada raiz[16];
};
struct um_setor_raiz um;
vazio principal()
{
int resultado, i, num_setores,j;
char wipe_buf[512]; /* Buffer de dados a ser usado para limpar
fora da área de dados do arquivo */
clrscr();
result= absread(0x00, 1, 19, &one); /* Ler setor absoluto
19 (Primeiro Setor do Diretório Raiz) */
se (resultado != 0)
{
perror("Erro na leitura do setor, pressione qualquer tecla para
Saída...");
obter();
saída(1);
}
/* Exibir informações dos arquivos após a leitura do diretório raiz */
printf("NÚMERO DO ARQUIVO. NOME DO ARQUIVO EXTENSÃO CLUSTER INICIAL
TAMANHO DO ARQUIVO \n\n");
para(i=1;i<16;i++)
{
printf("\n %5d %8.8s %3.3s %5u %10lu ",
i, one.entry[i].nomedoarquivo, one.entry[i].extensão,
um.entrada[i].cluster_inicial, um.entrada[i].tamanho_do_arquivo);
}
//// Obtenha a entrada do usuário para excluir o arquivo \\\\
printf("\n\n Digite o número do arquivo que deseja excluir e
Apagar completamente ");
scanf("%d", &i);
se(i<1 || i>15)
{
printf(" \"%d\" é uma opção inválida..., pressione qualquer
Chave para Sair...", i);
obter();
saída(1);
}
///// Primeiro confirme, depois continue \\\\\\
printf("\n Você está prestes a desaparecer,
O arquivo \"%.8s.%s\"",
one.entry[i].nomedoarquivo,
uma.entrada[i].extensão);
printf("\n Deseja continuar...(S/N) ");
alternar(obter())
{
caso 'y':
caso 'Y':
quebrar;
padrão:
saída(0);
}
///// Calcular o tamanho do arquivo em setores \\\\\
num_setores = um.entrada[i].tamanho_do_arquivo/512;
se((uma.entrada[i].tamanho_do_arquivo%512)>0)
{
num_setores = num_setores+1;
}
/* Buffer de dados de 512 bytes com 512 caracteres NULL */
para(j=0;j<512;j++)
{
wipe_buf[j] = '\0';
}
///// Setor inicial do arquivo \\\\\
j= uma.entrada[i].cluster_inicial+31;
/* Apagar a área de dados até que os setores do arquivo terminem */
entrada(j!=(one.entry[i].starting_cluster +
número_de_setores+31) )
{
se((abswrite(0x00, 1, j, &wipe_buf))!=0)
{
printf("\n Erro ao gravar em setores do disco");
pegar();
saída(0);
}
j++;
}
printf("\n\n Arquivo \"%.8s.%.3s\" Excluído !!!" ,
one.entry[i].nome_do_arquivo,
uma.entrada[i].extensão);
um.entrada[i].atributo = 0; /* Definir atributo de arquivo
para 0 */
uma.entrada[i].tempo = 0; /* Limpar informações de tempo
arquivo */
um.entrada[i].data = 0; /* Limpar informações de data
arquivo */
um.entrada[i].cluster_inicial = 0; /* Defina o cluster inicial como 0
*/
um.entrada[i].tamanho_do_arquivo = 0; /* Defina o tamanho do arquivo como 0 */
um.entrada[i].nomedoarquivo[0]=0xE5; /* Dê controle remoto
Status do arquivo em arquivo */
///// Grave as informações acima no diretório raiz \\\\\\
resultado = abswrite(0x00, 1, 19, &um);
se (resultado != 0)
{
perror("Erro ao ler o setor, pressione qualquer tecla para
Saída...");
pegar();
saída(1);
}
}
Comentários sobre a lógica e codificação do programa:
A estrutura root é usada para ler 32 bytes de uma entrada de arquivo no diretório raiz, e a estrutura one_root_sector lê todas as 16 entradas de arquivo em um setor do diretório raiz.
Se você quiser ler todos os setores das informações do diretório raiz, você deve considerá-lo como uma entrada struct root[224]; No entanto, escrevi um programa para analisar 16 registros de apenas um setor do diretório raiz.
O setor inicial do arquivo é calculado da seguinte forma:
j= um.registro[i].cluster_inicial+31;
Isso é feito porque a área de dados de um disquete de 1,44 MB e 3 ½ polegadas começa depois dos primeiros 32 setores do disco. E em um disquete com a capacidade especificada, um cluster corresponde a um setor.
A tabela a seguir mostra o mapa lógico de um disquete de 1,44 MB e 3½ polegadas:

O resultado do programa é exibido da seguinte forma:

Aqui excluímos e apagamos os dados do arquivo PARTBOOT.C. Quando vemos o conteúdo do disquete usando o comando DIR, o arquivo PARTBOOT.C não é mostrado lá. Quando o programa é executado, a entrada para o arquivo excluído é exibida da seguinte forma:

Aqui o símbolo "" (0xE5) significa que o arquivo foi excluído. (veja a tabela para o primeiro caractere do nome do arquivo).
Se você quiser escrever o mesmo programa para o disco rígido, também precisará usar FAT com diretório raiz para obter informações sobre a área de dados de qualquer arquivo.
Isso ocorre porque a taxa de fragmentação de dados em discos rígidos aumenta com o tempo, à medida que arquivos antigos são excluídos e novos são criados. Então não há necessidade de todos os clusters de dados de qualquer arquivo no disco permanecerem um após o outro de forma contígua na área de dados. Ao acessar o FAT, você pode acessar todos esses clusters.