Recent

Author Topic: Have anyone know how to format the partition to FAT32 File System with pascal?  (Read 2420 times)

TYDQ

  • Full Member
  • ***
  • Posts: 139
I have met a bug that when I tried to format the partition to FAT32 File System with pascal,the UEFI cannot recognize my FAT32 Header,and this is the key source code:
fat32 records in uefi.pas:
Code: Pascal  [Select][+][-]
  1. type fat32_header=packed record
  2.                   JumpOrder:array[1..3] of byte;
  3.                   OemCode:array[1..8] of char;
  4.                   BytesPerSector:word;
  5.                   SectorPerCluster:byte;
  6.                   ReservedSectorCount:word;
  7.                   NumFATs:byte;
  8.                   RootEntryCount:word;
  9.                   TotalSector16:word;
  10.                   Media:byte;
  11.                   FATSectors16:word;
  12.                   SectorPerTrack:word;
  13.                   NumHeads:word;
  14.                   HiddenSectors:dword;
  15.                   TotalSectors32:dword;
  16.                   FATSector32:dword;
  17.                   ExtendedFlags:word;
  18.                   FileSystemVersion:word;
  19.                   RootCluster:dword;
  20.                   FileSystemInfo:word;
  21.                   BootSector:word;
  22.                   Reserved:array[1..12] of byte;
  23.                   DriverNumber:byte;
  24.                   Reserved1:byte;
  25.                   BootSignature:byte;
  26.                   VolumeID:dword;
  27.                   VolumeLabel:array[1..11] of char;
  28.                   FileSystemType:array[1..8] of char;
  29.                   Reserved2:array[1..420] of byte;
  30.                   SignatureWord:word;
  31.                   Reserved3:array[1..65023] of byte;
  32.                   end;
  33.      fat32_file_system_info=packed record
  34.                             FSI_leadSig:dword;
  35.                             FSI_Reserved1:array[1..480] of byte;
  36.                             FSI_StrucSig:dword;
  37.                             FSI_FreeCount:dword;
  38.                             FSI_NextFree:dword;
  39.                             FSI_Reserved2:array[1..12] of byte;
  40.                             FSI_TrailSig:dword;
  41.                             FSI_Reserved3:array[1..65023] of byte;
  42.                             end;
My fat32 header to write in the specified disk's position:
Code: Pascal  [Select][+][-]
  1. if(i=harddiskindex) then
  2.     begin
  3.      fat32h.JumpOrder[1]:=$EB; fat32h.JumpOrder[2]:=$58; fat32h.JumpOrder[3]:=$90;
  4.      fat32h.OemCode[1]:='T'; fat32h.OemCode[2]:='Y'; fat32h.OemCode[3]:='D'; fat32h.OemCode[4]:='Q';
  5.      fat32h.OemCode[5]:='O'; fat32h.OemCode[6]:='S'; fat32h.OemCode[7]:=' '; fat32h.OemCode[8]:=#0;
  6.      fat32h.BytesPerSector:=blocksize;
  7.      fat32h.SectorPerCluster:=128;
  8.      fat32h.ReservedSectorCount:=4+256 div (blocksize div 512);
  9.      fat32h.NumFATs:=2;
  10.      fat32h.RootEntryCount:=0;
  11.      fat32h.TotalSector16:=0;
  12.      fat32h.Media:=$F8;
  13.      fat32h.FATSectors16:=0;
  14.      fat32h.SectorPerTrack:=0;
  15.      fat32h.NumHeads:=0;
  16.      fat32h.HiddenSectors:=0;
  17.      fat32h.TotalSectors32:=1024*100 div (blocksize div 512);
  18.      fat32h.FATSector32:=128 div (blocksize div 512);
  19.      fat32h.ExtendedFlags:=0;
  20.      fat32h.filesystemVersion:=0;
  21.      fat32h.RootCluster:=2;
  22.      fat32h.FileSystemInfo:=1;
  23.      fat32h.BootSector:=6;
  24.      for j:=1 to 12 do fat32h.Reserved[j]:=0;
  25.      fat32h.DriverNumber:=$00;
  26.      fat32h.Reserved1:=0;
  27.      fat32h.BootSignature:=$29;
  28.      fat32h.VolumeID:=0;
  29.      fat32h.VolumeLabel[1]:='E'; fat32h.VolumeLabel[2]:='F'; fat32h.VolumeLabel[3]:='I'; fat32h.VolumeLabel[4]:=' ';
  30.      fat32h.VolumeLabel[5]:='P'; fat32h.VolumeLabel[6]:='A'; fat32h.VolumeLabel[7]:='R'; fat32h.VolumeLabel[8]:='T';
  31.      fat32h.VolumeLabel[9]:=' '; fat32h.VolumeLabel[10]:=' '; fat32h.VolumeLabel[11]:=#0;
  32.      fat32h.FileSystemType[1]:='F'; fat32h.FileSystemType[2]:='A'; fat32h.FileSystemType[3]:='T';
  33.      fat32h.FileSystemType[4]:='3'; fat32h.FileSystemType[5]:='2'; fat32h.FileSystemType[6]:=' ';
  34.      fat32h.FileSystemType[7]:=' '; fat32h.FileSystemType[8]:=#0;
  35.      for j:=1 to 420 do fat32h.Reserved2[j]:=0;
  36.      fat32h.SignatureWord:=$AA55;
  37.      if(BlockSize>512) then for j:=1 to BlockSize-512 do fat32h.Reserved3[j]:=0;
  38.      fat32fs.FSI_leadsig:=$41615252;
  39.      for j:=1 to 480 do fat32fs.FSI_Reserved1[j]:=0;
  40.      fat32fs.FSI_StrucSig:=$61417272;
  41.      fat32fs.FSI_FreeCount:=100*1024 div (blocksize div 512)-128 div (blocksize div 512)-2;
  42.      fat32fs.FSI_NextFree:=2;
  43.      for j:=1 to 12 do fat32fs.FSI_Reserved2[j]:=0;
  44.      fat32fs.FSI_TrailSig:=$AA550000;
  45.      if(BlockSize>512) then for j:=1 to BlockSize-512 do fat32fs.FSI_Reserved3[j]:=0;
  46.      diop^.WriteDisk(diop,mediaid,gpt.FirstUsableLBA*blocksize,blocksize,@fat32h);
  47.      diop^.WriteDisk(diop,mediaid,gpt.FirstUsableLBA*blocksize+blocksize,blocksize,@fat32fs);
  48.     end;
Have anyone know why the bug occurs and please give me a solution to format the fat32 file system in one of GPT Partitions using pascal?
My total source code is in this repository https://github.com/TYDQSoft/UEFIPascalOS

MarkMLl

  • Hero Member
  • *****
  • Posts: 8525
Since nobody else has commented: write your code to format the partition to /exactly/ what the canonical UEFI utilities would do, and only then start doing things like customising OemCode.

Frankly, while I've never been particularly worried about using my own code to read a preformatted filesystem, I've always been very wary about writing it. However I think that FAT (including FAT32) is somewhat more forgiving than more advances FSes: hence it's popularity.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TYDQ

  • Full Member
  • ***
  • Posts: 139
Since nobody else has commented: write your code to format the partition to /exactly/ what the canonical UEFI utilities would do, and only then start doing things like customising OemCode.

Frankly, while I've never been particularly worried about using my own code to read a preformatted filesystem, I've always been very wary about writing it. However I think that FAT (including FAT32) is somewhat more forgiving than more advances FSes: hence it's popularity.

MarkMLl
But performatted file system is invaild on the UEFI Bare Machine with all Disk Utilities are also invaild,I want to write an UEFI OS installer by myself to install my Test OS on the disk.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8525
In that case find a preformatted FS that isn't invalid before trying to go any further.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Laksen

  • Hero Member
  • *****
  • Posts: 802
    • J-Software
For it to be seen as a FAT32 fs and not a FAT12/16 the total amount of clusters must be over 65525

TYDQ

  • Full Member
  • ***
  • Posts: 139
My pascal is changed after I read the FAT32 Specification.And these are my codes but I cannot create the subdirectory for the root directory:
Code: Pascal  [Select][+][-]
  1. fat32h.JumpOrder[1]:=$EB; fat32h.JumpOrder[2]:=$58; fat32h.JumpOrder[3]:=$90;
  2.      fat32h.OemCode[1]:='T'; fat32h.OemCode[2]:='Y'; fat32h.OemCode[3]:='D'; fat32h.OemCode[4]:='Q';
  3.      fat32h.OemCode[5]:='O'; fat32h.OemCode[6]:='S'; fat32h.OemCode[7]:=' '; fat32h.OemCode[8]:=' ';
  4.      fat32h.BytesPerSector:=blocksize;
  5.      fat32h.SectorPerCluster:=1;
  6.      fat32h.ReservedSectorCount:=32;
  7.      fat32h.NumFATs:=2;
  8.      fat32h.RootEntryCount:=0;
  9.      fat32h.TotalSector16:=0;
  10.      fat32h.Media:=$F8;
  11.      fat32h.FATSectors16:=0;
  12.      fat32h.SectorPerTrack:=32;
  13.      fat32h.NumHeads:=8;
  14.      fat32h.HiddenSectors:=0;
  15.      fat32h.TotalSectors32:=1024*256 div (blocksize div 512);
  16.      fat32h.FATSector32:=128 div (blocksize div 512);
  17.      fat32h.ExtendedFlags:=0;
  18.      fat32h.filesystemVersion:=0;
  19.      fat32h.RootCluster:=fat32h.FATSector32*2+fat32h.ReservedSectorCount;
  20.      fat32h.FileSystemInfo:=1;
  21.      fat32h.BootSector:=6;
  22.      for j:=1 to 12 do fat32h.Reserved[j]:=0;
  23.      fat32h.DriverNumber:=$80;
  24.      fat32h.Reserved1:=0;
  25.      fat32h.BootSignature:=$29;
  26.      fat32h.VolumeID:=$4067AD4D;
  27.      fat32h.VolumeLabel[1]:='E'; fat32h.VolumeLabel[2]:='F'; fat32h.VolumeLabel[3]:='I'; fat32h.VolumeLabel[4]:=' ';
  28.      fat32h.VolumeLabel[5]:='P'; fat32h.VolumeLabel[6]:='A'; fat32h.VolumeLabel[7]:='R'; fat32h.VolumeLabel[8]:='T';
  29.      fat32h.VolumeLabel[9]:=' '; fat32h.VolumeLabel[10]:=' '; fat32h.VolumeLabel[11]:=' ';
  30.      fat32h.FileSystemType[1]:='F'; fat32h.FileSystemType[2]:='A'; fat32h.FileSystemType[3]:='T';
  31.      fat32h.FileSystemType[4]:='3'; fat32h.FileSystemType[5]:='2'; fat32h.FileSystemType[6]:=' ';
  32.      fat32h.FileSystemType[7]:=' '; fat32h.FileSystemType[8]:=' ';
  33.      for j:=1 to 420 do fat32h.Reserved2[j]:=0;
  34.      fat32h.SignatureWord:=$AA55;
  35.      if(BlockSize>512) then for j:=1 to BlockSize-512 do fat32h.Reserved3[j]:=0;
  36.      fat32fs.FSI_leadsig:=$41615252;
  37.      for j:=1 to 480 do fat32fs.FSI_Reserved1[j]:=0;
  38.      fat32fs.FSI_StrucSig:=$61417272;
  39.      fat32fs.FSI_FreeCount:=1024*256 div (blocksize div 512)-fat32h.FATSector32*2-fat32h.ReservedSectorCount;
  40.      fat32fs.FSI_NextFree:=fat32h.FATSector32*2+fat32h.ReservedSectorCount;
  41.      for j:=1 to 12 do fat32fs.FSI_Reserved2[j]:=0;
  42.      fat32fs.FSI_TrailSig:=$AA550000;
  43.      if(BlockSize>512) then for j:=1 to BlockSize-512 do fat32fs.FSI_Reserved3[j]:=0;
  44.      diop^.WriteDisk(diop,mediaid,gpt.FirstUsableLBA*blocksize,blocksize,@fat32h);
  45.      diop^.WriteDisk(diop,mediaid,gpt.FirstUsableLBA*blocksize+blocksize,blocksize,@fat32fs);
  46.      diop^.WriteDisk(diop,mediaid,gpt.FirstUsableLBA*blocksize+blocksize*6,blocksize,@fat32h);
  47.      diop^.WriteDisk(diop,mediaid,gpt.FirstUsableLBA*blocksize+blocksize*7,blocksize,@fat32fs);
