Ir al contenido



Foto

Trabajando con FAT16 y FAT32


  • Por favor identifícate para responder
17 respuestas en este tema

#1 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 16 junio 2012 - 01:20

Hace unas semanas comentaba con seoane que tras la publicación de dos artículos suyos sobre la lectura directa de discos FAT32, escribí un código en C/C++ añadiendo mas funcionalidad y compatible con FAT16 . No lo compatibilicé con FAT12 por el desuso actual de ese sistema de archivos. A Domingo le agradó mi interés en el tema y me animó a publicarlo. Así que quedé con seoane en impulsar un poco el tema, organizar y publicar el código, pero mis quehaceres me obligaron a posponerlo. Este tipo de código puede resultar peligroso para una unidad USB, así que me he tomado tiempo en realizar pruebas con distintos tipos de Pendrives pequeños
y grandes de hasta 32GB.

Como el tema que abrió seoane data de hace casi 2 meses, este mensaje se me alarga un poco y se centra en C/C++, me ha parecido oportuno abrir un nuevo tema y no continuar con el previo.

El código que presento lee directamente los dispositivos sin usar Streams, es compatible con FAT16 y 32, interpreta  nombres largos de archivo, realiza imágenes de los dispositivos, las lee y es capaz de extraer archivos o carpetas, tanto de un disco como de un archivo de imagen. Estas últimas características pueden ser de utilidad a la hora de realizar copias de seguridad de las unidades con fines restauradores y para extraer el contenido de las mismas sin necesidad de restaurar una unidad.

El código está escrito en C/C++ en forma de API, no es OOP pero se podría escribir una clase con escasos cambios.

Acompaño una aplicación escrita en BCB6 que muestra el uso de la API y hace amigable este asunto, en un entorno gráfico con un TreeView, unos Memo y un ListView que representa un explorador gráfico. El programa detecta automáticamente la inserción de unidades USB y las coloca en un árbol, cuyo primer nivel es la unidad física y en el segundo, muestra la unidad lógica. La aplicación se podría complicar bastante mas...

Como curiosidad añadida, si recordáis el artículo de seoane en el que hablaba de cómo bloquear el acceso a un archivo autorun.inf, la APP de ejemplo usa la API que comento, para tratar los atributos de archivo FAT16/32 a bajo  nivel realizando la tarea descrita en cualquier archivo o carpeta del disco. También podemos jugar con los atributos de directorio y archivo convirtiendo lo uno en lo otro y haciendo inaccesible los contenidos para Windows. En fin, es cuestión de jugar y experimentar.

He de advertir prudencia a la hora de restaurar imágenes de los pendrives, si equivocamos la unidad la machacaremos con la imagen convirtiéndola en otro pendrive... El programa avisará varias veces antes de escribir encima de una unidad de disco.

La API es fácil de usar. Primeramente debemos inicializar con la función OpenDisk que abre el disco físico o unidad lógica en cuestión. Precisa de un parámetro especial, un puntero a un tipo que he llamado ID_VOL y que  almacenará el MBR, BMB, FAT y algunos datos mas de la unidad abierta. Este parámetro se precisará para el resto de las API y representa la unidad que hemos abierto. Al finalizar siempre deberemos llamar a CloseDisk con el consabido parámetro. El código está bastante documentado.

Un ejemplo simple en una aplicación de consola:


cpp
  1. // Inicializamos y abrimos la unidad K:
  2. ID_VOL IdV;
  3. int Status = OpenDisk("\\\\.\\K:", &IdV, 0, false);
  4.  
  5. // Leemos el Root Directory
  6. ListDir(&IdV, "");
  7. // Leemos el Contenido de una carpeta: "K:\Mi Carpeta"
  8. ListDir(&IdV, "Mi Carpeta");
  9.  
  10. // Cambiando atributos
  11. ModifyAttr(&IdV, "Autorun.inf", ATTR_DEVICE, ATTR_DEVICE);
  12.  
  13. // Terminamos...
  14. CloseDisk(&IdV);


Como la unidad abierta está representada por ID_VOL, se omite "K:\". Así, si damos una ruta como "Mi Carpeta" se entiende que es del directorio raíz; sin embargo "Mi Carpeta\archivo" entiende que archivo está en “Mi Carpeta” y que ésta se encuentra en el directorio raíz.

