Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
prog:lazarus:cas:files:virtualdisk [25/07/2024 12:03]
thierry [Comment créé un disque virtuel en Pascal]
prog:lazarus:cas:files:virtualdisk [25/07/2024 12:04] (Version actuelle)
thierry [Autre piste]
Ligne 28: Ligne 28:
 Source : OpenAI ChatGPT Source : OpenAI ChatGPT
 ===== Autre piste ===== ===== Autre piste =====
 +<note important>​généré par ChatGPT, non vérifié !!!</​note>​
 +Créer un fichier VHD à partir d'un disque dur réel en Free Pascal nécessite une compréhension du format VHD ainsi que la capacité à lire les données d'un disque dur et à les écrire dans un fichier avec la structure correcte du VHD.
  
 +Le format VHD (Virtual Hard Disk) est un format de fichier de disque virtuel développé par Microsoft. Il existe plusieurs types de VHD, mais nous nous concentrerons ici sur un VHD de type "​fixed-size",​ qui est le plus simple à implémenter.
 +
 +### Étapes pour créer un fichier VHD en Free Pascal
 +
 +1. **Lire les données du disque dur réel**
 +2. **Créer l'​en-tête du fichier VHD**
 +3. **Écrire les données dans le fichier VHD avec l'​en-tête**
 +
 +### Code Exemple en Free Pascal
 +
 +Voici un exemple de code qui lit les données d'un disque dur réel et les écrit dans un fichier VHD fixe:
 +
 +<code delphi>
 +program DiskToVHD;
 +
 +uses
 +  SysUtils, Classes;
 +
 +const
 +  BufferSize = 1024 * 1024;  // 1 MB buffer
 +  SectorSize = 512;
 +  FixedVHDHeaderSize = 512;
 +
 +type
 +  TVHDFooter = packed record
 +    Cookie: array[0..7] of AnsiChar;
 +    Features: Cardinal;
 +    FileFormatVersion:​ Cardinal;
 +    DataOffset: Int64;
 +    TimeStamp: Cardinal;
 +    CreatorApplication:​ array[0..3] of AnsiChar;
 +    CreatorVersion:​ Cardinal;
 +    CreatorHostOS:​ array[0..3] of AnsiChar;
 +    OriginalSize:​ Int64;
 +    CurrentSize:​ Int64;
 +    DiskGeometry:​ array[0..5] of Byte;
 +    DiskType: Cardinal;
 +    Checksum: Cardinal;
 +    UniqueID: array[0..15] of Byte;
 +    SavedState: Byte;
 +    Reserved: array[0..426] of Byte;
 +  end;
 +
 +procedure CreateFixedVHD(const DiskPath, VHDPath: string);
 +var
 +  DiskFile, VHDFile: TFileStream;​
 +  Buffer: array[1..BufferSize] of Byte;
 +  BytesRead: LongInt;
 +  DiskSize, RemainingSize:​ Int64;
 +  Footer: TVHDFooter;
 +  I: Integer;
 +begin
 +  DiskFile := TFileStream.Create(DiskPath,​ fmOpenRead or fmShareDenyNone);​
 +  try
 +    DiskSize := DiskFile.Size;​
 +    RemainingSize := DiskSize;
 +    VHDFile := TFileStream.Create(VHDPath,​ fmCreate);
 +    try
 +      // Copy disk data to VHD file
 +      while RemainingSize > 0 do
 +      begin
 +        BytesRead := DiskFile.Read(Buffer,​ BufferSize);​
 +        if BytesRead > 0 then
 +        begin
 +          VHDFile.Write(Buffer,​ BytesRead);
 +          Dec(RemainingSize,​ BytesRead);
 +        end
 +        else
 +          Break;
 +      end;
 +
 +      // Fill remaining space if necessary
 +      FillChar(Buffer,​ BufferSize, 0);
 +      while RemainingSize > 0 do
 +      begin
 +        BytesRead := Min(RemainingSize,​ BufferSize);​
 +        VHDFile.Write(Buffer,​ BytesRead);
 +        Dec(RemainingSize,​ BytesRead);
 +      end;
 +
 +      // Prepare VHD footer
 +      FillChar(Footer,​ SizeOf(Footer),​ 0);
 +      Move('​conectix',​ Footer.Cookie,​ 8);
 +      Footer.Features := $00000002; // no features enabled
 +      Footer.FileFormatVersion := $00010000;
 +      Footer.DataOffset := -1;
 +      Footer.TimeStamp := DateTimeToFileDate(Now) - DateTimeToFileDate(EncodeDate(2000,​ 1, 1));
 +      Move('​GPTS',​ Footer.CreatorApplication,​ 4);
 +      Footer.CreatorVersion := $00060000;
 +      Move('​Wi2k',​ Footer.CreatorHostOS,​ 4);
 +      Footer.OriginalSize := DiskSize;
 +      Footer.CurrentSize := DiskSize;
 +      Footer.DiskGeometry[0] := $10;  // cylinders (16)
 +      Footer.DiskGeometry[1] := $FE;  // heads (254)
 +      Footer.DiskGeometry[2] := $00;  // sectors per track (0)
 +      Footer.DiskGeometry[3] := $3F;  // sectors per track (63)
 +      Footer.DiskGeometry[4] := $00;
 +      Footer.DiskGeometry[5] := $00;
 +      Footer.DiskType := 2;  // fixed
 +      Footer.Checksum := 0;
 +      for I := 0 to SizeOf(Footer) - 1 do
 +        Footer.Checksum := Footer.Checksum + PByte(@Footer)[I];​
 +      Footer.Checksum := not Footer.Checksum;​
 +
 +      // Write footer twice
 +      VHDFile.Write(Footer,​ SizeOf(Footer));​
 +      VHDFile.Write(Footer,​ SizeOf(Footer));​
 +    finally
 +      VHDFile.Free;​
 +    end;
 +  finally
 +    DiskFile.Free;​
 +  end;
 +end;
 +
 +begin
 +  try
 +    CreateFixedVHD('​\\.\PhysicalDrive0',​ '​output.vhd'​);​
 +    Writeln('​VHD créé avec succès.'​);​
 +  except
 +    on E: Exception do
 +      Writeln('​Une erreur est survenue : ', E.Message);
 +  end;
 +end.
 +</​code>​
 +### Explications
 +
 +1. **Structure du Footer VHD**: Le programme définit la structure du footer pour un VHD fixe, nécessaire pour marquer la fin du fichier VHD et contenir des métadonnées importantes.
 +2. **Lecture du disque physique**: Le programme ouvre le disque physique spécifié (`\\.\PhysicalDrive0`),​ lit les données par blocs de 1 MB et les écrit dans le fichier VHD.
 +3. **Footer VHD**: Après avoir copié toutes les données, le programme crée et écrit deux fois le footer VHD à la fin du fichier, conformément aux spécifications du format VHD.
 +
 +### Précautions et Limitations
 +
 +- **Privilèges administratifs**:​ L'​accès au disque physique nécessite des privilèges administratifs.
 +- **Taille du disque**: Assurez-vous d'​avoir suffisamment d'​espace disque pour contenir la copie complète du disque physique.
 +- **Checksum et autres métadonnées**:​ Le calcul du checksum et des autres métadonnées du footer VHD doit être correct pour que le fichier VHD soit valide et utilisable.
 +
 +Ce programme est un point de départ. Pour une solution robuste et complète, il est recommandé de bien comprendre les spécifications du format VHD et de tester rigoureusement le code pour gérer toutes les éventualités.
 ====== Sources & Ressouces ====== ====== Sources & Ressouces ======
   * [[https://​learn.microsoft.com/​fr-fr/​archive/​msdn-magazine/​2009/​april/​windows-with-c-the-virtual-disk-api-in-windows-7]]   * [[https://​learn.microsoft.com/​fr-fr/​archive/​msdn-magazine/​2009/​april/​windows-with-c-the-virtual-disk-api-in-windows-7]]