📄 diskio.pas
字号:
Result := False;
if FHandle = 0 then Exit;
if FVolume = 0 then Exit;
R.EAX := $440d; // IOCTL for block device
R.EBX := FVolume; // one-based drive number
R.ECX := $0866; // Get Media ID
R.EDX := Longint(Mid);
R.Flags := 1; // preset the carry flag
if not DeviceIoControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL) then Exit;
if (R.Flags and 1) <> 0 then Exit;
Result := True;
end;
const DRIVE_IS_SUBST = $8000;
procedure TDiskIO.DriveReread;
var P: Pointer;
R: T32Regs;
cb: DWord;
W: TWin95;
begin
if FHandle = 0 then Exit;
if FVolume = 0 then Exit;
W := CheckWindows95;
if W = NoWin95 then Exit;
FSectorsPerCluster := 0;
FSectorsPerFAT := 0;
FFATSize := 0;
if FFAT <> NIL then FreeMem(FFAT);
FFAT := NIL;
if FFATSector <> NIL then FreeMem(FFATSector);
FFATSector := NIL;
FFATCount := 0;
FRootDirCluster := 0;
FSerial := 0;
FLabel := '';
FRootDirSector := 0;
FSectorsPerFAT := 0;
FRootDirEntries := 0;
FEndingCluster := 0;
FCluster2Sector := 0;
FFileSystem := fsNone;
if W = OSR2 then
begin
GetMem(P, SizeOf(TExt_DeviceParams));
R.EBX := FVolume;
R.ECX := $4860;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
R.EBX := FVolume;
R.ECX := $860;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
FVolume := 0;
FPhysicalVolume := -1;
FLogicalSectors := 0;
FPhysicalSectors := 0;
FHeads := 0;
FCylinders := 0;
FBytesPerSector := 0;
FreeMem(P, SizeOf(TExt_DeviceParams));
Exit;
end;
end;
FLogicalSectors := PExt_DeviceParams(P)^.dpBPB.bpbBigTotalSectors;
FBytesPerSector := PExt_DeviceParams(P)^.dpBPB.bpbSectorSize;
FHeads := PExt_DeviceParams(P)^.dpBPB.bpbHeads;
FCylinders := PExt_DeviceParams(P)^.dpNumberOfCylinders;
FPhysicalSectors := PExt_DeviceParams(P)^.dpBPB.bpbSectorsPerTrack;
FreeMem(P, SizeOf(TExt_DeviceParams));
CheckFileSystem;
GetMem(P, SizeOf(TDriveMapInfo));
R.EBX := FVolume;
R.ECX := $486F;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
R.EBX := FVolume;
R.ECX := $86F;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
FPhysicalVolume := -1;
FPhysicalSectors := 0;
FHeads := 0;
FCylinders := 0;
FreeMem(P, SizeOf(TDriveMapInfo));
Exit;
end;
end;
FPhysicalVolume := PDriveMapInfo(P)^.dmiInt13Unit;
FreeMem(P, SizeOf(TDriveMapInfo));
end else
begin
GetMem(P, SizeOf(TDeviceParams));
R.EBX := FVolume;
R.ECX := $860;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
FVolume := 0;
FPhysicalVolume := -1;
FLogicalSectors := 0;
FPhysicalSectors := 0;
FHeads := 0;
FCylinders := 0;
FBytesPerSector := 0;
FreeMem(P, SizeOf(TDeviceParams));
Exit;
end;
if PDeviceParams(P)^.dpBPB.bpbTotalSectors = 0 then
FLogicalSectors := PDeviceParams(P)^.dpBPB.bpbBigTotalSectors else
FLogicalSectors := PDeviceParams(P)^.dpBPB.bpbTotalSectors;
FBytesPerSector := PDeviceParams(P)^.dpBPB.bpbSectorSize;
FHeads := PDeviceParams(P)^.dpBPB.bpbHeads;
FCylinders := PDeviceParams(P)^.dpNumberOfCylinders;
FPhysicalSectors := PDeviceParams(P)^.dpBPB.bpbSectorsPerTrack;
FreeMem(P, SizeOf(TDeviceParams));
CheckFileSystem;
GetMem(P, SizeOf(TDriveMapInfo));
R.EBX := FVolume;
R.ECX := $86F;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
FPhysicalVolume := -1;
FPhysicalSectors := 0;
FHeads := 0;
FCylinders := 0;
FreeMem(P, SizeOf(TDriveMapInfo));
Exit;
end;
FPhysicalVolume := PDriveMapInfo(P)^.dmiInt13Unit;
FreeMem(P, SizeOf(TDriveMapInfo));
end;
end;
procedure TDiskIO.SetDrive(Value: Char);
var S: String;
P: Pointer;
R: T32Regs;
cb: DWord;
W: TWin95;
V: Longint;
Flags: Longint;
MID: TMID;
AMID: TPASMID;
begin
if FHandle = 0 then Exit;
S := Value;
S := UpperCase(S);
W := CheckWindows95;
if W = NoWin95 then Exit;
V := FVolume;
FVolume := Byte(S[1])-$40;
if V=FVolume then Exit;
if not VolumeCheck(Flags) then
begin
FVolume := V;
Exit;
end;
if (Flags and DRIVE_IS_SUBST) <> 0 then
begin
FVolume := V;
Exit;
end;
if not GetMediaID(@MID) then
begin
FVolume := V;
Exit;
end;
TMID2TPASMID(MID, AMID);
if (AMID.midFileSysType = 'CDROM') or (AMID.midFileSysType = 'CD001') or
(AMID.midFileSysType = 'CDAUDIO') then
begin
FVolume := V;
Exit;
end;
FSectorsPerCluster := 0;
FSectorsPerFAT := 0;
FFATSize := 0;
if FFAT <> NIL then FreeMem(FFAT);
FFAT := NIL;
if FFATSector <> NIL then FreeMem(FFATSector);
FFATSector := NIL;
FFATCount := 0;
FRootDirCluster := 0;
FSerial := 0;
FLabel := '';
FRootDirSector := 0;
FSectorsPerFAT := 0;
FRootDirEntries := 0;
FEndingCluster := 0;
FCluster2Sector := 0;
FFileSystem := fsNone;
if W = OSR2 then
begin
GetMem(P, SizeOf(TExt_DeviceParams));
R.EBX := FVolume;
R.ECX := $4860;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
R.EBX := FVolume;
R.ECX := $860;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
FVolume := 0;
FPhysicalVolume := -1;
FLogicalSectors := 0;
FPhysicalSectors := 0;
FHeads := 0;
FCylinders := 0;
FBytesPerSector := 0;
FreeMem(P, SizeOf(TExt_DeviceParams));
Exit;
end;
end;
FLogicalSectors := PExt_DeviceParams(P)^.dpBPB.bpbBigTotalSectors;
FBytesPerSector := PExt_DeviceParams(P)^.dpBPB.bpbSectorSize;
FHeads := PExt_DeviceParams(P)^.dpBPB.bpbHeads;
FCylinders := PExt_DeviceParams(P)^.dpNumberOfCylinders;
FPhysicalSectors := PExt_DeviceParams(P)^.dpBPB.bpbSectorsPerTrack;
FreeMem(P, SizeOf(TExt_DeviceParams));
CheckFileSystem;
GetMem(P, SizeOf(TDriveMapInfo));
R.EBX := FVolume;
R.ECX := $486F;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
R.EBX := FVolume;
R.ECX := $86F;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
FPhysicalVolume := -1;
FPhysicalSectors := 0;
FHeads := 0;
FCylinders := 0;
FreeMem(P, SizeOf(TDriveMapInfo));
Exit;
end;
end;
FPhysicalVolume := PDriveMapInfo(P)^.dmiInt13Unit;
FreeMem(P, SizeOf(TDriveMapInfo));
end else
begin
GetMem(P, SizeOf(TDeviceParams));
R.EBX := FVolume;
R.ECX := $860;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
FVolume := 0;
FPhysicalVolume := -1;
FLogicalSectors := 0;
FPhysicalSectors := 0;
FHeads := 0;
FCylinders := 0;
FBytesPerSector := 0;
FreeMem(P, SizeOf(TDeviceParams));
Exit;
end;
if PDeviceParams(P)^.dpBPB.bpbTotalSectors = 0 then
FLogicalSectors := PDeviceParams(P)^.dpBPB.bpbBigTotalSectors else
FLogicalSectors := PDeviceParams(P)^.dpBPB.bpbTotalSectors;
FBytesPerSector := PDeviceParams(P)^.dpBPB.bpbSectorSize;
FHeads := PDeviceParams(P)^.dpBPB.bpbHeads;
FCylinders := PDeviceParams(P)^.dpNumberOfCylinders;
FPhysicalSectors := PDeviceParams(P)^.dpBPB.bpbSectorsPerTrack;
FreeMem(P, SizeOf(TDeviceParams));
CheckFileSystem;
GetMem(P, SizeOf(TDriveMapInfo));
R.EBX := FVolume;
R.ECX := $86F;
R.EDX := Longint(P);
R.EAX := $440D;
DeviceIOControl(FHandle, VWIN32_DIOC_DOS_IOCTL,
@R, SizeOf(R), @R, SizeOf(R), cb, NIL);
if (R.Flags and 1)<>0 then
begin
FPhysicalVolume := -1;
FPhysicalSectors := 0;
FHeads := 0;
FCylinders := 0;
FreeMem(P, SizeOf(TDriveMapInfo));
Exit;
end;
FPhysicalVolume := PDriveMapInfo(P)^.dmiInt13Unit;
FreeMem(P, SizeOf(TDriveMapInfo));
end;
end;
type
PTransfer = ^TTransfer;
TTransfer = record
StartSector: Longint;
SectorCount: Word;
Buffer: Longint;
end;
var Transfer: TTransfer;
F: TMemoryStream;
function TDiskIO.ReadLogicalSectorEx(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);
L := F.Size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -