📄 diskio.pas
字号:
P := Longint(F.Memory);
L1 := StartSector;
if VolumeLock(lLogical) then
begin
Result := True;
while L>MaxSize do
begin
Transfer.StartSector := L1;
Transfer.SectorCount := 100;
Transfer.Buffer := P;
R.ESI := 0;
R.EDX := FVolume;
R.ECX := $FFFFFFFF;
R.EBX := Longint(@Transfer);
R.EAX := $7305;
L1 := L1+100;
L := L-MaxSize;
P := P+MaxSize;
IOCTL(VWIN32_DIOC_DOS_DRIVEINFO, R);
Result := Result and (not Odd(R.Flags));
end;
Transfer.StartSector := L1;
Transfer.SectorCount := L div FBytesPerSector;
Transfer.Buffer := P;
R.ESI := 0;
R.EDX := FVolume;
R.ECX := $FFFFFFFF;
R.EBX := Longint(@Transfer);
R.EAX := $7305;
IOCTL(VWIN32_DIOC_DOS_DRIVEINFO, R);
Result := Result and (not Odd(R.Flags));
VolumeUnlock(lLogical);
end;
F.Seek(0, 0);
if nSize > F.Size then F.Read(Buffer, F.Size)
else F.Read(Buffer, nSize);
F.Free;
end;
function TDiskIO.ReadLogicalSector(StartSector, nSectors: Longint; var Buffer; nSize: Longint): Boolean;
var R: T32Regs;
L, L1: Longint;
MaxSize: Longint;
P: Longint;
W: TWin95;
begin
FillChar(Buffer, nSize, 0);
Result := False;
if (FHandle = 0) or (FVolume = 0) then Exit;
W := CheckWindows95;
if W = NoWin95 then Exit;
if W = OSR2 then
begin
Result := ReadLogicalSectorEx(StartSector, nSectors, Buffer, nSize);
if Result then Exit;
end;
if StartSector>=FLogicalSectors-1 then StartSector := FLogicalSectors-1;
if StartSector+nSectors>FLogicalSectors then nSectors := FLogicalSectors-StartSector;
MaxSize := FBytesPerSector*100;
F := TMemoryStream.Create;
F.SetSize(nSectors*FBytesPerSector);
L := F.Size;
P := Longint(F.Memory);
L1 := StartSector;
if VolumeLock(lLogical) then
begin
Result := True;
while L>MaxSize do
begin
Transfer.StartSector := L1;
Transfer.SectorCount := 100;
Transfer.Buffer := P;
R.EAX := FVolume-1;
R.ECX := $FFFFFFFF;
R.EBX := Longint(@Transfer);
L1 := L1+100;
L := L-MaxSize;
P := P+MaxSize;
IOCTL(VWIN32_DIOC_DOS_INT25, R);
Result := Result and (not Odd(R.Flags));
end;
Transfer.StartSector := L1;
Transfer.SectorCount := L div FBytesPerSector;
Transfer.Buffer := P;
R.EAX := FVolume-1;
R.ECX := $FFFFFFFF;
R.EBX := Longint(@Transfer);
IOCTL(VWIN32_DIOC_DOS_INT25, R);
Result := Result and (not Odd(R.Flags));
VolumeUnlock(lLogical);
end;
F.Seek(0, 0);
if nSize > F.Size then F.Read(Buffer, F.Size)
else F.Read(Buffer, nSize);
F.Free;
end;
function TDiskIO.WriteLogicalSectorEx(StartSector, nSectors: Longint; var Buffer; nSize: Longint): Boolean;
var R: T32Regs;
L, L1: Longint;
MaxSize: Longint;
P: Longint;
begin
Result := False;
if StartSector>=FLogicalSectors-1 then StartSector := FLogicalSectors-1;
if StartSector+nSectors>FLogicalSectors then nSectors := FLogicalSectors-StartSector;
MaxSize := FBytesPerSector*100;
F := TMemoryStream.Create;
F.SetSize(nSectors*FBytesPerSector);
F.Seek(0, 0);
F.Write(Buffer, F.Size);
L := F.Size;
P := Longint(F.Memory);
L1 := StartSector;
if VolumeLock(lLogical) then
begin
Result := True;
while L>MaxSize do
begin
Transfer.StartSector := L1;
Transfer.SectorCount := 100;
Transfer.Buffer := P;
R.ESI := $6001;
R.EDX := FVolume;
R.ECX := $FFFFFFFF;
R.EBX := Longint(@Transfer);
R.EAX := $7305;
L1 := L1+100;
L := L-MaxSize;
P := P+MaxSize;
IOCTL(VWIN32_DIOC_DOS_DRIVEINFO, R);
Result := Result and (not Odd(R.Flags));
end;
Transfer.StartSector := L1;
Transfer.SectorCount := L div FBytesPerSector;
Transfer.Buffer := P;
R.ESI := 1;
R.EDX := FVolume;
R.ECX := $FFFFFFFF;
R.EBX := Longint(@Transfer);
R.EAX := $7305;
IOCTL(VWIN32_DIOC_DOS_DRIVEINFO, R);
Result := Result and (not Odd(R.Flags));
VolumeUnlock(lLogical);
end;
F.Seek(0, 0);
if nSize > F.Size then F.Read(Buffer, F.Size)
else F.Read(Buffer, nSize);
F.Free;
end;
function TDiskIO.WriteLogicalSector(StartSector, nSectors: Longint; var Buffer; nSize: Longint): Boolean;
var R: T32Regs;
L, L1: Longint;
MaxSize: Longint;
P: Longint;
W: TWin95;
begin
Result := False;
if (FHandle = 0) or (FVolume = 0) then Exit;
W := CheckWindows95;
if W = NoWin95 then Exit;
if W = OSR2 then
begin
Result := WriteLogicalSectorEx(StartSector, nSectors, Buffer, nSize);
if Result then Exit;
end;
if StartSector>=FLogicalSectors-1 then StartSector := FLogicalSectors-1;
if StartSector+nSectors>FLogicalSectors then nSectors := FLogicalSectors-StartSector;
MaxSize := FBytesPerSector*100;
F := TMemoryStream.Create;
F.SetSize(nSectors*FBytesPerSector);
F.Seek(0, 0);
F.Write(Buffer, F.Size);
L := F.Size;
P := Longint(F.Memory);
L1 := StartSector;
if VolumeLock(lLogical) then
begin
Result := True;
while L>MaxSize do
begin
Transfer.StartSector := L1;
Transfer.SectorCount := 100;
Transfer.Buffer := P;
R.EAX := FVolume-1;
R.ECX := $FFFFFFFF;
R.EBX := Longint(@Transfer);
L1 := L1+100;
L := L-MaxSize;
P := P+MaxSize;
IOCTL(VWIN32_DIOC_DOS_INT26, R);
Result := Result and (not Odd(R.Flags));
end;
Transfer.StartSector := L1;
Transfer.SectorCount := L div FBytesPerSector;
Transfer.Buffer := P;
R.EAX := FVolume-1;
R.ECX := $FFFFFFFF;
R.EBX := Longint(@Transfer);
IOCTL(VWIN32_DIOC_DOS_INT26, R);
Result := Result and (not Odd(R.Flags));
VolumeUnlock(lLogical);
end;
F.Free;
end;
procedure TDiskIO.CheckFileSystem;
var P, P1, P2: Pointer;
I, J: Longint;
szFSType: String;
B1, B2: Byte;
W: Word;
L: Longint;
begin
GetMem(P, FBytesPerSector);
if not ReadLogicalSector(0, 1, P^, FBytesPerSector) then
begin
FreeMem(P);
Exit;
end;
if PBOOTSect(P)^.bsFATsecs = 0 then FFileSystem := fsFAT32;
if FFileSystem = fsFAT32 then
begin
FSerial := PBootSect32(P)^.bsVolumeID;
SetLength(FLabel, 11);
for I := 1 to 11 do FLabel[I] := PBootSect32(P)^.bsVolumeLabel[I];
try
while (Length(FLabel)<>0) and (FLabel[Length(FLabel)]=' ') do
Delete(FLabel, Length(FLabel), 1);
except
on Exception do;
end;
FSectorsPerCluster := PBootSect32(P)^.bpb.A_BF_BPB_SectorsPerCluster;
FFATCount := PBootSect32(P)^.bpb.A_BF_BPB_NumberOfFATs;
GetMem(FFATSector, FFATCount*4);
I := PBootSect32(P)^.bpb.A_BF_BPB_ReservedSectors;
Longint(FFATSector^) := I;
FSectorsPerFAT := PBootSect32(P)^.bpb.A_BF_BPB_BigSectorsPerFatHi;
FSectorsPerFAT := (FSectorsPerFAT shl 16)+PBootSect32(P)^.bpb.A_BF_BPB_BigSectorsPerFat;
P1 := FFATSector;
Inc(Longint(P1), 4);
if FFATCount>1 then
for J := 2 to FFATCount do
begin
I := I+FSectorsPerFAT;
Longint(P1^) := I;
Inc(Longint(P1), 4);
end;
FRootDirCluster := PBootSect32(P)^.bpb.A_BF_BPB_RootDirStrtClusHi;
FRootDirCluster := (FRootDirCluster shl 16)+PBootSect32(P)^.bpb.A_BF_BPB_RootDirStrtClus;
FRootDirSector := PBootSect32(P)^.bpb.A_BF_BPB_ReservedSectors+FFATCount*FSectorsPerFAT;
FRootDirSector := FRootDirSector+(FRootDirCluster-2)*FSectorsPerCluster;
FCluster2Sector := FRootDirSector;
end else
begin
FSerial := PBootSect(P)^.bsVolumeID;
SetLength(FLabel, 11);
for I := 1 to 11 do FLabel[I] := PBootSect(P)^.bsVolumeLabel[I];
try
while (Length(FLabel)<>0) and (FLabel[Length(FLabel)]=' ') do
Delete(FLabel, Length(FLabel), 1);
except
on Exception do;
end;
SetLength(szFSType, 8);
FillChar(szFSType[1], 8, 0);
Move(PBootSect(P)^.bsFileSysType, szFSType[1], 8);
try
while (Length(szFSType) <> 0) and (szFSType[Length(szFSType)] = ' ') do
Delete(szFSType, Length(szFSType), 1);
except
on Exception do;
end;
if strcomp(PChar(szFSType), 'FAT12') = 0 then FFileSystem := fsFAT12 else
if strcomp(PChar(szFSType), 'FAT16') = 0 then FFileSystem := fsFAT16;
FSectorsPerCluster := PBootSect(P)^.bsSecPerClust;
FFATCount := PBootSect(P)^.bsFATs;
GetMem(FFATSector, FFATCount*4);
FSectorsPerFAT := PBootSect(P)^.bsFATsecs;
I := PBootSect(P)^.bsResSectors;
Longint(FFATSector^) := I;
P1 := FFATSector;
Inc(Longint(P1), 4);
if FFATCount>1 then
for J := 2 to FFATCount do
begin
I := I+FSectorsPerFAT;
Longint(P1^) := I;
Inc(Longint(P1), 4);
end;
FRootDirEntries := PBootSect(P)^.bsRootDirEnts;
FRootDirSector := PBootSect(P)^.bsResSectors+FSectorsPerFAT*FFATCount;
FRootDirCluster := 1;
FCluster2Sector := FRootDirSector+((FRootDirEntries*32+FBytesPerSector-1) div FBytesPerSector);
end;
FLabel := UpperCase(FLabel);
FEndingCluster := ((FLogicalSectors-FCluster2Sector) div FSectorsPerCluster)+1;
FreeMem(P);
if FFileSystem = fsNone then Exit;
{Read FAT}
GetMem(P, FSectorsPerFAT*FFATCount*FBytesPerSector);
if not ReadLogicalSector(FATSector[1], FSectorsPerFAT*FFATCount, P^, FBytesPerSector*FSectorsPerFAT*FFATCount) then
begin
FreeMem(P);
Exit;
end;
FFATSize := FEndingCluster-1;
GetMem(FFAT, FFATSize*FFATCount*4);
FillChar(FFAT^, FFATSize*FFATCount*4, 0);
P2 := FFAT;
if FFileSystem = fsFAT12 then
begin
for J := 0 to FFATCount-1 do
begin
P1 := Pointer(Longint(P)+J*FSectorsPerFAT*FBytesPerSector+3);
for I := 1 to FFATSize div 2 do
begin
B1 := Byte(P1^); Inc(Longint(P1));
B2 := Byte(P1^) and $0F;
W := B2; W := (W shl 8) or B1;
L := W;
Longint(P2^) := L and FAT_MASK_12;
Inc(Longint(P2), 4);
B1 := Byte(P1^) and $F0; Inc(Longint(P1));
B2 := Byte(P1^); Inc(Longint(P1));
W := B2; W := (W shl 4) or (B1 shr 4);
L := W;
Longint(P2^) := L and FAT_MASK_12;
Inc(Longint(P2), 4);
end;
if Odd(FFATSize) then
begin
B1 := Byte(P1^); Inc(Longint(P1));
B2 := Byte(P1^) and $0F;
W := B2; W := (W shl 8) or B1;
L := W;
Longint(P2^) := L and FAT_MASK_12;
end;
end;
end else
if FFileSystem = fsFAT16 then
begin
for J := 0 to FFATCount-1 do
begin
P1 := Pointer(Longint(P)+J*FSectorsPerFAT*FBytesPerSector+4);
for I := 1 to FFATSize do
begin
L := Word(P1^); Inc(Longint(P1), 2);
Longint(P2^) := L and FAT_MASK_16;
Inc(Longint(P2), 4);
end;
end;
end else
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -