function TCoMCProcess.protectFAT(const drvName: WideString): Int64;
var
bFAT: TFAT32BootRecord;
MID: TMediaIdentifier;
DSI: TDiskSizingInformation;
dirFat: array of TFAT32DirEntry;
rootDirSector: Integer;
RootContent: TMemoryStream;
buff: Byte;
FATStart: Int64;
FATSector: Int64;
FATSectorContent: TMemoryStream;
FATSectorEntry: Int64;
FATEntriesPerSector: Integer;
DataClusterRel: Int64;
DataClusterAbs: Int64;
tDrv: Char;
i, j: Integer;
dummyFile: TFileStream;
patchPos: Integer;
bFAT16: TFAT16BootRecord;
RootDirStart: Integer;
RootDirSize: Integer;
begin
tDrv := Char(drvName[1]);
// Acquire the drive's info...
DSI := RDA.RDAFindDiskSizeInformation(tDrv + ':\');
MID := RDA.RDAGetMediaIdentifier(tDrv);
// FATxx filesystem...
if (AnsiContainsText(MID.FileSysType, 'FAT32')) then
begin
if RDA.RDAReadSectors((Ord(tDrv) - 64), 0, 1, @bFAT) then
begin
try
dummyFile := TFileStream.Create(drvName + 'autorun.inf',
fmCreate or fmOpenRead);
dummyFile.Free;
except
on e: Exception do
Result := 4;
end;
// find RootDir in DataClusters
rootDirSector := bFAT.ReservedSectors +
(bFAT.SectorsPerFat * bFAT.NumOfFatCopies);
SetLength(dirFat, (bFAT.BytesPerSec div 32));
FATEntriesPerSector := (bFAT.BytesPerSec div 32);
// Read RootDir in DataClusters 0-111
for i := 0 to bFAT.SecPerClust - 1 do
if RDA.RDAReadSectors((Ord(tDrv) - 64), rootDirSector + i, 1,
@dirFat[0]) then
begin
j := 1;
while j < (FATEntriesPerSector + 1) do
begin
if dirFat[j].fileName[1] = #0 then
Break;
if (Trim(dirFat[j].fileName) = 'AUTORUN') and
(Trim(dirFat[j].FileExt) = 'INF') then
begin
RootContent := TMemoryStream.Create;
RootContent.SetSize(DSI.SectorSize);
if RDA.RDAReadSectors((Ord(tDrv) - 64), rootDirSector + i, 1,
RootContent.Memory) then
begin
patchPos := (j * 32) + 11;
RootContent.Position := patchPos;
RootContent.Read(buff, 1);
if buff = $20 then
begin
buff := $40;
RootContent.Position := patchPos;
RootContent.Write(buff, 1);
if RDA.RDAWriteSectors((Ord(tDrv) - 64), rootDirSector + i, 1,
RootContent.Memory) then
Result := 0
else
Result := 1;
end
else if buff = $40 then
Result := 2;
end;
RootContent.Free;
end;
Inc(j);
end;
end;
// find the FAT table
FATStart := bFAT.ReservedSectors;
FATSectorContent := TMemoryStream.Create;
FATSectorContent.SetSize(DSI.SectorSize);
FATSectorEntry := 2;
FATSector := FATStart;
// read FAT entry for RootDir
while DataClusterRel <= $0FFFFFF8 do
begin
if (RDA.RDAReadSectors((Ord(tDrv) - 64), FATSector, 1,
FATSectorContent.Memory)) then
begin
FATSectorContent.Position := FATSectorEntry * 4;
FATSectorContent.Read(DataClusterRel, SizeOf(Integer));
DataClusterRel := DataClusterRel - 2;
DataClusterAbs := rootDirSector + DataClusterRel * bFAT.SecPerClust;
for i := 0 to bFAT.SecPerClust - 1 do
if RDA.RDAReadSectors((Ord(tDrv) - 64), DataClusterAbs + i, 1,
@dirFat[0]) then
begin
j := 1;
while j < (FATEntriesPerSector + 1) do
begin
if dirFat[j].fileName[1] = #0 then
Break;
if (Trim(dirFat[j].fileName) = 'AUTORUN') and
(Trim(dirFat[j].FileExt) = 'INF') then
begin
RootContent := TMemoryStream.Create;
RootContent.SetSize(DSI.SectorSize);
if RDA.RDAReadSectors((Ord(tDrv) - 64), DataClusterAbs + i, 1,
RootContent.Memory) then
begin
patchPos := (j * 32) + 11;
RootContent.Position := patchPos;
RootContent.Read(buff, 1);
if buff = $20 then
begin
buff := $40;
RootContent.Position := patchPos;
RootContent.Write(buff, 1);
if RDA.RDAWriteSectors((Ord(tDrv) - 64),
DataClusterAbs + i, 1, RootContent.Memory) then
Result := 0
else
Result := 1;
end
else if buff = $40 then
Result := 2;
end;
RootContent.Free;
end;
Inc(j);
end;
end;
end;
// Next FAT entry
FATSectorEntry := DataClusterRel + 2;
// Calculate new FAT sector to read
FATSector := (FATStart + FATSectorEntry div 128);
FATSectorEntry := (FATSectorEntry mod 128);
end;
FATSectorContent.Free;
end;
end
else if (AnsiContainsText(MID.FileSysType, 'FAT')) then
begin
// Code for FAT12 and FAT16
if RDA.RDAReadSectors((Ord(tDrv) - 64), 0, 1, @bFAT16) then
begin
try
dummyFile := TFileStream.Create(drvName + 'autorun.inf',
fmCreate or fmOpenRead);
dummyFile.Free;
except
on e: Exception do
Result := 4;
end;
// Find RootDir
RootDirStart := bFAT16.ReservedSectors +
(bFAT16.NumOfFatCopies * bFAT16.SectorsPerFatOld);
RootDirSize := (bFAT16.MaxRootEntries * 32) div bFAT16.BytesPerSec;
SetLength(dirFat, (bFAT16.BytesPerSec div 32));
FATEntriesPerSector := (bFAT16.BytesPerSec div 32);
for j := 0 to RootDirSize - 1 do
begin
if RDA.RDAReadSectors((Ord(tDrv) - 64), RootDirStart + j, 1,
@dirFat[0]) then
begin
for i := 0 to FATEntriesPerSector - 1 do
begin
if dirFat[i].fileName[0] = #0 then
Break;
if (Trim(dirFat[i].fileName) = 'AUTORUN') and
(Trim(dirFat[i].FileExt) = 'INF') then
begin
RootContent := TMemoryStream.Create;
RootContent.SetSize(DSI.SectorSize);
if RDA.RDAReadSectors((Ord(tDrv) - 64), RootDirStart + j, 1,
RootContent.Memory) then
begin
patchPos := (i * 32) + 11;
RootContent.Position := patchPos;
RootContent.Read(buff, 1);
if buff = $20 then
begin
buff := $40;
RootContent.Position := patchPos;
RootContent.Write(buff, 1);
if RDA.RDAWriteSectors((Ord(tDrv) - 64), RootDirStart + j, 1,
RootContent.Memory) then
Result := 0
else
Result := 1;
end
else if buff = $40 then
Result := 2;
end;
RootContent.Free;
end;
end;
end;
end;
end;
end
else
Result := 3;
end;