Does anyone have a solution to solve the bug(The fat32 records are not changed)?

bobby100

  • Sr. Member
  • ****
  • Posts: 301
    • Malzilla
Hi TYDQ,
I can't help with formatting the partition, but for creating directories etc. - you can take a look at this Delphi unit:
https://torry.net/components/files-and-drives/disk-access/raw-disk-access
I have used it in the past in the program MCShield (antivirus) (Windows XP/Vista/Win7) to read and write to SD Cards and flash drives, and your fat32_header record in the first post reminded me of it (some small differences with 0 or 1 for first array position).

Here is some code (Delphi) I was using to mess with autorun.inf files in root directory. Not really what you asked for, but maybe it can give you some ideas.
Code: Pascal  [Select][+][-]
  1. function TCoMCProcess.protectFAT(const drvName: WideString): Int64;
  2. var
  3.   bFAT: TFAT32BootRecord;
  4.   MID: TMediaIdentifier;
  5.   DSI: TDiskSizingInformation;
  6.   dirFat: array of TFAT32DirEntry;
  7.   rootDirSector: Integer;
  8.   RootContent: TMemoryStream;
  9.   buff: Byte;
  10.   FATStart: Int64;
  11.   FATSector: Int64;
  12.   FATSectorContent: TMemoryStream;
  13.   FATSectorEntry: Int64;
  14.   FATEntriesPerSector: Integer;
  15.   DataClusterRel: Int64;
  16.   DataClusterAbs: Int64;
  17.   tDrv: Char;
  18.   i, j: Integer;
  19.   dummyFile: TFileStream;
  20.   patchPos: Integer;
  21.   bFAT16: TFAT16BootRecord;
  22.   RootDirStart: Integer;
  23.   RootDirSize: Integer;
  24. begin
  25.   tDrv := Char(drvName[1]);
  26.   // Acquire the drive's info...
  27.   DSI := RDA.RDAFindDiskSizeInformation(tDrv + ':\');
  28.   MID := RDA.RDAGetMediaIdentifier(tDrv);
  29.   // FATxx filesystem...
  30.   if (AnsiContainsText(MID.FileSysType, 'FAT32')) then
  31.   begin
  32.     if RDA.RDAReadSectors((Ord(tDrv) - 64), 0, 1, @bFAT) then
  33.     begin
  34.       try
  35.         dummyFile := TFileStream.Create(drvName + 'autorun.inf',
  36.           fmCreate or fmOpenRead);
  37.         dummyFile.Free;
  38.       except
  39.         on e: Exception do
  40.           Result := 4;
  41.       end;
  42.       // find RootDir in DataClusters
  43.       rootDirSector := bFAT.ReservedSectors +
  44.         (bFAT.SectorsPerFat * bFAT.NumOfFatCopies);
  45.       SetLength(dirFat, (bFAT.BytesPerSec div 32));
  46.       FATEntriesPerSector := (bFAT.BytesPerSec div 32);
  47.       // Read RootDir in DataClusters   0-111
  48.       for i := 0 to bFAT.SecPerClust - 1 do
  49.         if RDA.RDAReadSectors((Ord(tDrv) - 64), rootDirSector + i, 1,
  50.           @dirFat[0]) then
  51.         begin
  52.           j := 1;
  53.           while j < (FATEntriesPerSector + 1) do
  54.           begin
  55.             if dirFat[j].fileName[1] = #0 then
  56.               Break;
  57.             if (Trim(dirFat[j].fileName) = 'AUTORUN') and
  58.               (Trim(dirFat[j].FileExt) = 'INF') then
  59.             begin
  60.               RootContent := TMemoryStream.Create;
  61.               RootContent.SetSize(DSI.SectorSize);
  62.               if RDA.RDAReadSectors((Ord(tDrv) - 64), rootDirSector + i, 1,
  63.                 RootContent.Memory) then
  64.               begin
  65.                 patchPos := (j * 32) + 11;
  66.                 RootContent.Position := patchPos;
  67.                 RootContent.Read(buff, 1);
  68.                 if buff = $20 then
  69.                 begin
  70.                   buff := $40;
  71.                   RootContent.Position := patchPos;
  72.                   RootContent.Write(buff, 1);
  73.                   if RDA.RDAWriteSectors((Ord(tDrv) - 64), rootDirSector + i, 1,
  74.                     RootContent.Memory) then
  75.                     Result := 0
  76.                   else
  77.                     Result := 1;
  78.                 end
  79.                 else if buff = $40 then
  80.                   Result := 2;
  81.               end;
  82.               RootContent.Free;
  83.             end;
  84.             Inc(j);
  85.           end;
  86.         end;
  87.       // find the FAT table
  88.       FATStart := bFAT.ReservedSectors;
  89.       FATSectorContent := TMemoryStream.Create;
  90.       FATSectorContent.SetSize(DSI.SectorSize);
  91.       FATSectorEntry := 2;
  92.       FATSector := FATStart;
  93.       // read FAT entry for RootDir
  94.       while DataClusterRel <= $0FFFFFF8 do
  95.       begin
  96.         if (RDA.RDAReadSectors((Ord(tDrv) - 64), FATSector, 1,
  97.           FATSectorContent.Memory)) then
  98.         begin
  99.           FATSectorContent.Position := FATSectorEntry * 4;
  100.           FATSectorContent.Read(DataClusterRel, SizeOf(Integer));
  101.           DataClusterRel := DataClusterRel - 2;
  102.           DataClusterAbs := rootDirSector + DataClusterRel * bFAT.SecPerClust;
  103.           for i := 0 to bFAT.SecPerClust - 1 do
  104.             if RDA.RDAReadSectors((Ord(tDrv) - 64), DataClusterAbs + i, 1,
  105.               @dirFat[0]) then
  106.             begin
  107.               j := 1;
  108.               while j < (FATEntriesPerSector + 1) do
  109.               begin
  110.                 if dirFat[j].fileName[1] = #0 then
  111.                   Break;
  112.                 if (Trim(dirFat[j].fileName) = 'AUTORUN') and
  113.                   (Trim(dirFat[j].FileExt) = 'INF') then
  114.                 begin
  115.                   RootContent := TMemoryStream.Create;
  116.                   RootContent.SetSize(DSI.SectorSize);
  117.                   if RDA.RDAReadSectors((Ord(tDrv) - 64), DataClusterAbs + i, 1,
  118.                     RootContent.Memory) then
  119.                   begin
  120.                     patchPos := (j * 32) + 11;
  121.                     RootContent.Position := patchPos;
  122.                     RootContent.Read(buff, 1);
  123.                     if buff = $20 then
  124.                     begin
  125.                       buff := $40;
  126.                       RootContent.Position := patchPos;
  127.                       RootContent.Write(buff, 1);
  128.                       if RDA.RDAWriteSectors((Ord(tDrv) - 64),
  129.                         DataClusterAbs + i, 1, RootContent.Memory) then
  130.                         Result := 0
  131.                       else
  132.                         Result := 1;
  133.                     end
  134.                     else if buff = $40 then
  135.                       Result := 2;
  136.                   end;
  137.                   RootContent.Free;
  138.                 end;
  139.                 Inc(j);
  140.               end;
  141.             end;
  142.         end;
  143.         // Next FAT entry
  144.         FATSectorEntry := DataClusterRel + 2;
  145.         // Calculate new FAT sector to read
  146.         FATSector := (FATStart + FATSectorEntry div 128);
  147.         FATSectorEntry := (FATSectorEntry mod 128);
  148.       end;
  149.       FATSectorContent.Free;
  150.     end;
  151.   end
  152.   else if (AnsiContainsText(MID.FileSysType, 'FAT')) then
  153.   begin
  154.     // Code for FAT12 and FAT16
  155.     if RDA.RDAReadSectors((Ord(tDrv) - 64), 0, 1, @bFAT16) then
  156.     begin
  157.       try
  158.         dummyFile := TFileStream.Create(drvName + 'autorun.inf',
  159.           fmCreate or fmOpenRead);
  160.         dummyFile.Free;
  161.       except
  162.         on e: Exception do
  163.           Result := 4;
  164.       end;
  165.       // Find RootDir
  166.       RootDirStart := bFAT16.ReservedSectors +
  167.         (bFAT16.NumOfFatCopies * bFAT16.SectorsPerFatOld);
  168.       RootDirSize := (bFAT16.MaxRootEntries * 32) div bFAT16.BytesPerSec;
  169.       SetLength(dirFat, (bFAT16.BytesPerSec div 32));
  170.       FATEntriesPerSector := (bFAT16.BytesPerSec div 32);
  171.       for j := 0 to RootDirSize - 1 do
  172.       begin
  173.         if RDA.RDAReadSectors((Ord(tDrv) - 64), RootDirStart + j, 1,
  174.           @dirFat[0]) then
  175.         begin
  176.           for i := 0 to FATEntriesPerSector - 1 do
  177.           begin
  178.             if dirFat[i].fileName[0] = #0 then
  179.               Break;
  180.             if (Trim(dirFat[i].fileName) = 'AUTORUN') and
  181.               (Trim(dirFat[i].FileExt) = 'INF') then
  182.             begin
  183.               RootContent := TMemoryStream.Create;
  184.               RootContent.SetSize(DSI.SectorSize);
  185.               if RDA.RDAReadSectors((Ord(tDrv) - 64), RootDirStart + j, 1,
  186.                 RootContent.Memory) then
  187.               begin
  188.                 patchPos := (i * 32) + 11;
  189.                 RootContent.Position := patchPos;
  190.                 RootContent.Read(buff, 1);
  191.                 if buff = $20 then
  192.                 begin
  193.                   buff := $40;
  194.                   RootContent.Position := patchPos;
  195.                   RootContent.Write(buff, 1);
  196.                   if RDA.RDAWriteSectors((Ord(tDrv) - 64), RootDirStart + j, 1,
  197.                     RootContent.Memory) then
  198.                     Result := 0
  199.                   else
  200.                     Result := 1;
  201.                 end
  202.                 else if buff = $40 then
  203.                   Result := 2;
  204.               end;
  205.               RootContent.Free;
  206.             end;
  207.           end;
  208.         end;
  209.       end;
  210.     end;
  211.   end
  212.   else
  213.     Result := 3;
  214. end;
  215.  

TYDQ

  • Full Member
  • ***
  • Posts: 139
Hi TYDQ,
I can't help with formatting the partition, but for creating directories etc. - you can take a look at this Delphi unit:
https://torry.net/components/files-and-drives/disk-access/raw-disk-access
I have used it in the past in the program MCShield (antivirus) (Windows XP/Vista/Win7) to read and write to SD Cards and flash drives, and your fat32_header record in the first post reminded me of it (some small differences with 0 or 1 for first array position).

Here is some code (Delphi) I was using to mess with autorun.inf files in root directory. Not really what you asked for, but maybe it can give you some ideas.
Code: Pascal  [Select][+][-]
  1. function TCoMCProcess.protectFAT(const drvName: WideString): Int64;
  2. var
  3.   bFAT: TFAT32BootRecord;
  4.   MID: TMediaIdentifier;
  5.   DSI: TDiskSizingInformation;
  6.   dirFat: array of TFAT32DirEntry;
  7.   rootDirSector: Integer;
  8.   RootContent: TMemoryStream;
  9.   buff: Byte;
  10.   FATStart: Int64;
  11.   FATSector: Int64;
  12.   FATSectorContent: TMemoryStream;
  13.   FATSectorEntry: Int64;
  14.   FATEntriesPerSector: Integer;
  15.   DataClusterRel: Int64;
  16.   DataClusterAbs: Int64;
  17.   tDrv: Char;
  18.   i, j: Integer;
  19.   dummyFile: TFileStream;
  20.   patchPos: Integer;
  21.   bFAT16: TFAT16BootRecord;
  22.   RootDirStart: Integer;
  23.   RootDirSize: Integer;
  24. begin
  25.   tDrv := Char(drvName[1]);
  26.   // Acquire the drive's info...
  27.   DSI := RDA.RDAFindDiskSizeInformation(tDrv + ':\');
  28.   MID := RDA.RDAGetMediaIdentifier(tDrv);
  29.   // FATxx filesystem...
  30.   if (AnsiContainsText(MID.FileSysType, 'FAT32')) then
  31.   begin
  32.     if RDA.RDAReadSectors((Ord(tDrv) - 64), 0, 1, @bFAT) then
  33.     begin
  34.       try
  35.         dummyFile := TFileStream.Create(drvName + 'autorun.inf',
  36.           fmCreate or fmOpenRead);
  37.         dummyFile.Free;
  38.       except
  39.         on e: Exception do
  40.           Result := 4;
  41.       end;
  42.       // find RootDir in DataClusters
  43.       rootDirSector := bFAT.ReservedSectors +
  44.         (bFAT.SectorsPerFat * bFAT.NumOfFatCopies);
  45.       SetLength(dirFat, (bFAT.BytesPerSec div 32));
  46.       FATEntriesPerSector := (bFAT.BytesPerSec div 32);
  47.       // Read RootDir in DataClusters   0-111
  48.       for i := 0 to bFAT.SecPerClust - 1 do
  49.         if RDA.RDAReadSectors((Ord(tDrv) - 64), rootDirSector + i, 1,
  50.           @dirFat[0]) then
  51.         begin
  52.           j := 1;
  53.           while j < (FATEntriesPerSector + 1) do
  54.           begin
  55.             if dirFat[j].fileName[1] = #0 then
  56.               Break;
  57.             if (Trim(dirFat[j].fileName) = 'AUTORUN') and
  58.               (Trim(dirFat[j].FileExt) = 'INF') then
  59.             begin
  60.               RootContent := TMemoryStream.Create;
  61.               RootContent.SetSize(DSI.SectorSize);
  62.               if RDA.RDAReadSectors((Ord(tDrv) - 64), rootDirSector + i, 1,
  63.                 RootContent.Memory) then
  64.               begin
  65.                 patchPos := (j * 32) + 11;
  66.                 RootContent.Position := patchPos;
  67.                 RootContent.Read(buff, 1);
  68.                 if buff = $20 then
  69.                 begin
  70.                   buff := $40;
  71.                   RootContent.Position := patchPos;
  72.                   RootContent.Write(buff, 1);
  73.                   if RDA.RDAWriteSectors((Ord(tDrv) - 64), rootDirSector + i, 1,
  74.                     RootContent.Memory) then
  75.                     Result := 0
  76.                   else
  77.                     Result := 1;
  78.                 end
  79.                 else if buff = $40 then
  80.                   Result := 2;
  81.               end;
  82.               RootContent.Free;
  83.             end;
  84.             Inc(j);
  85.           end;
  86.         end;
  87.       // find the FAT table
  88.       FATStart := bFAT.ReservedSectors;
  89.       FATSectorContent := TMemoryStream.Create;
  90.       FATSectorContent.SetSize(DSI.SectorSize);
  91.       FATSectorEntry := 2;
  92.       FATSector := FATStart;
  93.       // read FAT entry for RootDir
  94.       while DataClusterRel <= $0FFFFFF8 do
  95.       begin
  96.         if (RDA.RDAReadSectors((Ord(tDrv) - 64), FATSector, 1,
  97.           FATSectorContent.Memory)) then
  98.         begin
  99.           FATSectorContent.Position := FATSectorEntry * 4;
  100.           FATSectorContent.Read(DataClusterRel, SizeOf(Integer));
  101.           DataClusterRel := DataClusterRel - 2;
  102.           DataClusterAbs := rootDirSector + DataClusterRel * bFAT.SecPerClust;
  103.           for i := 0 to bFAT.SecPerClust - 1 do
  104.             if RDA.RDAReadSectors((Ord(tDrv) - 64), DataClusterAbs + i, 1,
  105.               @dirFat[0]) then
  106.             begin
  107.               j := 1;
  108.               while j < (FATEntriesPerSector + 1) do
  109.               begin
  110.                 if dirFat[j].fileName[1] = #0 then
  111.                   Break;
  112.                 if (Trim(dirFat[j].fileName) = 'AUTORUN') and
  113.                   (Trim(dirFat[j].FileExt) = 'INF') then
  114.                 begin
  115.                   RootContent := TMemoryStream.Create;
  116.                   RootContent.SetSize(DSI.SectorSize);
  117.                   if RDA.RDAReadSectors((Ord(tDrv) - 64), DataClusterAbs + i, 1,
  118.                     RootContent.Memory) then
  119.                   begin
  120.                     patchPos := (j * 32) + 11;
  121.                     RootContent.Position := patchPos;
  122.                     RootContent.Read(buff, 1);
  123.                     if buff = $20 then
  124.                     begin
  125.                       buff := $40;
  126.                       RootContent.Position := patchPos;
  127.                       RootContent.Write(buff, 1);
  128.                       if RDA.RDAWriteSectors((Ord(tDrv) - 64),
  129.                         DataClusterAbs + i, 1, RootContent.Memory) then
  130.                         Result := 0
  131.                       else
  132.                         Result := 1;
  133.                     end
  134.                     else if buff = $40 then
  135.                       Result := 2;
  136.                   end;
  137.                   RootContent.Free;
  138.                 end;
  139.                 Inc(j);
  140.               end;
  141.             end;
  142.         end;
  143.         // Next FAT entry
  144.         FATSectorEntry := DataClusterRel + 2;
  145.         // Calculate new FAT sector to read
  146.         FATSector := (FATStart + FATSectorEntry div 128);
  147.         FATSectorEntry := (FATSectorEntry mod 128);
  148.       end;
  149.       FATSectorContent.Free;
  150.     end;
  151.   end
  152.   else if (AnsiContainsText(MID.FileSysType, 'FAT')) then
  153.   begin
  154.     // Code for FAT12 and FAT16
  155.     if RDA.RDAReadSectors((Ord(tDrv) - 64), 0, 1, @bFAT16) then
  156.     begin
  157.       try
  158.         dummyFile := TFileStream.Create(drvName + 'autorun.inf',
  159.           fmCreate or fmOpenRead);
  160.         dummyFile.Free;
  161.       except
  162.         on e: Exception do
  163.           Result := 4;
  164.       end;
  165.       // Find RootDir
  166.       RootDirStart := bFAT16.ReservedSectors +
  167.         (bFAT16.NumOfFatCopies * bFAT16.SectorsPerFatOld);
  168.       RootDirSize := (bFAT16.MaxRootEntries * 32) div bFAT16.BytesPerSec;
  169.       SetLength(dirFat, (bFAT16.BytesPerSec div 32));
  170.       FATEntriesPerSector := (bFAT16.BytesPerSec div 32);
  171.       for j := 0 to RootDirSize - 1 do
  172.       begin
  173.         if RDA.RDAReadSectors((Ord(tDrv) - 64), RootDirStart + j, 1,
  174.           @dirFat[0]) then
  175.         begin
  176.           for i := 0 to FATEntriesPerSector - 1 do
  177.           begin
  178.             if dirFat[i].fileName[0] = #0 then
  179.               Break;
  180.             if (Trim(dirFat[i].fileName) = 'AUTORUN') and
  181.               (Trim(dirFat[i].FileExt) = 'INF') then
  182.             begin
  183.               RootContent := TMemoryStream.Create;
  184.               RootContent.SetSize(DSI.SectorSize);
  185.               if RDA.RDAReadSectors((Ord(tDrv) - 64), RootDirStart + j, 1,
  186.                 RootContent.Memory) then
  187.               begin
  188.                 patchPos := (i * 32) + 11;
  189.                 RootContent.Position := patchPos;
  190.                 RootContent.Read(buff, 1);
  191.                 if buff = $20 then
  192.                 begin
  193.                   buff := $40;
  194.                   RootContent.Position := patchPos;
  195.                   RootContent.Write(buff, 1);
  196.                   if RDA.RDAWriteSectors((Ord(tDrv) - 64), RootDirStart + j, 1,
  197.                     RootContent.Memory) then
  198.                     Result := 0
  199.                   else
  200.                     Result := 1;
  201.                 end
  202.                 else if buff = $40 then
  203.                   Result := 2;
  204.               end;
  205.               RootContent.Free;
  206.             end;
  207.           end;
  208.         end;
  209.       end;
  210.     end;
  211.   end
  212.   else
  213.     Result := 3;
  214. end;
  215.  
I have been solved this problem by referring to Microsoft efi specification for file allocation table 32,Thank you.

 

TinyPortal © 2005-2018