home *** CD-ROM | disk | FTP | other *** search
- {*********************************************}
- { }
- { R4s File DOS Function Unit }
- { Copyright (c) 1996, 97 By Bérczi László }
- { }
- {*********************************************}
- {Last Edit: 1997 VI 1. 15:00}
- {R4s File DOS = R4s rewrited all the DOS File user function for making a
- virtual disks. It means you have a disk image file and R4sFDOS makes a
- virtual drive from it - under R4sFDOS -.}
- {$G+}
-
- {Bugs:
- - Critical error No mouse update (while Dump-ing disk, NO Handle Event)
- - Just that ONE ... ^
- }
-
- unit R4s_FDOS;
-
- INTERFACE
- uses Objects, R4s_Symb, X_Stream;
-
- type
-
- PChar13 = ^TChar13;
- TChar13 = Array[1..13] of Char;
-
- PChar11 = ^TChar11;
- TChar11 = Array[1..11] of Char;
-
- PChar8 = ^TChar8;
- TChar8 = Array[1..8] of Char;
-
- PChar3 = ^TChar3;
- TChar3 = Array[1..3] of Char;
-
- PFCB = ^TFCB;
- TFCB = record {for DOS 5.0+}
- DriveNumber : Byte;
- FileName : TChar8;
- FileExt : TChar3;
- CurrBlockNum : Word; {current block number; each block is 128 Byte long}
- LogicalRecSize: Word;
- FileSize : Longint;
- FileDate, {Date of last write}
- FileTime : Word; {Time of last write}
- {S+}SysFileEntry : Byte; {EXT FUNCS} {number of system file table entry for file}
- Attribute : Byte; {bits 7,6 - SHARE.exe ... ; bits 5-0 device attribute word}
- ExtraInfo : Byte; {b7: RO attr from SFT; b6 archive attr from SFT
- b5-0: high number of sector number}
- StartCluster : Word; {starting cluster of file}
- SectorNumber : Word; {low word of sector number containing directory entry}
- {E+}DirEntrypSec : Byte; {END EXT FUNCS} {number of directory entry within sector}
- RecordInCurBlk: Byte; {record within current block 0-127}
- RndAccRecNum : Longint; {random access record number (if record size is > 64 bytes, high byte is omitted)}
- R4sFCBsPos : Byte;
- end;
-
- PRFCB = ^TRFCB;
- TRFCB = record {TRFCB: FCB for renaming}
- DriveNumber: Byte;
- OldFileName: TChar8;
- OldFileExt : TChar3;
- NillAreaLow: Array[1..5] of Char;
- NewFileName: TChar8;
- NewFileExt : TChar3;
- NillAreaHi : Array[1..9] of Char;
- end;
-
- PHandle = ^THandle;
- THandle = record
- Path : String[80]; {temporary}
- Entry : TDirectoryEntry;
- Position: Longint; {in Byte from start of file}
- PosZero : Boolean;
- OwnerDIR: Word; {Owner directory's cluster number}
- end;
-
- {R4s_Symb includes these types}
- (*PDirectoryEntry = ^TDirectoryEntry;
- TDirectoryEntry = record
- FileName : TChar8;
- Extension: TChar3;
- Attribute: Byte;
- Reserved : Array[1..10] of Byte;
- Time,
- Date,
- ClusterNumber: Word;
- FileSize : Longint;
- end;
-
- PDriveParameterBlock = ^TDriveParameterBlock;
- TDriveParameterBlock = record
- Drive : Byte; {0: A, 1: B . . .}
- UNWDeviceDriver : Byte;
- BytePerSector : Word;
- SectorPerCluster : Byte;
- SqrNSectorACluster: Byte;
- BootSizeInSector : Word;
- FATNumber : Byte;
- MaxDirectories : Word;
- FirstDataSector : Word;
- MaxCluster : Word;
- SectorPerFAT : Word;
- FirstDIRsSector : Word;
- DeviceHeader : PDeviceHeader;
- MediaID : Byte;
- AccessByte : Byte;
- NextDPB : PDriveParameterBlock;
- FirstFreeCluster : Word;
- FreeClusterssNumb : Word
- end; {R4s_REM}
-
- PFileTime = ^TFileTime;
- TFileTime = record
- Hour,
- Minute,
- Second: Byte;
- end;
-
- PFileDate = ^TFileDate;
- TFileDate = record
- Year : Word;
- Month,
- Day : Byte;
- end;
-
- PBootSecInforms = ^TBootSecInforms; {SizeOf(TBootSecInforms) = 62 Byte}
- TBootSecInforms = record
- JMP : Array[1..3] of Byte;
- OEMName : Array[1..8] of Char;
- Byte_Sector : Word;
- Sector_Cluster : Byte;
- ReservedSecs : Word;
- FATCount : Byte; {FATCount * SectorInOneFAT }
- MaxRootEntries, {(MaxRootEntries * 32) / Byte_Sector}
- Total_Sector : Word; {DataStart = ReservedSecs + FATSize + RootSize}
- MediaDescriptor: Byte;
- SectorInOneFAT,
- Sector_Track,
- Head_Number,
- Hidden_Sector : Word; {if partitions > 32M then It's the Lo Word }
- Hidden_SectorHi: Word; {if partitions > 32M then used else not used }
- BIGTotal_Sector: Longint; {if (partitions > 32M) And (Total_Sector = 0) }
- PhisicalDriveNo: Byte; { then used else not used }
- InfoLevel : Word; {Must be 0 ???}
- SerialNumber : Longint; {In Hex (bin) }
- VolumeLabel : Array[1..11] of Char; {'NO NAME ' if none present}
- FileSystemType : Array[1..8] of Char; {'FAT12 ' or 'FAT16 ' or 'FAT ' (OS2)}
- TempArray : Array[1..1024-62] of Byte;
- end;
- *)
-
- PFindFileDataType = ^TFindFileDataType;
- TFindFileDataType = record
- DriveLetter : Byte;
- SearchTemp : TChar11;
- SearchAttribute : Byte;
- EnrtyCountwDIR : Word;
- OwnerDIRStartClus: Word;
- OwnerDIRSector : Longint;
- {Reserved : Array[1..4] of Char;}
- FoundAttribute : Byte;
- FileTime,
- FileDate : Word;
- FileSize : Longint;
- FileName : TChar13; {ASCIIZ !!!}
- end;
-
- PNameBuffer = ^TNameBuffer;
- TNameBuffer = Array[1..128] of Char;
-
- PDiskInfo_Serial = ^TDiskInfo_Serial;
- TDiskInfo_Serial = record
- InfoLevel : Word; {Must be 0}
- SerialNumber : Longint;
- VolumeLabel : Array[1..11] of Char; {'NO NAME ' if none present}
- FileSystemType: Array[1..8] of Char; {'FAT12 ' or 'FAT16 '}
- end;
-
- PCurrentDIR = ^TCurrentDIR;
- TCurrentDIR = record
- Sector: Longint;
- Path : String;
- end;
-
- PBuffer4k = ^TBuffer4k;
- TBuffer4k = Array[1..4096] of Char;
-
- PBuffer = ^TBuffer;
- TBuffer = Array[1..16384] of Char;
-
- PBuffer64k = ^TBuffer64k;
- TBuffer64k = Array[1..65535] of Char;
-
- PBooleanArray = ^TBooleanArray;
- TBooleanArray = Array[0..5760] of Boolean;
-
- PSector = ^TSector;
- TSector = Array[1..4096] of Char; {Usually the Sector size is 512 Byte}
-
- PFileTime = ^TFileTime;
- TFileTime = record
- Hour,
- Minute,
- Second: Byte;
- end;
-
- PFileDate = ^TFileDate;
- TFileDate = record
- Year : Word;
- Month,
- Day : Byte;
- end;
-
- PAbstractDrive = ^TAbstractDrive;
- TAbstractDrive = Object(TObject)
- public
- LastStatus: Byte;
- CF : Boolean; {Carray Flag}
- Drive : Byte;
- constructor Init(ADrive: Byte);
- destructor Done; virtual;
- function ResetDisk(ADrive: Byte): Byte; virtual; {Ret: Status} {1300}
- function GetStatusOfLastOperation(ADrive: Byte): Byte; virtual; {Ret: Status} {1301}
- function ReadSectorsIntoMemory(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecCount: Byte; var Status, ReadedSecCount: Byte): Boolean; virtual; {1302}
- function WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToWrite: Byte; var Status, SecWrited: Byte): Boolean; virtual; {1303}
- function VerifySectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToVerify: Byte; var Status, SecVerified: Byte): Boolean; virtual; {1304}
- function ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
- var Status, ReadedSecCount: Byte): Boolean; virtual; {1301}
- procedure GetDriveDatas(var AFATStart, AFATSize, ARootStart, ARootSize, ADataStart: Word; var AMaxEntryPerSec: Byte;
- var ABootInf: TBootSecInforms);
- function GetDriveNumber: Byte;
- private
- FATStart,
- FATSize,
- RootStart,
- RootSize,
- DataStart : Word;
- MaxEntryPerSec : Byte;
- BootInf : TBootSecInforms; {The BootSector's informations}
- UseXMSCache : Boolean;
- IsSectorIn,
- IsSectorModified: PBooleanArray;
- XMSCache : PXMSStream;
- end;
-
- PPhisicalDrive = ^TPhisicalDrive;
- TPhisicalDrive = Object(TAbstractDrive)
- public
- constructor Init(ADrive: Byte);
- destructor Done; virtual;
- function ResetDisk(ADrive: Byte): Byte; virtual; {Ret: Status} {1300}
- function ReadSectorsIntoMemory(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecCount: Byte; var Status, ReadedSecCount: Byte): Boolean; virtual; {1302}
- function WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToWrite: Byte; var Status, SecWrited: Byte): Boolean; virtual; {1303}
- function VerifySectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToVerify: Byte; var Status, SecVerified: Byte): Boolean; virtual; {1304}
- function ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
- var Status, ReadedSecCount: Byte): Boolean; virtual; {1301}
- end;
-
- PImageDrive = ^TImageDrive;
- TImageDrive = Object(TAbstractDrive)
- public
- DriveStr : String[80];
- ImageFile: File;
- constructor Init(ADrive: String);
- destructor Done; virtual;
- function ResetDisk(ADrive: Byte): Byte; virtual; {Ret: Status} {1300}
- function ReadSectorsIntoMemory(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecCount: Byte; var Status, ReadedSecCount: Byte): Boolean; virtual; {1302}
- function WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToWrite: Byte; var Status, SecWrited: Byte): Boolean; virtual; {1303}
- function VerifySectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToVerify: Byte; var Status, SecVerified: Byte): Boolean; virtual; {1304}
- function ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
- var Status, ReadedSecCount: Byte): Boolean; virtual; {1301}
- function SetWriteProtect(On: Boolean): Boolean; virtual;
- private
- IsWriteProtected: Boolean;
- function GetBytePERSector: Word;
- end;
-
- (* PXMSImageDrive = ^TXMSImageDrive;
- TXMSImageDrive = Object(TAbstractDrive)
- public
- DriveStr : String[80];
- ImageFile: File;
- constructor Init(ADrive: String);
- destructor Done; virtual;
- function ResetDisk(ADrive: Byte): Byte; virtual; {Ret: Status} {1300}
- function ReadSectorsIntoMemory(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecCount: Byte; var Status, ReadedSecCount: Byte): Boolean; virtual; {1302}
- function WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToWrite: Byte; var Status, SecWrited: Byte): Boolean; virtual; {1303}
- function VerifySectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToVerify: Byte; var Status, SecVerified: Byte): Boolean; virtual; {1304}
- function ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
- var Status, ReadedSecCount: Byte): Boolean; virtual; {1301}
- function SetWriteProtect(On: Boolean): Boolean; virtual;
- private
- IsWriteProtected: Boolean;
- function GetBytePERSector: Word;
- end;
- *)
-
- {MicroSoft offers handle-oriented file commands instead of FCB like !!!
- So handle-oriented file commands is more reliable then FCB like.
- /FCB oriented file command may mistakes/ - MicroSoft (MS-DOS)}
-
- PR4sFileDOS = ^TR4sFileDOS;
- TR4sFileDOS = Object(TObject)
- public {Original DOS functions}
- {R} constructor Init(ADriveObj: PAbstractDrive); {R means it's ready}
- {R} destructor Done; virtual;
- {R} procedure SelectDefaultDrive(DriveImageFile: String); virtual; {210E}
- {R} function OpenFileByFCB(var FCB: TFCB): Boolean; virtual; {UnOp} {210F}
- {R} function CloseFileByFCB(var FCB: TFCB): Boolean; virtual; { Op} {2110}
- function FindFirstByFCB(FCB: TFCB): Boolean; virtual; {UnOp} {2111}
- function FindNextByFCB(FCB: TFCB): Boolean; virtual; {UnOp} {2112}
- function DeleteFileByFCB(FCB: TFCB): Boolean; virtual;{UnOp} {2113}
- {R} function SeqReadByFCB(var FCB: TFCB): Boolean;virtual;{Op,Return data in DTA 2114}
- function SeqWriteByFCB(FCB: TFCB): Boolean; virtual; {Op,Expect data in DTA 2115}
- function CreateFileByFCB(FCB: TFCB): Boolean; virtual;{UnOp,overw. if exist 2116}
- function RenameFileByFCB(RFCB: TRFCB): Boolean; virtual; {2117}
- {R} function GetCurrentDrive: String; virtual; {2119}
- {R} procedure SetDTA(Address: Pointer); virtual; {Disk Transfer Area 211A}
- procedure GetAllocationInformationForDefDrive(var SecClus: Byte; {211B}
- var ByteSec: Word; var TotClus: Word; var MediaID: Byte); virtual;
- (*procedure GetAllocationInformationForSpecDrive(Drive: String; var SecClus: Byte; {211C}
- var ByteSec: Word; var TotClus: Word; var MediaID: Byte); virtual;*)
- function GetDPBForDefDrive: PDriveParameterBlock; virtual; {211F}
- function ReadRandomRecByFCB(FCB: TFCB): Boolean; virtual; {Op,Return data in DTA 2121}
- function WriteRandomRecByFCB(FCB: TFCB): Boolean; virtual; {Op,Except data in DTA 2122}
- function GetFileSizeByFCB(var FCB: TFCB): Boolean; virtual; {UnOp 2123}
- procedure SetRandomRecNumbForFCB(var FCB: TFCB); virtual; {Op 2124}
- function RandomBlockReadByFCB(var NumbRecToRead: Word; var FCB: TFCB): Boolean; virtual; {Op,Return data in DTA 2127}
- function RandomBlockWriteByFCB(var NumbRecToRead: Word; var FCB: TFCB): Boolean; virtual;{Op,Except data in DTA 2128}
- function PraseFileNameToFCB(var FCB: TFCB; Str: String; var UnPrasedPos: Byte): Boolean; virtual; {UnOp 2129}
- {R} function GetDTA: Pointer; virtual; {212F}
- (*function GetDPBForSpecDrive(Drive: String): PDriveParameterBlock; virtual; {2132}*)
- function GetFreeDiskSpace(Drive: String; var SecClus, FreeClus, ByteClus, TotalClus: Word): Boolean; virtual; {2136}
- function MkDIR(Name: TASCIIZ): Boolean; virtual; {2139}
- function RmDIR(Name: TASCIIZ): Boolean; virtual; {213A}
- {R} function ChDIR(Name: TASCIIZ): Boolean; virtual; {213B}
- function CreatFile(Name: TASCIIZ; Attributes: Word; var Handle: Word): Boolean; virtual; {213C}
- {R} function OpenFile(Name: TASCIIZ; AccessMode: Byte; var Handle: Word): Boolean; virtual; {213D}
- {R} function CloseFile(Handle: Word): Boolean; virtual; {213E}
- {R?}function ReadFromFile(Handle: Word; var ByteToRead: Word; var Buf; BufSize: Word): Boolean; virtual; {213F}
- {N} function WriteToFile(Handle: Word; var ByteToWrite: Word; var Buf): Boolean; virtual; {2140}
- function DeleteFile(Name: String): Boolean; virtual; {2141}
- {R} function SeekFile(Handle: Word; SeekType: Byte; var Pos: Longint): Boolean; virtual; {2142}
- {R} function GetFilePos(Handle: Word): Longint; {2142xx} {if Return = $FFFFFFFF then It means Error !}
- {*} function GetFileAttributes(Name: String; var Attributes: Word): Boolean; virtual; {214300}
- function SetFileAttributes(Name: String; Attributes: Word): Boolean; virtual; {214301}
- (*function GetDeviceInforms(Handle: Word; var Inform: Word): Boolean; virtual; {214400}
- function SetDeviceInforms(Handle: Word; Inform: Word): Boolean; virtual; {214401}*)
- function DuplicateFileHandle(Handle: Word; var NewHandle: Word): Boolean; virtual; {2145}
- {?} function DuplicateFileHandle2(Handle: Word; var NewHandle: Word): Boolean; virtual; {2146}
- function GetCurrentDIR(Drive: Byte; var ASCIIZPath: TASCIIZ): Boolean; virtual; {2147}
- {R} function FindFirstFile(Name: TASCIIZ; Attribute: Byte): Boolean; virtual; {Return FF DataBlock in DTA 214E}
- {R} function FindNextFile: Boolean; virtual; {EXCEPT previous FF DataBlock in DTA 214F}
- function RenameFile(OldName, NewName: TASCIIZ): Boolean; virtual; {2156}
- {R} function GetFilesTimeAndDate(Handle: Word; var Time, Date: Word): Boolean; virtual; {215700}
- function SetFilesTimeAndDate(Handle: Word; Time, Date: Word): Boolean; virtual; {215701}
- (*function GetExtAttributesForFile {215702}
- function GetExtAttributesProperties {215703}
- function SetExtAttributes {215704}*)
- function CreateTempFile(var Name: TASCIIZ {\ !}; Attribute: Word; var Handle: Word): Boolean; virtual; {215A}
- function CreateNewFile(var Name: TASCIIZ; Attribute: Word; var Handle: Word): Boolean; virtual; {215B}
- function NameExpand(Name: TASCIIZ; var OutNameBuffer: TNameBuffer): Boolean; virtual; {Canonicalize filename or path 2160}
- function FlushFileDatas(Handle: Word): Boolean; virtual; {2168}
- {*} function GetDiskSerialNumber(Disk: String; var DiskInfo: TDiskInfo_Serial): Boolean; virtual; {216900}
- function SetDiskSerialNumber(Disk: String; DiskInfo: TDiskInfo_Serial): Boolean; virtual; {216901}
- function ComitFile(Handle: Word): Boolean; virtual; {216A}
- {} function ExtendedOpenOrCreateFile(Name: String; OpenMode, Flags: Byte; Attribute: Word; Action: Byte;
- var Handle: Word): Boolean; virtual; {216C00}
- {function AbsouluteDiskRead(Disk: String; SecToRead, StartSec: Word; var Buf ... {26..}
- public {DOS Extensions}
- function GetFileSize(Handle: Word): Longint;
- public {Helper methods for using DOS functions}
- DTA : Pointer;
- Error: Byte;
- procedure PrepareFCBForUsing(var FCB: TFCB; AFileName, AFileExt: String);
- procedure TempFunc;
- public {Temporary, check methods for out use}
- function GetHandle(Handle: Byte): PHandle;
- private {Sub-methods for internal use of FDOS}
- function GetSectorOfDirectory(Name: TASCIIZ; var Sector: Longint; var Path: String): Boolean; virtual;
- private
- MyFCB : TFCB;
- TheDrive : String;
- DriveNum : Byte;
- DriveObj : PAbstractDrive;
- DriveImage: File;
- CurDIR : TCurrentDIR;
- ASector : TSector;
- AEntry : TDirectoryEntry;
- FATStart,
- FATSize,
- RootStart,
- RootSize,
- DataStart : Word;
- MaxEntryPerSec: Byte;
- BootInf : TBootSecInforms; {The BootSector's informations}
- FCBs : Array[1..50] of PFCB;
- Handles : Array[6..55] of THandle;
- IsUsedHandle : Array[6..55] of Boolean;
- FAT : PBuffer; {64k;}
- Is12bitFAT : Boolean;
- CRC_ASector,
- SectorNumber : Longint;
- private {Internal converter, and other helper methods}
- function GetSectorPerByteInADriveImage(Drive: String): Word;
- procedure ClearAllLocalVariable;
- function ReadLogicalSector(SecNb: Longint): Boolean;
- function ReadnLogigalSector(FromSector: Longint; var Count: Word; ToMem: Pointer): Boolean;
- function IsEntryASimpleFile(Entry: TDirectoryEntry): Boolean;
- function ConvertClusterNumberToLogicalSector(ClusNum: Word): Longint;
- function ConvertLogicalSectorToClusterNumber(LogSec: Longint): Word;
- function IsNULLEntry(const Entry: TDirectoryEntry): Boolean;
- function IsNULLTheEntry(Sector: TSector; Index: Word): Boolean;
- function IsFillWithEntry(Sector: TSector): Boolean;
- function IsUsedEntry(Sector: TSector; Index: Word): Boolean;
- procedure CopyBufToBootInforms(var Buf; var ABootInf: TBootSecInforms);
- procedure ConvertTimeWordToRecord(FileTimeW: Word; var FileTime: TFileTime);
- procedure ConvertDateWordToRecord(FileDateW: Word; var FileDate: TFileDate);
- procedure CopyBufToDirEntry(var Buf; Index: Byte; var _AEntry: TDirectoryEntry);
- procedure GetBootInforms;
- function GetFirstFreeFCBsPos: Byte;
- function ReadFAT: Boolean;
- function HasDrive12bitFAT: Boolean;
- function Convert12BitFATToWord(FATBuf: Pointer; FATIndex: Word): Word;
- procedure CopyASectorToDTA(var _ASector; Count: Word);
- procedure BringDecedXByte(var Buf; SegBuf, OfsBuf, WithX: Word; SizeOfBuf: Integer);
- procedure ConvertStringToChar13(S: String; var CArray: TChar13);
- procedure ConvertStringToChar11(S: String; var CArray: TChar11);
- end;
-
- const
-
- SeekFrom_Start = 0;
- SeekFrom_CurFilePos = 1;
- SeekFrom_End = 2;
-
- Cluster12_FREE = $0000;
- Cluster12_RES = $0FF0; {RESERVED}
- Cluster12_RES2 = $0FF1; {RESERVED}
- Cluster12_RES3 = $0FF2; {RESERVED}
- Cluster12_RES4 = $0FF3; {RESERVED}
- Cluster12_RES5 = $0FF4; {RESERVED}
- Cluster12_RES6 = $0FF5; {RESERVED}
- Cluster12_RES7 = $0FF6; {RESERVED}
- Cluster12_BAD = $0FF7;
- Cluster12_EOF = $0FF8;
- Cluster12_EOF2 = $0FF9;
- Cluster12_EOF3 = $0FFA;
- Cluster12_EOF4 = $0FFB;
- Cluster12_EOF5 = $0FFC;
- Cluster12_EOF6 = $0FFD;
- Cluster12_EOF7 = $0FFE;
- Cluster12_EOF8 = $0FFF;
-
- Cluster16_FREE = $0000;
- Cluster16_RES = $FFF0; {RESERVED}
- Cluster16_RES2 = $FFF1; {RESERVED}
- Cluster16_RES3 = $FFF2; {RESERVED}
- Cluster16_RES4 = $FFF3; {RESERVED}
- Cluster16_RES5 = $FFF4; {RESERVED}
- Cluster16_RES6 = $FFF5; {RESERVED}
- Cluster16_RES7 = $FFF6; {RESERVED}
- Cluster16_BAD = $FFF7;
- Cluster16_EOF = $FFF8;
- Cluster16_EOF2 = $FFF9;
- Cluster16_EOF3 = $FFFA;
- Cluster16_EOF4 = $FFFB;
- Cluster16_EOF5 = $FFFC;
- Cluster16_EOF6 = $FFFD;
- Cluster16_EOF7 = $FFFE;
- Cluster16_EOF8 = $FFFF;
-
- {Original DOS Error}
- R4sFDOS_NoError = $00; {ConvertExtErrCodeToString}
- R4sFDOS_FunctionNumberInvalid = $01;
- R4sFDOS_FileNotFound = $02;
- R4sFDOS_PathNotFound = $03;
- R4sFDOS_TooManyOpenFiles = $04;
- R4sFDOS_AccessDenied = $05;
- R4sFDOS_InvalidHandle = $06;
- R4sFDOS_FormatInvalid = $0B;
- R4sFDOS_AccessCodeInvalid = $0C;
- R4sFDOS_DataInvalid = $0D;
- R4sFDOS_InvalidDrive = $0F;
- R4sFDOS_AttemptedToRemoveCurrentDirectory = $10;
- R4sFDOS_NoMoreFiles = $12;
- R4sFDOS_DiskWrite_Protected = $13;
- R4sFDOS_UnknownUnit = $14;
- R4sFDOS_DriveNotReady = $15;
- R4sFDOS_UnknownCommand = $16;
- R4sFDOS_DataError_CRC = $17;
- R4sFDOS_BadRequestStructureLength = $18;
- R4sFDOS_SeekError = $19;
- R4sFDOS_UnknownMediaType = $1A;
- R4sFDOS_SectorNotFound = $1B;
- R4sFDOS_WriteFault = $1D;
- R4sFDOS_ReadFault = $1E;
- R4sFDOS_GeneralFailure = $1F;
- R4sFDOS_SharingViolation = $20;
- R4sFDOS_LockViolation = $21;
- R4sFDOS_DiskChangeInvalid = $22;
- R4sFDOS_FCBUnavailable = $23;
- R4sFDOS_SharingBufferOverflow = $24;
- R4sFDOS_InsufficientDiskSpace = $27;
- R4sFDOS_FileExists = $50;
- R4sFDOS_CannotMakeDirectory = $52;
- {R4sFileDOS Enhanced Error Codes}
- R4sFDOS_EOF = $53;
- R4sFDOS_FATToBig = $54;
- R4sFDOS_Unknown = $FF;
-
- NoAttr = $00;
- ReadOnly = $01;
- Hidden = $02;
- SysFile = $04;
- VolumeID = $08;
- Directory = $10;
- Archive = $20;
- AnyFile = $3F;
-
- IMPLEMENTATION
- uses R4s_Init, DOS, CRC, R4s_Str, R4s_Conv, R4s_MEMF;
-
- {TAbstractDrive}
- constructor TAbstractDrive.Init(ADrive: Byte);
- begin
- {Inherited Init;} {OFF: Because it fill himself with 0}
- end;
-
- destructor TAbstractDrive.Done;
- begin
- Abstract;
- end;
-
- function TAbstractDrive.ResetDisk(ADrive: Byte): Byte;
- begin
- Abstract;
- end;
-
- function TAbstractDrive.GetStatusOfLastOperation(ADrive: Byte): Byte;
- begin
- GetStatusOfLastOperation:=LastStatus;
- end;
-
- function TAbstractDrive.ReadSectorsIntoMemory(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecCount: Byte; var Status, ReadedSecCount: Byte): Boolean;
- begin
- Abstract;
- end;
-
- function TAbstractDrive.WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToWrite: Byte; var Status, SecWrited: Byte): Boolean;
- begin
- Abstract;
- end;
-
- function TAbstractDrive.VerifySectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToVerify: Byte; var Status, SecVerified: Byte): Boolean;
- begin
- Abstract;
- end;
-
- function TAbstractDrive.ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
- var Status, ReadedSecCount: Byte): Boolean;
- begin
- Abstract;
- end;
-
- procedure TAbstractDrive.GetDriveDatas(var AFATStart, AFATSize, ARootStart, ARootSize, ADataStart: Word;
- var AMaxEntryPerSec: Byte; var ABootInf: TBootSecInforms);
- begin
- AFATStart:=FATStart;
- AFATSize:=FATSize;
- ARootStart:=RootStart;
- ARootSize:=RootSize;
- ADataStart:=DataStart;
- AMaxEntryPerSec:=MaxEntryPerSec;
- ABootInf:=BootInf;
- end;
-
- function TAbstractDrive.GetDriveNumber: Byte;
- begin
- GetDriveNumber:=Drive;
- end;
-
- {TPhisicalDrive}
- constructor TPhisicalDrive.Init(ADrive: Byte);
- var Status, Readed: Byte;
- begin
- Inherited Init(ADrive);
- Drive:=ADrive;
- for Readed:=0 to 4 do if ResetDisk(Drive) = 0 then Break;
- ReadSectorsIntoMemory(BootInf, Drive, 0, 0, 1, 2, Status, Readed);
- with BootInf do
- begin
- FATStart:=ReservedSecs;
- FATSize:=FATCount * SectorInOneFAT;
- RootStart:=FATStart + FATSize;
- RootSize:=(MaxRootEntries * 32) div Byte_Sector;
- DataStart:=RootStart + RootSize;
- MaxEntryPerSec:=(Sector_Cluster * Byte_Sector) div $20; {20h = 32 = AEntry Size}
-
- if IsXMSDriverInstalled
- then if Total_Sector * Byte_Sector < (GetTotalExtendedMemorySize* 1024)+(64*1024)
- then UseXMSCache:=True
- else UseXMSCache:=False
- else UseXMSCache:=False;
-
- end;
-
- {
- IsSectorIn,
- IsSectorModified: PBooleanArray;
- XMSCache : PXMSStream;
- }
- end;
-
- destructor TPhisicalDrive.Done;
- begin
- end;
-
- function TPhisicalDrive.ResetDisk(ADrive: Byte): Byte; Assembler;
- asm
- xor ah, ah
- mov dl, ADrive
- and al, 01111111b
- int 13h
- mov al, ah
- end;
-
- function TPhisicalDrive.ReadSectorsIntoMemory(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecCount: Byte; var Status, ReadedSecCount: Byte): Boolean; Assembler;
- asm
- push es
- push di
-
- cmp SecCount, 00h
- jne @Cont
- mov ah, 0FFh
- xor al, al
- jmp @Error
-
- @Cont:
- mov ax, Track {CylNum -> ax (ah, al)}
- shl ah, 6 {xxxx xxBB -> BBxx xxxx}
- mov bl, Sector {SecNum -> bl}
- shl bl, 2 {xxBB BBBB -> BBBB BB00}
- shr bl, 2 {BBBB BB00 -> 00BB BBBB}
- add ah, bl {ah -> ah felsô két bit és bl alsô 6 bit}
- xchg al, ah {ah, al között csere}
- mov cx, ax
-
- mov ah, 02h
- mov al, SecCount
- mov dh, Head
- mov dl, ADrive
- les bx, [Buf]
- int 13h
- jc @Error
-
- les di, Self
- mov Byte Ptr es:[di].TPhisicalDrive.LastStatus, ah
- mov Byte Ptr es:[di].TPhisicalDrive.CF, False
- les di, Status
- mov Byte Ptr es:[di], ah
- les di, ReadedSecCount
- mov Byte Ptr es:[di], al
-
- mov al, True
- jmp @Exit
-
- @Error:
- les di, Self
- mov Byte Ptr es:[di].TPhisicalDrive.LastStatus, ah
- mov Byte Ptr es:[di].TPhisicalDrive.CF, True
- les di, Status
- mov Byte Ptr es:[di], ah
- les di, ReadedSecCount
- mov Byte Ptr es:[di], al
- mov al, False
- @Exit:
- pop di
- pop es
- end;
-
- function TPhisicalDrive.WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToWrite: Byte; var Status, SecWrited: Byte): Boolean;
- begin
- end;
-
- function TPhisicalDrive.VerifySectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToVerify: Byte; var Status, SecVerified: Byte): Boolean;
- begin
- end;
-
- function TPhisicalDrive.ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
- var Status, ReadedSecCount: Byte): Boolean;
- var
- Track : Word;
- Sector,
- Head : Byte;
- begin
- Sector:=Byte(((StartSec) mod BootInf.Sector_Track)+1);
- Track:=Word(((StartSec) div BootInf.Sector_Track) div BootInf.Head_Number);
- if ADrive > $7F then Head:=Byte(((((StartSec) div BootInf.Sector_Track) mod BootInf.Head_Number))+1) {HDD}
- else Head:=Byte((((StartSec) div BootInf.Sector_Track) mod BootInf.Head_Number)); {FDD}
- ReadLogicalSectorIntoMemory:=ReadSectorsIntoMemory(Buf, ADrive, Head, Track,
- Sector, SecCount, Status, ReadedSecCount);
- end;
-
- {TImageDrive}
- constructor TImageDrive.Init(ADrive: String);
- var
- TempW: Word;
- Status, Readed: Byte;
- begin
- Inherited Init(0);
- DriveStr:=ADrive;
- Assign(ImageFile, DriveStr);
- GetFAttr(ImageFile, TempW);
- IsWriteProtected:=(TempW and ReadOnly) <> 0;
- if (TempW and ReadOnly) <> 0 then FileMode:=0;
- {$I-}
- Reset(ImageFile, GetBytePERSector);
- {$I+}
- if IOResult <> 0 then RunError($5); {File Not Found!}
- if (TempW and ReadOnly) <> 0 then FileMode:=2;
-
- Drive:=0;
- ResetDisk(Drive);
- ReadSectorsIntoMemory(BootInf, Drive, 0, 0, 1, 2, Status, Readed);
- with BootInf do
- begin
- FATStart:=ReservedSecs;
- FATSize:=FATCount * SectorInOneFAT;
- RootStart:=FATStart + FATSize;
- RootSize:=(MaxRootEntries * 32) div Byte_Sector;
- DataStart:=RootStart + RootSize;
- MaxEntryPerSec:=(Sector_Cluster * Byte_Sector) div $20; {20h = 32 = AEntry Size}
- end;
- end;
-
- destructor TImageDrive.Done;
- begin
- Close(ImageFile);
- end;
-
- function TImageDrive.ResetDisk(ADrive: Byte): Byte;
- begin
- Seek(ImageFile, 0);
- if IOResult = 0 then ResetDisk:=0
- else ResetDisk:=$80;
- end;
-
- function TImageDrive.ReadSectorsIntoMemory(var Buf; ADrive, Head: Byte; Track: Word;
- Sector, SecCount: Byte; var Status, ReadedSecCount: Byte): Boolean;
- var LogicalSec: Longint;
- begin
- LogicalSec:= Track * BootInf.Head_Number * BootInf.Sector_Track + Head * BootInf.Sector_Track + Sector - 1;
- ReadSectorsIntoMemory:=ReadLogicalSectorIntoMemory(Buf, ADrive, LogicalSec, SecCount, Status, ReadedSecCount);
- end;
-
- function TImageDrive.WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToWrite: Byte; var Status, SecWrited: Byte): Boolean;
- var
- TempWord : Word;
- LogicalSec: Longint;
- begin
- if IsWriteProtected
- then begin Status:=$03; SecWrited:=0; WriteSectors:=False; end
- else begin
- LogicalSec:= Track * BootInf.Head_Number * BootInf.Sector_Track + Head * BootInf.Sector_Track + Sector - 1;
- Seek(ImageFile, LogicalSec);
- BlockWrite(ImageFile, Buf, SecToWrite, TempWord);
- if IOResult = 0 then Status:=0
- else Status:=$80;
- SecWrited:=Byte(TempWord);
- WriteSectors:= IOResult = 0;
- end;
- end;
-
- function TImageDrive.VerifySectors(var Buf; ADrive, Head: Byte; Track: Word;
- Sector, SecToVerify: Byte; var Status, SecVerified: Byte): Boolean;
- begin
- VerifySectors:=ReadSectorsIntoMemory(Buf, ADrive, Head, Track, Sector,
- SecToVerify, Status, SecVerified);
- end;
-
- function TImageDrive.ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
- var Status, ReadedSecCount: Byte): Boolean;
- var TempWord: Word;
- begin
- Seek(ImageFile, StartSec);
- BlockRead(ImageFile, Buf, SecCount, TempWord);
- if IOResult = 0 then Status:=0
- else Status:=$80;
- ReadedSecCount:=Byte(TempWord);
- ReadLogicalSectorIntoMemory:= IOResult = 0;
- end;
-
- function TImageDrive.SetWriteProtect(On: Boolean): Boolean;
- var Attr: Word;
- begin
- GetFAttr(ImageFile, Attr);
- if On then Attr:=Attr or ReadOnly
- else Attr:=Attr and Not ReadOnly;
- if IOResult = 0 then begin
- SetFAttr(ImageFile, Attr);
- if IOResult = 0 then SetWriteProtect:=True
- else SetWriteProtect:=False;
- end
- else SetWriteProtect:=False;
- end;
-
- function TImageDrive.GetBytePERSector: Word;
- var
- F : File;
- BInf: TBootSecInforms;
- W : Word;
- begin
- Assign(F, DriveStr);
- {$I-}
- Reset(F, 1024);
- if IOResult <> 0 then begin GetBytePERSector:=512; Exit; end; {Structureless!!!}
- {$I+}
- BlockRead(F, BInf, 1, W);
- if W = 1 then GetBytePERSector:=BInf.Byte_Sector
- else GetBytePERSector:=512;
- Close(F);
- end;
-
- {PUBLIC Original DOS functions}
- constructor TR4sFileDOS.Init(ADriveObj: PAbstractDrive);
- var Mem, Disk: Longint;
- begin
- New(FAT);
-
- DriveObj:=ADriveObj;
- DriveNum:=ADriveObj^.GetDriveNumber;
-
- SelectDefaultDrive(TheDrive);
- if Error <> 0 then begin Error:=R4sFDOS_DriveNotReady; Fail; end;
- Is12bitFAT:=HasDrive12bitFAT;
- SetDTA(Ptr(PrefixSeg, $80));
- end;
-
- destructor TR4sFileDOS.Done;
- begin
- ClearAllLocalVariable;
- Dispose(FAT);
- DriveObj^.Done;
- Inherited Done;
- end;
-
- procedure TR4sFileDOS.SelectDefaultDrive(DriveImageFile: String);
- var
- TempW: Word;
- TempB: Boolean;
- begin
- { if ExistFile(DriveImageFile) then {Because of read before exists ?!!!}
- { begin}
- (* TheDrive:=DriveImageFile;
- TempW:=GetSectorPerByteInADriveImage(TheDrive);
- {$I-} Assign(DriveImage, TheDrive);
- Reset(DriveImage, TempW); {$I+}*)
- ClearAllLocalVariable;
- DriveObj^.GetDriveDatas(FATStart, FATSize, RootStart, RootSize,
- DataStart, MaxEntryPerSec, BootInf);
-
- CurDIR.Sector:=RootStart; {ConvertClusterNumberToLogicalSector(8);}
- CurDIR.Path:=':\';
- if IOResult <> 0 then Error:=R4sFDOS_DriveNotReady
- else if Not ReadFAT then Error:=R4sFDOS_FATToBig;
- {end else Error:=R4sFDOS_DriveNotReady;}
- end;
-
- {... a többit majd a következô számokban ...}
-
-
- END.