Capítulo – 11
Criando cópias de segurança
Por que você precisa de backups?
"É sempre melhor prevenir do que remediar." O backup também é uma parte importante da prevenção de desastres de dados, o que pode nos ajudar a superar falhas de disco ou qualquer outro tipo de perda de dados. Neste capítulo, discutiremos como podemos recuperar dados mesmo após algumas falhas graves de disco, apenas usando backups feitos anteriormente.
A recuperação usando backups salvos anteriormente é quase sempre de até 100%; no entanto, em alguns casos específicos, diferentes tipos de falhas de disco podem causar diferenças nos resultados da recuperação.
Restaurar dados usando backups é um processo bastante simples, rápido e confiável que pode dar os melhores resultados, enquanto restaurar dados sem backups é complexo, confuso e pode levar muito tempo e, mesmo assim, em muitos casos, temos medo de não obter 100% dos dados.
Quando e o que reservar
Há várias áreas diferentes no disco que precisam ser copiadas uma vez ou em intervalos diferentes. A tabela a seguir fornece uma visão geral das etapas envolvidas em um backup completo e ajuda você a descobrir quando e o que fazer backup:
O que precisa ser reservado |
Quando o backup é necessário? |
Cópia de segurança MBR |
Depois do FDISK. O MBR é criado pelo comando FDISK DOS. Você pode fazer backup do MBR após o FDISK, porém mesmo após FORMATAÇÃO das partições criadas pelo FDISK, o MBR permanece inalterado. |
Cópia de segurança DBR |
Após a formatação, crie um backup DBR para cada disco lógico. |
Faça backup de entradas e diretórios FAT. |
As entradas de FAT e diretório mudam toda vez que você cria ou exclui arquivos ou diretórios. Portanto, é recomendável fazer uma cópia de segurança diariamente. |
Fazer backup dos dados do usuário |
Deve ser feito regularmente. Esse tipo de backup resulta na criação de uma imagem de disco. No entanto, isso consome tempo, mas a maioria das empresas que têm dados muito confidenciais em seus discos gostam de gastar seu tempo criando uma imagem de disco porque dessa forma podem fazer backup de todas as informações descritas acima. |
Além disso, você deve criar um disco de inicialização de emergência para o sistema. Caso ocorra algum acidente com os dados do seu disco rígido, você poderá inicializar o sistema usando este disquete e analisar a unidade em busca de erros.
Fazendo backup do MBR (Master Boot Record) e seu uso
O registro mestre de inicialização (MBR), ou às vezes chamado de tabela de partição mestre (MPT), contém um pequeno programa para carregar e executar a partição ativa (ou inicializável) do disco rígido. O registro mestre de inicialização contém informações sobre todas as quatro partições primárias.
Para uma discussão detalhada sobre MBR, consulte o capítulo "Uma abordagem lógica para discos e sistemas operacionais", discutido anteriormente neste livro.
O MBR está localizado no setor absoluto 0 ou podemos dizer no cilindro 0, cabeça 0 e setor 1. Ele é criado no disco rígido executando o comando FDISK.EXE do DOS.
Por que fazer um backup do MBR:
O MBR permite que o setor de inicialização da partição ativa obtenha controle quando o sistema inicia.
Após o autoteste de inicialização (POST), o BIOS carrega o MBR (Master Boot Record) do disco rígido para a memória e o executa. Primeiro, o MBR verifica se há uma partição ativa no disco rígido, depois carrega o registro de inicialização do DOS (DBR) na memória e passa o controle para o código de inicialização do sistema operacional. Em seguida, o código do registro de inicialização do sistema operacional carrega o restante do sistema operacional na memória.
Portanto, podemos dizer que se o MBR do disco estiver danificado, o disco rígido estará praticamente morto e o sistema ficará completamente incapaz de inicializar ou executar o sistema operacional. Nesse estado, todos os dados armazenados no disco rígido ficam inacessíveis. Normalmente, as mensagens de erro são exibidas da seguinte forma:
"Tabela de partição inválida" "Erro ao carregar o sistema operacional" "Sistema operacional ausente"
O que pode ser restaurado usando um backup MBR?
Fazer backup do MBR pode ajudar você a se livrar das mensagens de erro acima. Usando o backup, você pode corrigir os seguintes problemas:
- Erro ao carregar o sistema operacional devido a um IPL (carregador de programa inicial) corrompido
- Partição(ões) primária(s) perdida(s)
- Informações de partição corrompidas
- Número mágico errado
Escrevendo um programa para criar um backup MBR:
/* Programa para criar backup MBR */
#incluir <bios.h>
#incluir <stdio.h>
int principal(vazio)
{
estrutura diskinfo_t dinfo; /* Estrutura para armazenamento
informações de parâmetros do disco */
resultado int;
número de inteiros=0;
char nomedoarquivo[80]; /* Salva o nome do arquivo fornecido
Usuário */
static char dbuf[512]; /* Buffer de dados de 512 bytes */
ARQUIVO *fp;
dinfo.drive = 0x80; /* número da unidade para o primeiro disco rígido
Disco */
dinfo.head = 0; /* número da cabeça do disco */
dinfo.track = 0; /* número da trilha */
dinfo.sector = 1; /* número do setor */
dinfo.nsectors = 1; /* contagem de setores */
dinfo.buffer = dbuf; /* buffer de dados */
printf("\n Digite o nome do arquivo e o caminho para armazenar o
Backup do MBR \n ");
obtém(nome do arquivo);
// Abra o arquivo para armazenar o backup do MBR \\
if((fp=fopen(nome do arquivo,"wb"))==NULL)
{
printf("Não foi possível criar o arquivo, pressione qualquer tecla para
Saída...");
obter();
saída(0);
}
printf("Tentando ler do disco rígido:\n");
//// Leia o setor de disco especificado \\\\
resultado = _bios_disk(_DISK_READ, &dinfo);
se ((resultado & 0xff00) == 0)
{
printf("Disco lido da unidade de disco rígido:
bem-sucedido.\n");
/// Grave 512 bytes de MBR no arquivo \\\\
enquanto(contagem<512)
{
fprintf(fp,"%c",dbuf[contagem] & 0xff );
contar++;
}
fclose(fp);
}
outro
printf("Não é possível ler a unidade de disco rígido, status = 0x%02x\n", resultado);
retornar 0;
}
Comentários sobre a codificação do programa:
Na codificação do programa fornecida anteriormente, basicamente estamos procedendo para executar as seguintes tarefas passo a passo:
- dinfo aponta para a estrutura diskinfo_t que contém as informações dos parâmetros necessários para a operação realizada pela função _bios_disk.
- Como queremos ler o primeiro setor do disco, a localização do setor será a seguinte:
Parâmetro |
O que isso significa |
dinfo.drive = 0x80 |
Indica a unidade física 80H que é a primeira unidade de disco rígido. |
dinfo.cabeça = 0 |
Aponta para a cabeça número 0 |
dinfo.track = 0 |
Ele aponta para a trilha 0 |
dinfo.setor = 1 |
Primeiro setor do disquete que é o setor 1 |
dinfo.setor = 1 |
>Número de setores a serem considerados para operação de leitura = 1 |
dinfo.buffer = dbuf |
Buffer de dados para a operação |
- Abra um fluxo de arquivo de nome de arquivo e caminho fornecidos pelo usuário para armazenar o backup do MBR de exatos 512 bytes. O nome do arquivo e o caminho são armazenados no array de caracteres filename.
- _bios_disk(_DISK_READ, &dinfo) lê o primeiro setor do disco rígido (80H), especificado por dinfo.
- O status retornado é armazenado no resultado que é usado para exibir a mensagem de operação bem-sucedida ou para exibir uma mensagem de erro na tela caso ocorra algum erro.
Programa para restaurar o MBR do backup:
Se o MBR estiver corrompido de alguma forma, o programa fornecido a seguir ajuda a restaurar o MBR.
Deve-se sempre ter em mente que o uso ilegal ou o uso por falta de conhecimento deste programa pode destruir suas informações de dados no disco rígido e pode tornar todos os dados inacessíveis. Você deve ter certeza do que vai fazer. Caso contrário, você pode complicar ainda mais o problema.
Programa para restaurar o MBR do backup:
A codificação do programa é a seguinte:
/* Programa para restaurar o backup do MBR a partir do arquivo de backup */
#incluir <bios.h>
#incluir <stdio.h>
int principal(vazio)
{
estrutura diskinfo_t dinfo;
int resultado;
int contagem=0;
char filename[80]; /* Armazena o nome do arquivo fornecido
por Usuário */
static char dbuf[512]; /* Buffer de dados de 512 bytes
*/
ARQUIVO *fp;
/* Obter a entrada do usuário para o caminho do arquivo de backup MBR */
printf("\n Digite o nome do arquivo e o caminho do arquivo de backup de
MBR \n ");
obtém(nome do arquivo);
if((fp=fopen(nome do arquivo,"rb"))==NULL)
{
printf("Não foi possível abrir o arquivo de backup, pressione qualquer tecla
para sair...");
obter();
saída(1);
}
/* Os dados MBR devem ter exatamente 512 bytes */
enquanto(contagem<512)
{
fscanf(fp,"%c",&dbuf[contagem]);
contar++;
}
fclose(fp);
printf("Tentando gravar no disco rígido:\n");
dinfo.drive = 0x80; /* número da unidade para o primeiro
Disco Rígido */
dinfo.head = 0; /* número da cabeça do disco */
dinfo.track = 0; /* número da trilha */
dinfo.sector = 1; /* número do setor */
dinfo.nsectors = 1; /* contagem de setores */
dinfo.buffer = dbuf; /* buffer de dados */
resultado = _bios_disk(_DISK_WRITE, &dinfo);
se ((resultado & 0xff00) == 0)
{
printf("Restaurando o backup do MBR para o disco
Setor: bem-sucedido.\n");
}
outro
printf("Não é possível gravar na unidade de disco rígido, status =
0x%02x\n", resultado);
retornar 0;
}
Comentários sobre a codificação do programa:
Na codificação do programa fornecida acima, basicamente estamos procedendo para executar as seguintes tarefas passo a passo:
- dinfo aponta para a estrutura diskinfo_t que contém as informações dos parâmetros necessários para a operação realizada pela função _bios_disk.
- Como queremos escrever no primeiro setor do disco, a localização do setor será a seguinte:
Parâmetro |
O que isso significa |
dinfo.drive = 0x80 |
Indica a unidade física 80H que é a primeira unidade de disco rígido. |
dinfo.cabeça = 0 |
Aponta para a cabeça número 0 |
dinfo.track = 0 |
Ele aponta para a trilha 0 |
dinfo.setor = 1 |
Primeiro setor do disquete que é o setor 1 |
dinfo.setor = 1 |
Número de setores a serem considerados para operação de leitura = 1 |
dinfo.buffer = dbuf |
Buffer de dados para a operação |
- O nome do arquivo e o caminho do Backup do MBR, fornecidos pelo usuário, são armazenados no array de caracteres filename. Deve-se ter em mente que as informações do MBR devem ter Exatos 512 bytes.
- _bios_disk(_DISK_WRITE, &dinfo) grava os dados no primeiro setor do disco rígido (80H), especificado por dinfo.
- O status retornado é armazenado no resultado que é usado para exibir a mensagem de operação bem-sucedida ou para exibir uma mensagem de erro na tela caso ocorra algum erro.
Backup do DBR (DOS Boot Record) e sua utilização
Depois da tabela de partição, o DOS Boot Record (DBR), ou às vezes chamado de DOS Boot Sector, é a segunda informação mais importante do seu disco rígido.
Para um estudo detalhado sobre DBR, consulte o capítulo “ Abordagem lógica para discos e sistemas operacionais ”, discutido anteriormente neste livro.
O primeiro setor lógico de cada partição DOS conterá um DOS Boot Record (DBR) ou DOS Boot Sector. O trabalho do DBR é carregar o sistema operacional do disco rígido para a memória principal do computador e dar o controle do sistema ao programa carregado.
O DOS Boot Record (DBR) para a primeira partição em um disco rígido geralmente é encontrado no Setor Absoluto 63 (o 64º setor na unidade de disco) ou no formato CHS, podemos dizer C–H–S = 0–1–1 para a maioria das unidades.
No entanto, esse local pode variar dependendo do SPT (Sectors per Track) do Drive. Por exemplo, em um drive antigo de 245 MB com apenas 31 SPT, o Boot Record estava localizado no 32º setor (Absolute Sector 31).
O DBR é criado pelo comando FORMAT do DOS, após o particionamento ser feito usando o comando FDISK. O setor no qual o DBR reside se torna o setor lógico 1 daquela partição específica para o DOS. O número do setor usado pelo DOS começa a partir do setor físico no qual o DBR está localizado.
O DBR contém um pequeno programa que é executado pelo programa executável Master Boot Record (MBR). Todas as partições DOS contêm o código do programa para inicializar a máquina, ou seja, carregar o sistema operacional, mas somente essa partição recebe o controle do Master Boot Record, que é especificado como partição ativa, na entrada da tabela de partições.
Por que fazer backup do DBR:
O DBR contém algumas informações importantes sobre a geometria do disco. Essas informações estão localizadas no primeiro setor de cada partição, como:
- Código de salto + NOP
- Nome e versão do OEM
- Bytes por setor
- Setores por cluster
- Setores Reservados
- Número de cópias do FAT
- Entradas máximas do diretório raiz (mas não disponíveis para FAT32)
- Número de setores na partição menor que 32 MB (portanto, não disponível para FAT32)
- Descritor de mídia (F8H para discos rígidos)
- Setores por FAT (em sistemas FAT mais antigos e não disponível para FAT32)
- Setores por trilha
- Número de cabeças
- Número de setores ocultos na partição
- Número de setores na partição
- Número de setores por FAT
- Sinalizadores do descritor de informações FAT
- Versão da unidade FAT32
- Número do cluster do início do diretório raiz
- Número do setor do setor de informações do sistema de arquivos
- Número do setor do setor de inicialização de backup
- Reservado
- Número de partição da unidade lógica
- Assinatura Estendida (29H)
- Número de série da partição
- Nome do volume da partição
- Nome FAT
- Código executável
- Marcador executável ou número mágico (AAH 55H)
Geralmente, as seguintes mensagens de erro são exibidas na tela:
“Falha na inicialização do disco”
“Disco sem sistema ou erro de disco”
“Disco de sistema inválido ou erro de E/S de disco”
“Substitua o disco e pressione qualquer tecla…”
O que pode ser recuperado com o Backup do DBR?
O backup do DBR pode ajudar você a se livrar das mensagens de erro acima. Essas mensagens de erro na tela esperam que o usuário coloque um disco inicializável com os programas mencionados acima na unidade de disquete e pressione uma tecla.
A unidade deve ser acessível se você inicializar o sistema a partir do disquete ou CD inicializável. Embora o disco rígido não seja inicializável, geralmente isso não deve afetar o acesso aos dados da unidade de disco. Após inicializar o sistema com o disco inicializável, você pode acessar os dados.
Restaurando o backup do DBR você pode superar os problemas gerados, conforme mencionado acima.
Programas para fazer e restaurar backups do DBR:
Os programas para fazer backups de DBRs e restaurá-los são quase semelhantes aos programas de backup e restauração de MBR.
Por exemplo, se você for escrever programas para fazer backup do DBR da primeira unidade lógica do disco e restaurá-lo, os parâmetros especificados pela estrutura dinfo serão alterados da seguinte forma:
Parâmetro |
O que isso significa |
dinfo.drive = 0x80 |
Indica a unidade física 80H que é a primeira unidade de disco rígido> |
dinfo.cabeça = 1 |
Aponta para a cabeça número 1 |
dinfo.track = 0 |
Ele aponta para a trilha 0 |
dinfo.setor = 1 |
Primeiro setor do disquete que é o setor 1 |
dinfo.setor = 1 |
Número de setores a serem considerados para operação de leitura = 1 |
dinfo.buffer = dbuf |
Buffer de dados para a operação |
Aqui vemos que apenas a localização do setor para leitura/gravação é alterada. Aqui o CHS é dado como 0-1-1, pois o DBR do primeiro drive lógico é armazenado aqui.
Imagem de disco completa
Esse tipo de backup está se tornando cada vez mais popular hoje em dia e é mais preferido por organizações que têm dados muito sensíveis em seus sistemas. Essas pessoas não podem correr nenhum risco de perder nem um único por cento de dados.
Essas organizações fazem seus backups como uma imagem de disco inteira regularmente. Embora demore um pouco, mas dá a você a certeza de que não perderá nada. Devido à sua crescente popularidade, os programadores têm tentado o melhor para tornar o software de imagem de disco cada vez mais rápido para minimizar o período de tempo gasto pelo processo de imagem.
A criação de imagens de disco é uma boa ideia porque, gastando apenas algumas dezenas de minutos, você pode ter a tranquilidade de ter um backup de tudo no seu bolso. Todos os fatores como MBR, BDR, FATs, diretórios raiz são copiados para o disco de destino como ele está.
O que precisamos para a criação de imagens de disco é um disco rígido de destino Idêntico (ou quase Idêntico) ao nosso disco rígido de origem, no qual temos nossos dados valiosos. Uma coisa é sempre mantida em mente: o disco de destino não deve ser menor que o disco de origem.
Depois de tirar a imagem completa, se você inicializar o sistema com o disco de destino, no qual tirou a imagem do disco, geralmente você obterá todos os dados como estão.
Escrevendo o programa para imagem completa do disco
O programa para criação de imagens de disco foi dado a seguir. O programa usa as extensões INT 13H, portanto, ele pode suportar discos grandes também.
O programa cria a imagem do primeiro disco rígido físico (0x80) para o segundo disco rígido físico (0x81), portanto, antes de criar a imagem de backup, você deve ter em mente que todos os dados no disco de destino (0x81) serão substituídos pelos dados do disco de origem (0x80) no padrão setor por setor.
A codificação do programa foi dada a seguir:
/* Programa para fazer a imagem do primeiro disco rígido (0x80) para o segundo disco rígido (0x81) */
#incluir<stdio.h>
#include<dos.h>
#incluir<conio.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 cil ; /* Número de Física
Cilindros em movimento */
cabeças longas não assinadas ;/* Número de Física
Cabeças em movimento */
unsigned long spt ; /* Número de Física
Setores por trilha */
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 pelas funções, readabsolutesectors e writeabsolutesectors */
estrutura diskaddrpacket
{
char packetsize ; /* Tamanho do pacote, geralmente 10H */
char reservado ; /* Reservado (0) */
int blockcount ; /* Número de blocos a 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 Veja os Comentários
Abaixo */
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);
}
return *g.sectors; /* Retorna o número de setores
na unidade */
}
////// Início do Main \\\\\\
vazio principal()
{
loop longo sem sinal=0, Setores_no_HDD1=0, Setores_no_HDD2=0;
unsigned char buffer[61440]; /* Buffer de dados de 61440
Bytes para ler/escrever 120 setores de 512 bytes por vez para economizar tempo. */
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. Pressione qualquer tecla para sair... ");
obter();
saída(1);
}
/// Obter parâmetros do primeiro disco rígido (0x80) \\\
Setores_em_HDD1 = getdrivegeometry (0x80);
printf("Total de setores no primeiro disco rígido = %lu\n\n",
Setores_em_HDD1);
/// Obter parâmetros do segundo disco Hsrd (0x81) \\\
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 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);
}
/* O destino não deve ser menor que a origem */
se(Setores_no_HDD2<Setores_no_HDD1)
{
printf("\n\n O disco de destino não deve ser menor
do que o Disco de Origem");
printf("\n Pressione qualquer tecla para sair...");
obter();
saída(0);
}
/* Se tudo estiver ok, copie todos os setores do disco de origem para o disco rígido de destino */
gotoxy(10,15);printf("Copiando Setor Absoluto: ");
para(loop=0;loop< =Setores_em_HDD1;loop=loop+120)
{
leiasetoresabsolutos ( 0x80, loop, 120, buffer );
escreversetoresabsolutos(0x81, loop, 120, buffer);
gotoxy(36,15); printf("%ld",loop);
se(kbhit())
{
saída(0);
}
}
//// Mostrar a mensagem de conclusão \\\
printf("\n\n A criação de imagens de disco foi concluída. Pressione qualquer tecla
Para sair...");
obter();
}
//// Fim do principal
Comentários sobre codificação:
Na codificação do programa fornecido anteriormente, para geração de imagens de disco, estamos procedendo executando as seguintes tarefas:
- A estrutura, geometria é usada pela função getdrivegeometry usando a extensão INT 13H, número da função 0x48. Para uma descrição detalhada sobre as extensões INT 13H, consulte o capítulo “Manipulando discos rígidos grandes”, discutido anteriormente neste livro.
Os tipos de dados que representam vários parâmetros do disco têm os seguintes significados:
Tipo de dados |
Tamanho em bytes |
Descrição |
tamanho int não assinado |
2 bytes |
Tamanho do Buffer |
sinalizadores int não assinados |
2 bytes |
Bandeiras de informação |
cilindro longo sem sinal |
4 bytes |
Número de cilindros físicos na unidade |
cabeças longas não assinadas |
4 bytes |
Número de cabeças físicas na unidade |
ponto longo não assinado |
4 bytes |
Número de setores físicos por trilha |
setores longos não assinados [2] |
8 bytes |
Número total de setores na unidade |
int sem sinal bps |
2 bytes |
Bytes por setor |
- A estrutura diskaddrpacket é usada pelas funções readabsolutesectors e writeabsolutesectors. O formato do pacote de endereço de disco foi dado na tabela a seguir:
Tipo de dados |
Tamanho em bytes |
Descrição |
tamanho do pacote char |
1 Byte |
Tamanho do pacote, geralmente 10H |
char reservado |
1 Byte |
Reservado (0) |
contagem de blocos int |
2 bytes |
Número de blocos a transferir |
char far *endereço do buffer |
4 bytes |
endereço para buffer de transferência |
bloco longo sem sinal [2] |
4 bytes |
Número de bloco absoluto inicial |
- A função getdrivegeometry é usada para obter os parâmetros do Drive especificado. A função getdrivegeometry usa a função número 0x48 de INT 13H Extensions.
O significado dos parâmetros foi descrito na tabela a seguir:
Parâmetro |
O que isso significa |
ihah = 0x48 |
Número de função 0x48 das extensões INT 13H |
ihdl = dirigir |
Número da unidade |
ixsi = FP_OFF ( (void far*)&g ) |
endereço ds:si para buffer para parâmetros de unidade, conforme discutido anteriormente |
s.ds = FP_SEG ( (void far*)&g ) |
endereço ds:si para buffer para parâmetros de unidade, conforme discutido anteriormente |
A função int86x(0x13, &i, &o, &s) invoca a interrupção 13H com o registrador de segmento Values. A função getdrivegeometry retorna o número total na unidade.
- Na função main(), (char)peekb(0x0040, 0x0075); (a função peekb é definida em DOS.H) retorna o número de discos rígidos conectados ao sistema.
O número de discos rígidos conectados ao sistema é representado pelo byte armazenado no local de memória 0040H:0075H (Segmento 0040H: Offset 0075H). Se o número de discos rígidos conectados ao sistema for menor que dois, o programa mostra a mensagem de erro e sai.
Sectors_in_HDD1 = getdrivegeometry (0x80); obtém os parâmetros do primeiro disco rígido (0x80) e retorna o número total de setores no primeiro disco rígido.
Da mesma forma, Sectors_in_HDD2 = getdrivegeometry (0x81); obtém os parâmetros do segundo disco rígido (0x81) e retorna o número total de setores no segundo disco rígido.
Após a confirmação do usuário para continuar com a criação de imagens, primeiro verifique a condição de que o tamanho do disco rígido de origem não deve ser maior que o tamanho do disco rígido de destino. Se o destino for menor, exiba a mensagem de erro e saia.
Se tudo estiver indo bem, copie os setores do disco de origem para o disco de destino. Aqui estamos lendo e gravando 61440 bytes (120 setores com cada um dos 512 bytes) por vez para tornar o processo de criação de imagens mais rápido.
Se você quiser usar mais setores de uma vez, mesmo além do limite de 64K, você pode fazer isso usando “huge Pointer” em modelo de memória grande. O Exemplo de Especificação é o seguinte:
char matriz enorme[100000L];
- A função readabsolutesectors (0x80, loop, 120, buffer); lê os 120 setores do primeiro disco rígido (0x80), começando pelo número do setor especificado pelo loop unsigned long integer e armazena os dados no buffer de dados.
- A função writeabsolutesectors (0x81, loop, 120, buffer) grava os dados do buffer de dados em 120 setores do segundo disco rígido (0x81), começando pelo número do setor especificado pelo loop de inteiro longo sem sinal.
A codificação das funções readabsolutesectors ( ) e writeabsolutesectors ( ) foi dada a seguir:
//// Função para ler setor(es) absoluto(s) \\\\
int readabsolutesectors ( int unidade,
número de setor longo sem sinal,
int número de setores,
vazio *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
ler */
/* 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
ler */
pp.blocknumber[1] = 0 ; /* Número do bloco */
ihah = 0x42 ; /* Número da função*/
ihdl = drive ; /* Número da unidade física */
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 */
}
//// Função para escrever setor(es) absoluto(s) \\\\
int writeabsolutesectors ( int unidade,
número de setor longo sem sinal,
int número de setores,
vazio *buffer )
{
sindicato REGS i, o ;
estrutura SREGS s;
estrutura diskaddrpacket pp;
pp.tamanho do pacote = 16 ; /* Tamanho do pacote = 10H */
pp.reservado = 0 ; /* Reservado = 0 */
pp.blockcount = numofsectors ; /* Número de setores
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
será escrito */
pp.númerodebloco[1] = 0 ; /* Número do bloco = 0 */
ihah = 0x43 ; /* Número da função */
ihal = 0x00 ; /* Entrada de sinalizadores, veja
comentários */
ihdl = unidade; /* Número do disco físico*/
/* ds:si para parâmetros de buffer */
ixsi = FP_OFF ( (void far*)&pp ) ;
/* ds:si para parâmetros de buffer */
s.ds = FP_SEG ( (void far*)&pp ) ;
/* Chama a função INT 13H especificada com os valores do registrador de segmento */
int86x ( 0x13, &i, &o, &s ) ;
se (oxcflag == 1)
retornar 0 ; /* falha */
mais
retornar 1 ; /* sucesso */
}
Comentários de codificação:
Os parâmetros usados por ambas as funções têm os seguintes significados:
Parâmetro |
Tamanho em bytes |
Descrição |
pp.tamanho do pacote = 16 ; |
1 byte |
Tamanho do pacote = 10H |
pp.reservado = 0 ; |
1 byte |
Reservado = 0 |
pp.blockcount = numofsectors ; |
2 bytes |
Número de setores para ler |
pp.bufferaddress = (char far*) MK_FP ( FP_SEG((void far*)buffer), FP_OFF((void far*)buffer)); |
----- |
para buffer de dados ou buffer de transmissão |
pp.blocknumber[0] = número_do_setor; |
4 bytes |
Número do setor para leitura/gravação (geralmente precisamos apenas deste). Somente separadamente. Pode suportar até 2,1 terabytes. |
pp.número_de_bloco[1] = 0 ; |
4 bytes |
Número do bloco. Use-o se estiver acessando um disco maior que 2,1 terabytes. |
ihah = 0x42; ou ihah = 0x43 ; |
2 bytes |
Função Número de extensões INT 13H |
ihal = 0x00; |
1 byte |
Os sinalizadores de gravação são usados somente na função de gravação; 00H, 01H são usados para gravação sem verificação e 02H é usado para gravação com verificação. |
ihdl = unidade; |
2 bytes |
Número do disco físico |
ixsi = FP_OFF ( (void far*)&pp ) ; |
------ |
ds:si para parâmetros de buffer |
s.ds = FP_SEG ( (void far*)&pp ) ; |
------ |
ds:si para parâmetros de buffer |
int86x ( 0x13, &i, &o, &s ) ; |
------ |
Chame a função INT 13H especificada com os valores do registrador de segmento |