Una curiosidad final: el programa que presento es capaz de "trucar" una memoria USB de forma que parezca de un tamaño mucho mas grande del real. Hice una prueba volcando una imagen de un pendrive de 16 GB a a otro viejo de 500 Mb, imaginaros el resultado  *-). Claro, esto como experimento o broma puede estar bien pero ese pendrive está un poco corrupto... ya lo restauraré.

Subo imágenes de la aplicación, el código fuente para BCB6 y el binario compilado.

Espero que el código y el programa sean de utilidad y sirvan de base para desarrollos futuros. Perdonarme si os aburre tanto C, si tengo mas tiempo procuraré migrar, al menos la API, a delphi, pero no prometo nada. Quizás algún valiente se atreva a hincarle el diente.



Saludos.



PD/ He adaptado el proyecto para que pueda ser compilado con bcb6pe.
Los platinos recordarán el hilo que inició cHackAll

Archivos adjuntos


  • 0

#2 seoane

seoane

    Advanced Member

  • Administrador
  • 1.249 mensajes
  • LocationEspaña

Escrito 16 junio 2012 - 05:32

(y) (y) (y)  Excelente !!!

Un trabajo magnifico, me descubro ante ti maestro.

Tengo que revisarlo a fondo, pero por lo de pronto ya me has resuelto una duda que tenia desde hace tiempo, como relacionar la letra de la unidad con el disco físico.

Gracias por compartirlo.
  • 0

#3 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 16 junio 2012 - 05:55

Me alegra que te guste. Cuando sacaste el tema me resultó interesante sobre todo porque me recordó viejos tiempos lidiando con disquetes y algún disco duro con el DOS y el "debug"... Pero también me pareció un tema de actualidad, asi que quise darle un empujoncito  :).

...Un trabajo magnifico, me descubro ante ti maestro.

Bueno, aunque posiblemente aparezca alguna cosilla que arreglar a mi me gusta como ha quedado. Por cierto que un maestro me califique de maestro es todo un halago, amigo.

...me has resuelto una duda que tenia desde hace tiempo, como relacionar la letra de la unidad con el disco físico.


Bueno, esa duda me la planteé cuando quise colocar las unidades en un árbol y fue la revisión de la API de Windows (msdn.microsoft.com) la que me dio la solución.

Ya ves que no eres el único interesado en cosas raras. :D :D :D


Saludos.
  • 0

#4 seoane

seoane

    Advanced Member

  • Administrador
  • 1.249 mensajes
  • LocationEspaña

Escrito 16 junio 2012 - 05:59

Ya ves que no eres el único interesado en cosas raras. :D :D :D


Es lo que tiene internet, que nunca falta un roto para un descosido  :D :D :D
  • 0

#5 seoane

seoane

    Advanced Member

  • Administrador
  • 1.249 mensajes
  • LocationEspaña

Escrito 17 junio 2012 - 06:18

Portar todo esto a Delphi es un monton de trabajo, pero podemos ir portando algunas funciones.

Como esta:


delphi
  1. uses
  2.   Windows, SysUtils;
  3.  
  4. const
  5.   IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = (ULONG('V') shl 16);
  6.  
  7. type
  8.   DISK_EXTENT = record
  9.     DiskNumber: DWORD;
  10.     StartingOffset: LARGE_INTEGER;
  11.     ExtentLength: LARGE_INTEGER;
  12.   end;
  13.  
  14.   VOLUME_DISK_EXTENTS = record
  15.     NumberOfDiskExtents: DWORD;
  16.     Extents: array[0..1] of DISK_EXTENT;
  17.   end;
  18.  
  19. function GetPhysicalDrive(Volume: Char): Integer;
  20. var
  21.   H: THandle;
  22.   Vde: VOLUME_DISK_EXTENTS;
  23.   BytesReturned: Cardinal;
  24. begin
  25.   Result:= -1;
  26.   H:= CreateFile(PAnsiChar('\\.\' + Volume + ':'),0,0,nil, OPEN_EXISTING, 0, 0);
  27.   if H <> INVALID_HANDLE_VALUE then
  28.   begin
  29.     if DeviceIoControl(H, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, nil, 0,
  30.       @Vde, SizeOf(Vde), BytesReturned, nil) then
  31.     begin
  32.       Result:= Vde.Extents[0].DiskNumber;
  33.     end;
  34.     CloseHandle(h);
  35.   end;
  36. end;
  37.  
  38. // Por ejemplo
  39. Writeln(GetPhysicalDrive('C'));


  • 0

#6 seoane

seoane

    Advanced Member

  • Administrador
  • 1.249 mensajes
  • LocationEspaña

Escrito 17 junio 2012 - 09:42

Otra función mas  ;)



delphi
  1. uses
  2.   Windows, SysUtils;
  3.  
  4. const
  5.   FILE_DEVICE_FILE_SYSTEM = 9;
  6.   FSCTL_LOCK_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16) or (6 shl 2);
  7.   FSCTL_DISMOUNT_VOLUME = (FILE_DEVICE_FILE_SYSTEM shl 16) or (8 shl 2);
  8.  
  9. function LockAndDismount(H: THandle; Force: Boolean): Boolean; overload;
  10. var
  11.   Returned: Cardinal;
  12. begin
  13.   Result:= FALSE;
  14.   if DeviceIoControl(H,FSCTL_LOCK_VOLUME, nil, 0, nil, 0, Returned, nil)
  15.     or Force then
  16.       Result:= DeviceIoControl(H,FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0,
  17.         Returned, nil);
  18. end;
  19.  
  20. function LockAndDismount(Volume: Char; Force: Boolean): THandle; overload;
  21. begin
  22.   Result:= FileOpen('\\.\' + Volume + ':',fmOpenRead or fmShareDenyWrite);
  23.   if Result <> INVALID_HANDLE_VALUE then
  24.   begin
  25.     if not LockAndDismount(Result,Force) then
  26.     begin
  27.       CloseHandle(Result);
  28.       Result:= INVALID_HANDLE_VALUE;
  29.     end;
  30.   end;
  31. end;
  32.  
  33. // Por ejemplo
  34. var
  35.   H: THandle;
  36. begin
  37.   // Bloqueamos y desmontamos G
  38.   H:= LockAndDismount('G',FALSE);
  39.   if H <> INVALID_HANDLE_VALUE then
  40.   begin
  41.     Writeln('OK');
  42.     // Desbloqueamos G
  43.     CloseHandle(H);
  44.   end else
  45.   begin
  46.     Writeln('ERROR');
  47.   end;
  48. end.


  • 0

#7 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 17 junio 2012 - 10:05

Caramba seoane te has propuesto migrarlo todo, comenzando por las llamadas DeviceIoControl.

¿No crees que es mejor simplificar las constantes a sus valores finales?


delphi
  1. FSCTL_DISMOUNT_VOLUME                = $00090020;
  2. FSCTL_LOCK_VOLUME                    = $00090018;
  3. IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = $00560000;



Al fin y al cabo en WinIoCtl.h son constantes también.


Veo, como me dijiste en su momento, que retomas el tema con interés  :D :D :D.


Saludos.
  • 0

#8 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 17 junio 2012 - 10:18



delphi
  1. function LockAndDismount(H: THandle; Force: Boolean): Boolean;



Eres muy respetuoso, yo desmonto directamente no me ando con juegos a la hora de hacer o restaurar una copia de seguridad...  *-)  (b)  :D :D :D


Saludos.
  • 0

#9 seoane

seoane

    Advanced Member

  • Administrador
  • 1.249 mensajes
  • LocationEspaña

Escrito 17 junio 2012 - 10:28

Eres muy respetuoso, yo desmonto directamente no me ando con juegos a la hora de hacer o restaurar una copia de seguridad... 


... y el que quiera seguridad que se haga un seguro de vida  :D :D :D
  • 0

#10 seoane

seoane

    Advanced Member

  • Administrador
  • 1.249 mensajes
  • LocationEspaña

Escrito 17 junio 2012 - 10:35

Veo, como me dijiste en su momento, que retomas el tema con interés  :D :D :D.


Pues si y no  :)

