2012-01-11 19 views
10

Duplicar posible:
How do I restore a file from the recycle bin using C#?
Recovering deleted file on windowsC# clases para recuperar archivos?

Estoy trabajando en una aplicación que se pretende recuperar archivos borrados del sistema (tanto los que la papelera de reciclaje y los que ya están vaciados de la papelera de reciclaje, pero aún comprensible) y unidades formateadas. Decidí C# como lenguaje, pero tengo problemas para encontrar clases que se ocupen de este problema. ¿Alguien sabe alguna clase/método para encontrar archivos borrados, recuperarlos o cualquier tutorial o ayuda en el asunto? Tengo poca experiencia en el tema, por lo que cualquier ayuda sería muy apreciada.

+1

Supongo que terminarás con una de las muchas aplicaciones de recuperación con una interfaz de línea de comandos. – CodingBarfield

+0

No estoy seguro de que C# lo haga, ya que probablemente necesite algunas API de bajo nivel para leer datos del disco desde una ubicación determinada. Es probable que use C o C++ para eso. – oleksii

+0

Relacionados: [Recuperación de archivos eliminados en Windows] (http://stackoverflow.com/questions/2837307/recovering-deleted-file-on-windows), [¿Cómo puedo recuperar un archivo usando C#?] (Http: // stackoverflow.com/questions/1352550/how-can-i-undelete-a-file-using-c), [¿Cómo abro un directorio con CreateFile en C# para examinar las entradas eliminadas?] (http://stackoverflow.com/questions/1344094/how-do-i-open-a-directory-with-createfile-in-c-sharp-to-exam-deleted-entries) –

Respuesta

37

No hay clases integradas para hacer lo que pidió.

En realidad, la eliminación de archivos es un proceso difícil y requiere un conocimiento de nivel muy bajo de su sistema de archivos. Entonces, lo primero que debe hacer es obtener información sobre la unidad que contiene el archivo que desea recuperar. Básicamente, primero quieres saber su sistema de archivos.

Tendrás que usar P/invocar mucho. En primer lugar obtener un identificador para la unidad que actuar bien:

[DllImport("kernel32.dll", SetLastError = true)] 
static extern bool CloseHandle(IntPtr handle); 

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
static extern IntPtr CreateFile(
    string lpFileName, 
    uint dwDesiredAccess, 
    uint dwShareMode, 
    IntPtr lpSecurityAttributes, 
    uint dwCreationDisposition, 
    int dwFlagsAndAttributes, 
    IntPtr hTemplateFile); 

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
static extern bool GetVolumeInformationByHandleW(
    IntPtr hDisk, 
    StringBuilder volumeNameBuffer, 
    int volumeNameSize, 
    ref uint volumeSerialNumber, 
    ref uint maximumComponentLength, 
    ref uint fileSystemFlags, 
    StringBuilder fileSystemNameBuffer, 
    int nFileSystemNameSize); 

// Gets a handle to the drive 
// Note: use CloseHandle to close the handle you opened once work is done 
IntPtr hDrive = NativeMethods.CreateFile(
    string.Format("\\\\.\\{0}:", DriveLetter) 
    GenericRead, 
    Read | Write, 
    IntPtr.Zero, 
    OpenExisting, 
    0, 
    IntPtr.Zero); 

// Then gets some information about the drive 
// The following function requires Vista+ 
// Use GetVolumeInformation for older systems 
const int VolumeNameSize = 255; 
const int FileSystemNameBufferSize = 255; 
StringBuilder volumeNameBuffer = new StringBuilder(VolumeNameSize); 
uint volumeSerialNumber = 0; 
uint maximumComponentLength = 0; 
uint fileSystemFeatures; 
StringBuilder fileSystemNameBuffer = new StringBuilder(FileSystemNameBufferSize); 

GetVolumeInformationByHandleW(
    hDrive, 
    volumeNameBuffer, 
    VolumeNameSize, 
    ref volumeSerialNumber, 
    ref maximumComponentLength, 
    ref fileSystemFeatures, 
    fileSystemNameBuffer, 
    FileSystemNameBufferSize); 

// Now you know the file system of your drive 
// NTFS or FAT16 or UDF for instance 
string FileSystemName = fileSystemNameBuffer.ToString(); 

Una vez que tenga el nombre del sistema de archivos, usted tiene que leer manualmente los datos en bruto de la unidad. Lo que leerá por completo depende del sistema de archivos de la unidad. De todos modos, usted tiene que conseguir una manija en el disco duro asociado para ello:

// Gets a handle to the physical disk 
IntPtr hDisk = CreateFile(string.Format("\\\\.\\PhysicalDrive{0}", diskNumber), 
    GenericRead, 
    Read | Write, 
    0, 
    OpenExisting, 
    0, 
    IntPtr.Zero); 

Ahora es la parte que tiene que saber mucho acerca de su sistema de archivos ... Para el sistema de archivos NTFS, Tendrás que entender el concepto de Master File Table. En realidad, eso es bastante difícil. Para sistemas de archivos FAT, eso es menos complicado pero aún así, tendrás que estudiar el FS por un tiempo. Comience con wikipedia.

Desde el mango que usaste usando CreateFile, ahora leerás (acceso sin procesar) bytes por byte (sector por sector en realidad) en el disco para obtener la información que deseas usando ReadFile.

// Used to read in a file 
[DllImport("kernel32.dll")] 
public static extern bool ReadFile(
    IntPtr hFile, 
    byte[] lpBuffer, 
    uint nNumberOfBytesToRead, 
    ref uint lpNumberOfBytesRead, 
    IntPtr lpOverlapped); 

// Used to set the offset in file to start reading 
[DllImport("kernel32.dll")] 
public static extern bool SetFilePointerEx(
    IntPtr hFile, 
    long liDistanceToMove, 
    ref long lpNewFilePointer, 
    uint dwMoveMethod); 

// Set offset 
int bufferSize = 512; 
byte[] buffer = new byte[bufferSize]; 
SetFilePointerEx(
    hDisk, 
    offset, 
    ref pt, 
    FileBegin); 

// Read a whole sector 
// Note that you can't read less than a whole sector of your physical disk. Usually it's 512 bytes, 
// but you'll have to retrieve this information from the disk geometry. If you're interested, I can provide you 
// some code. It requires the use of the IOCTL_DISK_GET_DRIVE_GEOMETRY control code. 
uint read = 0; 
ReadFile(
    hDisk, 
    buffer, 
    bufferSize, 
    ref read, 
    IntPtr.Zero); 

para NTFS, lo primero que conseguir el sector a partir de la MFT .... entonces usted tendrá que "analizar" la MFT y buscar archivos borrados ...

Gané explica todo el proceso aquí. Ver this link para un ejemplo.

Así que buena suerte con eso :)

Ahora es probable que desee utilizar una aplicación de terceros que ya hace todo esto y utilizarlo desde su propio programa (herramienta de línea de comandos como se ha dicho en los comentarios) .

Cuestiones relacionadas