Newsgroup: it.comp.lang.delphi
Titolo: Lettura byte a byte dell'HDD

Salve,
Come da oggetto, avrei bisogno di leggere byte a byte ogni singolo
cluster del mio HDD. Potete indicarmi se esiste una qualche libreria, un 
componente o quant'altro in merito.
Grazie,
Kayn.

Se usi Windows 2000, NT o XP devi crearti un driver apposito per 
accedere all'hardware, mentre se usi Windows 95 o 98 puoi utilizzare 
l'API DeviceIoControl ed accedere direttamente agli interrupt 13 (bios), 
21, 25 e 26 del DOS in questa maniera:
//----------------------------------------------------------------------
// Usati per l'accesso diretto all'hardware
// ----------------------------------------------------------------------
Const
    VWin_Dioc_Dos_Ioctl 	= 1; // INT 21h - Funzioni Da 4400h a 4411h
    VWin_Dioc_Dos_Int25	= 2; // INT 25h - Disk Read
    VWin_Dioc_Dos_Int26	= 3; // INT 25h - Disk Write
    VWin_Dioc_Dos_Int13	= 4; // INT 13h
Var
   hDevice : THandle;         // Handle del device
   isOpen  : Boolean;         // Device aperto o chiuso
Const
   flgCarry     	= $001;
   flgParity    	= $002;
   flgAuxiliary 	= $004;
   flgZero      	= $008;
   flgSign      	= $010;
   flgTrap      	= $020;
   flgInterrupt 	= $040;
   flgDirection 	= $080;
   flgOverflow  	= $100;
Var
   DIOCError : Dword;
Type
   DIOC_REGISTERS = Record
                      EBX   : Dword;
                      EDX   : Dword;
                      ECX   : Dword;
                      EAX   : Dword;
                      EDI   : Dword;
                      ESI   : Dword;
                      Flags : Dword;
                    End;
// Queste accedono al device driver di comunicazione hardware
Function DoIOCTLOpened(Var REG         	 : DIOC_REGISTERS;
                            DIOC_Function : Dword) : Boolean;
Var
   fResult : Boolean;
   CB      : Dword;
Begin
   fResult := DeviceIoControl(hDevice,
                              DIOC_Function,
                              @REG, SizeOf(REG),
                              @REG, SizeOf(Reg),
                              CB,   Nil);
   If Not fResult Then DIOCError := Reg.EAX;
   Result := fResult;
End;
Function DoIOCTL(Var REG           : DIOC_REGISTERS;
                      DIOC_Function : Dword) : Boolean;
Var
   fResult : Boolean;
   CB      : Dword;
Begin
   If isOpen Then
      Begin
        Result := DoIOCTLOpened(REG, DIOC_Function);
        Exit;
      End;
   hDevice := CreateFile('\\.\VWIN32',
                         0,
                         0,
                         Nil,
                         0,
                         FILE_FLAG_DELETE_ON_CLOSE,
                         0);
   If hDevice <> INVALID_HANDLE_VALUE Then
      Begin
        fResult := DeviceIoControl(hDevice,
                                   DIOC_Function,
                                   @REG, SizeOf(REG),
                                   @REG, SizeOf(REG),
                                   CB,   Nil);
        If Not fResult Then DIOCError := Reg.EAX;
        CloseHandle(hDevice);
      End
        Else
      Begin
        fResult   := False;
        DIOCError := GetLastError;
      End;
   Result := fResult;
End;
// Le routine che seguno accedono ai singoli interrupt
Function IOCTL_CallInt13(Var Reg : DIOC_REGISTERS) : Boolean;
Begin
   Result := DoIOCTL(Reg, VWin_Dioc_Dos_Int13);
End;
Function IOCTL_CallInt21(Var Reg : DIOC_REGISTERS) : Boolean;
Begin
   Result := DoIOCTL(Reg, VWin_Dioc_Dos_IOCTL);
End;
Function IOCTL_CallInt25(Var Reg : DIOC_REGISTERS) : Boolean;
Begin
   Result := DoIOCTL(Reg, VWin_Dioc_Dos_Int25);
End;
Function IOCTL_CallInt26(Var Reg : DIOC_REGISTERS) : Boolean;
Begin
   Result := DoIOCTL(Reg, VWin_Dioc_Dos_Int26);
End;
Quindi per prelevare, ad esempio, il numero di serie dell'hard-disk 
basta usare una funzione tipo questa che richiama l'interrupt 21 
funzione 44(esadecimale)
Function GetDriveSerialNum(Var MID   : MIDRec;
                                Drive : Word) : Boolean;
Var
   R : DIOC_REGISTERS;
Begin
   R.EAX := $440D;
   R.EBX := Drive;
   R.ECX := $0866;
   R.EDX := DWord(@MID);
   If IOCTL_CallInt21(R)
   Then
     Result := ((R.Flags And flgCarry) = 0)
   Else
     Result := False;
End;
Per le funzioni dei singoli interrupt cerca in giro e troverai una marea 
  di documentazione (in Inglese ovviamente)
Ciao,
David

microges ha scritto:
[cut]
Grazie per la risposta.
Avresti da consigliarmi qualcosa in più in merito a Windows NT/XP?
Kayn.

No mi dispiace ma credo che componenti per 2K/NT/XP che facciano questo 
siano solo a pagamento in quanto la creazione di un device driver è una 
grande scocciatura
Ciao,
David



Io cambierei "scocciatura" con "macello". Sono due mesi che stiamo litigando
nel creare un driver per una stampante virtuale e non è per nulla semplice,
il tutto con l'aggiunta che la documentazione, quando c'è ,è molto vaga
:-/
-- 
Lis                 
www.alessandroghezzi.it
O'Telma Formula1:   
http://snipurl.com/otelma
Gli Dei hanno dato agli uomini due orecchie e una bocca per poter ascoltare
il doppio e parlare la metà (Talète)

 :-/
Infatti tempo fà presi in mano la documentazione Microsoft per la 
creazione di driver, ma mi persi nei meandri delle specifiche.
Grazie cmq per l'aiuto.

 c'è ,è molto vaga :-/
http://www.setecastronomy.stufftoread.com/downloads/vprinter.zip
Vuoi supportarmi? 
http://url.repository.biz/go/3E
-- 
I am what I am, I do what I can
Do. Or do not. There is not try.

 
http://www.setecastronomy.stufftoread.com/downloads/vprinter.zip
Grazie, questo è lo stesso punto di partenza che abbiamo usato noi, ma è
solo un inizio perchè ci sono vari problemi e abbiamo dovuto fare parecchie
modifiche al print processor e alla procedura di assemblamento degli emf.
Ora, incrociando le dita, sembra funzionare
-- 
Lis                 
www.alessandroghezzi.it
O'Telma Formula1:   
http://snipurl.com/otelma
Entro sei mesi la gente si stancherà di stare a guardare quella scatola di
legno chiamata Tv (D.Zanuck)