Ahora lo que me anda rondando la cabeza son dos cosas: Android ( y aprender Java  :( ) y el Raspberry Pi que me compre en marzo y todavía no me ha llegado  (li) ... precisamente pensando en este ultimo quería hacer una aplicación que me permita crear y restaurar imágenes de la tarjeta SD, y para eso me vienen fenomenal esas dos funciones.

... pero no descarto volver a lo de la fat mas adelante  ;)
  • 0

#11 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 17 junio 2012 - 01:37

¡¡AVISO!!

Por error he incluido una versión del archivo FileSystem.cpp que no es la definitiva y puede provocar errores el las imágenes y restauraciones de memorias de mas de 4GB. Lo malo es que el archivo definitivo lo borré por equivocación pensando que era el antiguo...  :(  :@ :@ :@

Afortunadamente el cambio sólo afecta a una función así que lo he arreglado. No se si el binario compilaba la versión correcta o no, así que he retirado los archivos y los he vuelto a subir.  :)

Ahora son correctos, lo he probado con una memoria de 16GB.

Aconsejo que cuando hagáis una imagen la abráis con el programa y que la exploréis para ver que es correcta. En caso de error  aparecerán carpetas y archivos de nombres extrañísimos...

Tenéis los enlaces en el primer mensaje.



Saludos.

  • 0

#12 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 26 junio 2012 - 04:39

He decidido pulir algunas cosas que no me terminaban de convencer y he modificado algo la API y la aplicación para:

- Incluir la lectura de particiones en los archivos de imagen de memorias FAT16 y FAT32 y visualización con el explorador de NaviFat.
- Volcado múltiple de archivos y carpetas de Memorias o Imágenes FAT16 y FAT32.
- Cambio múltiple de atributos de carpetas y/o archivos.
- Mejoras en la seguridad de copias de seguridad (imágenes) y restauración de las mismas.

He de advertir el hecho de que si se cambian los atributos de archivo a directorio, para el S.O. se tratará de una carpeta. Si creamos mas archivos o carpetas dentro se corrompe perdiendo la información del archivo original. El cambio de carpeta a archivo y posterior escritura conseguirá efectos similares. No se debe olvidar que el cambio de atributos de archivo a bajo nivel es sólo a efectos experimentales, sobre todo los dos casos comentados.

Como anécdota, yo ya le he sacado utilidad práctica al programa. Tengo un navegador GPS SUPRATECH TRITON que me corrompe la SD cuando se queda sin batería. La reinstalación de los programas en la SD me llevaba mas de una hora de copia de archivos. Con la realización de una imagen de la SD y su posterior restauración es cuestión de pocos minutos.

Espero que alguien mas que yo encuentre utilidad a esta aplicación.

Subo los fuentes y el binario en el primer mensaje de este tema.



Saludos.

  • 0

#13 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 27 junio 2012 - 01:16

Cuando sea grande quiero ser como vosotros :D
  • 0

#14 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 25 agosto 2012 - 12:32

Pues he seguido experimentando el asunto de las copias de seguridad de memorias USB y he visto problemas para restaurar en unidades físicas en entorno Win 7, cosa que no ocurre con unidades lógicas en el mismo entorno. En Win XP ese problema no existe. En resumen Win 7 no deja escribir en cualquier sitio de una unidad física y así lo documenta Microsoft.

Para solventar este problema he decidido escribir un procedimiento que desmonta todas las unidades lógicas de una misma unidad física y también la misma unidad física es desmontada.



Este es el código para desmontar toda una unidad física que nos permite escribir libremente en ella en Vista y Win 7:


