Como realmente identificar arquivos por endereços de "Segmento de registro de arquivo", conforme relatado por chkdsk
?
Houve um blecaute e os sistemas de arquivos das minhas unidades foram corrompidos, o hardware e os arquivos do sistema operacional estão bem, fiz verificações completas, mas fiz uma coisa estúpida ao executar chkdsk /f X:
primeiro e ele processou 107.855 arquivos de dados.
Consegui acessar a pasta System Volume Information e encontrar os logs dentro da pasta Chkdsk. O log tem 11,2 MiB e eu o carreguei no Google Drive .
Estou tentando copiar programaticamente o arquivo de log e identificar todos os arquivos afetados por ele. É extremamente fácil para mim escrever o programa, sei o que estou fazendo.
Quero verificar os arquivos afetados e excluir os arquivos corrompidos e, possivelmente, baixá-los novamente. A unidade contém Tebibytes de download de jogos piratas e Tebibytes de dados que criei. Não quero fazer recuperação de dados e tal.
O problema é que a terminologia usada por chkdsk
é inconsistente e confusa:
Checking file system on D:
The type of the file system is NTFS.
Chkdsk cannot run because the volume is in use by another
process. Chkdsk may run if this volume is dismounted first.
ALL OPENED HANDLES TO THIS VOLUME WOULD THEN BE INVALID.
Would you like to force a dismount on this volume? (Y/N) Volume dismounted. All opened handles to this volume are now invalid.
Volume label is Tremillia.
Stage 1: Examining basic file system structure ...
Attribute record of type 0x80 and instance tag 0x4 is cross linked
starting at 0x9383fc2 for possibly 0xfe clusters.
Some clusters occupied by attribute of type 0x80 and instance tag 0x4
in file 0x46c4 is already in use.
Deleting corrupt attribute record (0x80, "")
from file record segment 0x46C4.
Attribute record of type 0x80 and instance tag 0x4 is cross linked
starting at 0x93840c0 for possibly 0x95 clusters.
Some clusters occupied by attribute of type 0x80 and instance tag 0x4
in file 0x46c5 is already in use.
Deleting corrupt attribute record (0x80, "")
from file record segment 0x46C5.
Attribute record of type 0x80 and instance tag 0x4 is cross linked
starting at 0x9384489 for possibly 0xc5 clusters.
Some clusters occupied by attribute of type 0x80 and instance tag 0x4
in file 0x4706 is already in use.
Deleting corrupt attribute record (0x80, "")
from file record segment 0x4706.
Attribute record of type 0x80 and instance tag 0x4 is cross linked
starting at 0x938454e for possibly 0x90 clusters.
Some clusters occupied by attribute of type 0x80 and instance tag 0x4
in file 0x470b is already in use.
Deleting corrupt attribute record (0x80, "")
from file record segment 0x470B.
Attribute record of type 0x80 and instance tag 0x3 is cross linked
starting at 0x93799ea for possibly 0x40 clusters.
Some clusters occupied by attribute of type 0x80 and instance tag 0x3
in file 0x4f3f is already in use.
...
Existem 3 tipos de endereços hexadecimais, denominados "segmento de registro de arquivo", "arquivo" e "cluster". Imediatamente você pode ver que o endereço do cluster começa muito grande e é muito maior que os endereços de "arquivo" e "segmento de registro de arquivo".
E então você pode ver que os endereços de "arquivo" e "segmento de registro de arquivo" são de intervalo semelhante e os mesmos endereços são chamados de "arquivo" e "segmento de registro de arquivo". Portanto, é evidente que “arquivo” e “segmento de registro de arquivo” são a mesma coisa.
Tentei pesquisar no Google como identificar arquivo por segmento de registro de arquivo e a maioria dos resultados são completamente irrelevantes. Os principais resultados são tutoriais inúteis feitos por empresas de software questionáveis, projetadas para vender seus produtos. Coisas como "como consertar", "o que fazer quando o segmento do registro do arquivo está ilegível"...
O Google é completamente inútil e os resultados não são o que eu quero, quero identificar os arquivos pelo número de "segmento de registro de arquivo".
A única coisa relevante que encontrei foi este post .
Bem, finalmente tive a oportunidade de experimentar alguns utilitários NTFS baseados em Linux. Não tenho certeza se eles são de ntfs-3g, ntfsprogs ou ntfsutils, mas qualquer pessoa que tenha uma distribuição Linux favorita deve ser capaz de iniciá-la e obter as informações necessárias com bastante facilidade. Os números são números de inode e dois comandos foram muito úteis. Este forneceu o que eu precisava:
ntfscluster -I <inode # / segmento de registro de arquivo #>
Incluía o caminho completo para o arquivo em questão e muito poucas outras informações. >Este comando forneceu muitas informações que eu não precisava:
ntfsinfo -i <inode # / segmento de registro de arquivo #>
Ele não forneceu o caminho, mas forneceu o número do inode do diretório pai, para que você pudesse fazer engenharia reversa do caminho usando esse comando repetidamente.
NTFSCluster é um utilitário Linux, a pesquisa ntfscluster windows
mostra resultados sobre o sistema de arquivos NTFS e seu tamanho de cluster, com a mensagem "Você quis dizer: janelas de cluster NTFS". A única coisa relevante é o terceiro resultado: NtfsProgs para Windows - GnuWin32 - SourceForge , esse resultado é um programa antigo de 2004 e está faltando libintl3.dll e libiconv2.dll no download. Depois de colar os .dlls na pasta não funciona:
PS C:\Users\Xeni> C:\Users\Xeni\Downloads\ntfsprogs-1.9.0-bin\bin\ntfscluster.exe -I 154681282 D:
Failed to set locale, using default '(null)'.
win32_io.c(199): ntfs_device_win32_open The handle is invalid.
ioctl failed
Couldn't mount device 'D:': Invalid argument
O NTFSInfo da SysInternals não parece fornecer a funcionalidade para identificar arquivo por segmento de registro de arquivo .
Depois de procurar um substituto descobri nfi.exe
que é ainda mais antigo, é de 1999! Funciona:
PS C:\Users\Xeni> nfi.exe D: 0x937950
NTFS File Sector Information Utility.
Copyright (C) Microsoft Corporation 1999. All rights reserved.
***Logical sector 9664848 (0x937950) on drive D is in file number 312188.
\Games\SPACEE~1\data\textures\galaxies\GALAXI~1.PAK
$DATA (nonresident)
logical sectors 8738944-10045631 (0x855880-0x9948bf)
Mas leva o número do setor lógico como argumento em vez de FILE RECORD SEGMENT :
PS C:\Users\Xeni> nfi.exe /?
NTFS File Sector Information Utility.
Copyright (C) Microsoft Corporation 1999. All rights reserved.
Dumps information about an NTFS volume, and optionally determines
which volume and file contains a particular sector.
Usage: D:\CliExec\nfi.exe drive-letter [logical-sector-number]
Drive-letter can be a single character or a character followed
by a colon (i.e., C or C: are acceptable).
Logical-sector-number is a decimal or 0x-prefixed hex
number, specifying a sector number relative to the volume
whose drive letter is given by drive-letter. If not
specified, then information about every file on the volume
is dumped.
D:\CliExec\nfi.exe NT-device-path physical-sector-number
Determines which volume a given physical sector on a drive is
within, and then which file on the volume it is in.
NT-device-path is the NT-style path to a physical device.
It must not include a partition specification.
Physical-sector-number is a decimal or 0x-prefixed hex
number, specifying a sector number relative to the physical
drive whose device path is given by NT-device-path.
D:\CliExec\nfi.exe full-win32-path
Dumps information about a particular file. full-win32-path
must start with a drive letter and a colon.
Achei que o número do setor lógico e o segmento de registro de arquivo eram a mesma coisa, mas parece que não são:
PS C:\Users\Xeni> fsutil fsinfo ntfsInfo D:
NTFS Volume Serial Number : 0xfc2bea5043264555
NTFS Version : 3.1
LFS Version : 2.0
Total Sectors : 7,810,824,157 ( 3.6 TB)
Total Clusters : 976,353,019 ( 3.6 TB)
Free Clusters : 275,935,695 ( 1.0 TB)
Total Reserved Clusters : 36,875 (144.0 MB)
Reserved For Storage Reserve : 0 ( 0.0 KB)
Bytes Per Sector : 512
Bytes Per Physical Sector : 512
Bytes Per Cluster : 4096
Bytes Per FileRecord Segment : 1024
Clusters Per FileRecord Segment : 0
Mft Valid Data Length : 2.14 GB
Mft Start Lcn : 0x0000000000000002
Mft2 Start Lcn : 0x000000000a31f5fd
MFT Zone Size : 200.13 MB
Max Device Trim Extent Count : 0
Max Device Trim Byte Count : 0
Max Volume Trim Extent Count : 62
Resource Manager Identifier : E548A579-8A28-11EB-BA87-F4B52033630B
Parece que o segmento de registro do arquivo tem 1024 bytes e o número do setor lógico é 512 bytes, então talvez eu precise dobrar o número para obter o arquivo real referenciado. Mas isso pode muito bem estar errado, pois o número de clusters é muito alto.
Então, como posso realmente identificar o arquivo por segmento de registro de arquivo?
Atualizar
Usei um pouco do Google-fu e descobri essa atrocidade de uma palavra-chave de pesquisa: "file record segment" -unreadable -fix -corrupt
e finalmente encontrei algo útil :
segmento de registro de arquivo: um registro na tabela de arquivos mestre que contém atributos para um arquivo específico em um volume NTFS. O segmento de registro de arquivo tem sempre 1.024 bytes (1 kilobyte) de tamanho.
Apenas duas frases contendo informações cruciais. É isso. O resultado é o resultado principal e todos os outros resultados são irrelevantes.
Agora preciso encontrar uma maneira de consultar programaticamente a Master File Table e esperar não corrompê-la acidentalmente, o que equivale a uma pesquisa mais fútil no Google ...
Vejo que você já descobriu que o número do setor LBA não tem nada a ver com o segmento de registro de arquivo.
Então:
MFT consiste basicamente em registros numerados de 1024 bytes. O número é o seu segmento de registro de arquivo (FRS). Este número é igual ao Arquivo.
(fonte: https://flatcap.github.io/linux-ntfs/ntfs/concepts/file_record.html )
Cluster são grupos reais de setores alocados para um arquivo. Setor é o endereço LBA, comece a contar a partir de 0 = primeiro setor do drive físico. O cluster começa a contar a partir de 0 no primeiro setor do volume ou sistema de arquivos. Portanto, para converter um número de cluster em um endereço de setor LBA, precisamos do deslocamento do LBA para o volume + (cluster * (setores por cluster))
Eu abordo isso do ponto de vista de recuperação de arquivos porque é isso que eu faço e então uso CreateFile para abrir uma unidade, interpreto o setor de inicialização para encontrar o MFT (o primeiro cluster do MFT é fornecido como é o fator de cluster (setores por cluster). MFT é auto-referenciado e, portanto, primeiro o FRS nos fornece todos os clusters alocados para o MFT e a partir daí eu 'analiso' os segmentos de registro do arquivo e coloco as informações principais em uma matriz. O FRS 197571 é então simplesmente o 197571º elemento da matriz a partir do qual você pode determinar o nome do arquivo .
É claro que isso fornece apenas um nome de arquivo e para determinar o caminho completo você precisa resolver o atributo $File_Name para determinar o 'pai', ir para aquele FRS, determinar o nome do arquivo etc.
O melhor recurso online é: https://flatcap.github.io/linux-ntfs/ntfs/
Uma ótima ferramenta para analisar dados RAW e dados interpretados como um FRS é o DMDE (mais exemplos ilustrando isso):
Talvez uma maneira mais direta seja, embora eu nunca tenha tentado, abrir um arquivo por ID de arquivo: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfilebyid? redirecionado de = MSDN , mais dicas @ https://www.codeproject.com/Questions/273746/Given-an-NTFS-File-ID-is-there-any-official-way-to