delphi
  1. const
  2. FSCTL_DISMOUNT_VOLUME                = $00090020;
  3. FSCTL_LOCK_VOLUME                    = $00090018;
  4. IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = $00560000;
  5. IOCTL_STORAGE_GET_DEVICE_NUMBER      = $002D1080;
  6.  
  7.  
  8. // Encuentra el número de disco físico que corresponde a una letra de unidad
  9. function GetPhysicalNumOfDrive(Volume: Char): integer;
  10. var
  11.   hFile: THandle;
  12.   Vde: array [0..56] of BYTE;  //VOLUME_DISK_EXTENTS
  13.   BytesReturned: Cardinal;
  14. begin
  15.   Result:= -1;
  16.   hFile:= CreateFile(PAnsiChar('\\.\' + Volume + ':'), 0, 0, nil, OPEN_EXISTING, 0, 0);
  17.   if hFile <> INVALID_HANDLE_VALUE then
  18.   begin
  19.     if DeviceIoControl(hFile, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, nil, 0, @Vde, SizeOf(Vde), BytesReturned, nil) then
  20.       Result:= PBYTE(DWORD(@Vde)+8)^;
  21.     CloseHandle(hFile);
  22.   end;
  23. end;
  24.  
  25.  
  26. // Desmonta un disco físico desmontando tosas sus particiones y la misma unidad
  27. procedure DisMountPhysicalDrive(hDevice: THANDLE; hVolumes: PDWORD; var MaxVolumes: DWORD);
  28. var
  29.   BytesReturned, LD, nVol: DWORD;
  30.   Vol: array [0..6] of char;
  31.   sdn: array [0..2] of DWORD; //STORAGE_DEVICE_NUMBER;
  32.   GetLogicalDrives: function(): DWORD; stdcall;
  33. begin
  34.   lstrcpy(Vol, '\\.\A:');
  35.   nVol:= 0;
  36.   GetLogicalDrives:= GetProcAddress(GetModuleHandle('Kernel32.dll'), 'GetLogicalDrives');
  37.  
  38.   if(DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, @sdn, sizeof(sdn), BytesReturned, nil)) then
  39.   begin
  40.     // Si es una unidad física
  41.     if (sdn[0] = 7) and (sdn[2] = 0) then
  42.     begin
  43.       LD:= GetLogicalDrives;
  44.       repeat
  45.         if (LD and 1) <> 0 then
  46.         begin
  47.           if GetPhysicalNumOfDrive(Vol[4]) = integer(sdn[1]) then
  48.           begin
  49.             inc(nVol);
  50.             if hVolumes <> nil then
  51.             begin
  52.               hVolumes^:= CreateFile(Vol, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH or FILE_FLAG_NO_BUFFERING, 0);
  53.               DeviceIoControl(hVolumes^, FSCTL_LOCK_VOLUME, nil, 0, nil, 0, BytesReturned, nil);
  54.               DeviceIoControl(hVolumes^, FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0, BytesReturned, nil);
  55.               inc(hVolumes);
  56.             end;
  57.           end;
  58.         end;
  59.         inc(Vol[4]); LD:= (LD shr 1);
  60.       until (LD = 0) or ((hVolumes <> nil) and (nVol = MaxVolumes));
  61.  
  62.       // Desmonto la unidad física
  63.       if hVolumes <> nil then
  64.       begin
  65.         DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, nil, 0, nil, 0, BytesReturned, nil);
  66.         DeviceIoControl(hDevice, FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0, BytesReturned, nil);
  67.       end;
  68.     end;
  69.   end;
  70.   MaxVolumes:= nVol;
  71. end;



Esta función precisa pasar un array de Handles con una dimensión igual o superior al número de unidades lógicas o particiones de la unidad de disco físico. Por necesidades propias, la unidad física la paso ya abierta pero es sencillo modificar el código para que el parámetro sea un nombre de unidad física "\\.\PhysicalDriveX".

Si el array de Handles es nulo, la función entiende que queremos saber el número necesario, lo calcula sin desmontar nada. Si devuelve 0 significa que hubo un error (no es una unidad física o el handle no era válido).

Un ejemplo de uso:


delphi
  1. var
  2.   hDevice: THANDLE;
  3.   nVols: DWORD;
  4.   hVols: array of THandle;
  5. begin
  6.   // Abrimos una unidad física.
  7.   hDevice:= CreateFile('\\.\PhysicalDrive1', GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH or FILE_FLAG_NO_BUFFERING, 0);
  8.  
  9.   // Calculo el número de handles necesarios (particiones)
  10.   DisMountPhysicalDrive(hDevice, nil, nVols);
  11.   SetLength(hVols, nVols);
  12.  
  13.   // Desmontamos completamente la unidad
  14.   DisMountPhysicalDrive(hDevice, @hVols[0], nVols);
  15.  
  16.  
  17.   // Ahora podemos escribir y leer tranquilamente
  18.   // ................................................................
  19.  
  20.  
  21.   // Una vez cerremos los Handles ¡¡Ya no está desmontada la unidad!!
  22.  
  23.   // Para que la unidad pueda ser usada de nuevo por el S.O. debemos liberarla
  24.   repeat CloseHandle(hVols[nVols-1]); dec(nVols); until nVols = 0;
  25.   CloseHandle(hDevice);
  26.   SetLength(hVols, 0);
  27. end;



La prueba de fuego la he hecho en Win 7 y con código similar en C/C++ recuperando una imagen de disco físico sobre un Pendrive. En delphi lo he probado pero sin escribir pero debe funcionar.

Un detalle curioso que me ha ocurrido en la versión delphi es que el AV me ha estado tocando las narices con la API "GetLogicalDrives" empeñándose en que estaba escribiendo un virus  ^o|, así que la he importado dinámicamente y a correr.

Bueno, espero que sea de utilidad. Seguro que a seoane le vale (o encuentra algún fallo pues ya digo que la prueba de fuego la hice en C/C++)



PD: No tratéis de desmontar la unidad del S.O.  *-)

Saludos.
  • 0

#15 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 25 agosto 2012 - 12:40

Y como extracto del código anterior voy a escribir una función que puede ser útil para saber si un Handle de dispositivo representa una unidad de disco física o no:



delphi
  1. const
  2. IOCTL_STORAGE_GET_DEVICE_NUMBER      = $002D1080;
  3.  
  4.  
  5. // True si el dispositivo es un disco físico
  6. function IsPhysicalDrive(hDevice: THANDLE): boolean;
  7. var
  8.   BytesReturned: DWORD;
  9.   sdn: array [0..2] of DWORD; //STORAGE_DEVICE_NUMBER;
  10. begin
  11.   Result:= false;
  12.   if(DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, @sdn, sizeof(sdn), BytesReturned, nil)) then
  13.     Result:= (sdn[0] = 7) and (sdn[2] = 0);
  14. end;




Ejemplo de uso:


delphi
  1. var
  2.   hDevice: THANDLE;
  3. begin
  4.   hDevice:= CreateFile('\\.\PhysicalDrive1', 0, 0, nil, OPEN_EXISTING, 0, 0);
  5.   Result = IsPhysicalDrive(hDevice);
  6. end;




Saludos.
  • 0

#16 seoane

seoane

    Advanced Member

  • Administrador
  • 1.249 mensajes
  • LocationEspaña

Escrito 25 agosto 2012 - 03:49

Seguro que a seoane le vale (o encuentra algún fallo pues ya digo que la prueba de fuego la hice en C/C++)

Pues seguro que me da alguna idea. Ya había notado que había problemas para restaurar las copias de seguridad de los USB, así que este código me viene fenomenal.

PD: No tratéis de desmontar la unidad del S.O.  *-)

Ya veo que tu ya probaste  :D ... yo probé a escribir sobre el MBR en XP y adivinen ... funciono  :s  :D
  • 0

#17 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 25 agosto 2012 - 04:29


PD: No tratéis de desmontar la unidad del S.O.  *-)

Ya veo que tu ya probaste  :D ... yo probé a escribir sobre el MBR en XP y adivinen ... funciono  :s  :D


Pues si, lo he probado contra el disco "\\.\PhysicalDrive0"  donde está mi unidad C:\. No pude resistirme a la tentación de desmontarlo... Los programas abiertos dejaros de responder adecuadamente y Explorer.exe cayó de mala manera, pero no hubo desastres  :D.

La peor experiencia con este tipo de código fue probando una restauración de Pendrive. Tenía dos enchufados. Uno con el código recién compilado (estaba trabajando sobre el pendrive) y otro de pruebas. Había puesto en el programa mil y un avisos de advertencia contra incautos antes de proceder a la restauración. Yo, ansioso por probar el funcionamiento del recién compilado y flamante código, ejecuté velozmente y confundí el pendrive... 16Gb de código, y archivos fueron destruidos en pocos segundos, lo que tardé en desenchufarlo.... :@ :. Que desastre. Menos mal que tenía copia y perdí pocas cosas.


Saludos.

 
  • 0

#18 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.043 mensajes
  • LocationMéxico

Escrito 26 agosto 2012 - 12:41

Ya ven porque los AV se quejan, ustedes si que le dan de patadas al API para que reaccione, que esperaban de los AV's :D :D :D

Saludos
  • 0