home *** CD-ROM | disk | FTP | other *** search
- {*********************************************************}
- { }
- { A unit forráskódja az IDG - PC-X szerkesztôségének, }
- { és Bérczi László-nak a tulajdona. }
- { A forráskód a kereskedelmi célokat kivéve szabadon }
- { terjeszthetô ! }
- { }
- { PC-X User (c) 1998, március }
- {*********************************************************}
- {$G+}
- unit PCXDrive;
-
- INTERFACE
- 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}
-
- const
- ReadOnly = $01;
- Hidden = $02;
- SysFile = $04;
- VolumeID = $08;
- Directory = $10;
- Archive = $20;
- AnyFile = $3F;
-
-
- var
- LastStatus: Byte;
- CF : Boolean;
-
- function ResetDisk(ADrive: Byte): Byte;
- function ReadSectorsIntoMemory(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecCount: Byte; var Status, ReadedSecCount: Byte): Boolean;
- function WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToWrite: Byte; var Status, SecWrited: Byte): Boolean;
- function VerifySectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToVerify: Byte; var Status, SecVerified: Byte): Boolean;
- function ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
- BootInf: PBootSecInforms; var Status, ReadedSecCount: Byte): Boolean;
- function GetBootSecInforms(Drive: Byte; var Informs: TBootSecInforms): Boolean;
- function GetStatusOfLastDriveOperation(Drive: Byte): Byte;
-
- procedure CopyBufToDirEntry(var Buf; Index: Byte; var _AEntry: TDirectoryEntry);
-
- function ConvertDriveLetterToPhisicalDriveNumber(Drv: Char): Byte;
- function ConvertStatusByteToString(StatusByte: Byte): String;
- function ConvertAttrByteToAttrStr(Attribute: Byte): String;
-
- procedure ConvertTimeWordToRecord(FileTimeW: Word; var FileTime: TFileTime);
- procedure ConvertDateWordToRecord(FileDateW: Word; var FileDate: TFileDate);
-
- function ConvertTimeAndDateToString(FileTimeW, FileDateW: Word): String;
-
-
- IMPLEMENTATION
- uses TTUtil;
-
- function ResetDisk(ADrive: Byte): Byte; Assembler;
- asm
- xor ah, ah
- mov dl, ADrive
- int 13h
- mov al, ah
- end;
-
- function 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}
- and al, 00111111b {xxBBBB BB -> 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
-
- mov LastStatus, ah
- mov 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:
- mov LastStatus, ah
- mov 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 WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToWrite: Byte; var Status, SecWrited: Byte): Boolean;
- begin
- end;
-
- function VerifySectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
- SecToVerify: Byte; var Status, SecVerified: Byte): Boolean;
- begin
- end;
-
- function ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
- BootInf: PBootSecInforms; 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;
-
- function GetBootSecInforms(Drive: Byte; var Informs: TBootSecInforms): Boolean; Assembler;
- var B: Boolean;
- asm
- push es
- mov dl, Drive
- shr dl, 7
- or dl, dl
- jne @HDD
- xor dh, dh
- jmp @Cont
- @HDD:
- mov dh, 1
- @Cont:
- mov dl, Drive
- mov cl, 1
- xor ch, ch
- les bx, [Informs]
-
- {mov ax, Informs.Word[2]
- mov ax, Informs.Word[0]}
-
- mov al, 1
- mov ah, 02h
- int 13h
- jc @Error
- mov B, True
- jmp @Exit
- @Error:
- mov B, False
- @Exit:
- mov al, B
- pop es
- end;
-
- function GetStatusOfLastDriveOperation(Drive: Byte): Byte; Assembler;
- asm
- mov ah, 01h
- mov dl, Drive
- int 13h
- xchg al, ah
- end;
-
- procedure CopyBufToDirEntry(var Buf; Index: Byte; var _AEntry: TDirectoryEntry); Assembler;
- const SizeOfAEntry: Word = SizeOf(TDirectoryEntry);
- asm
- push es
- push ds
- push di
- push si
- push bp
- les di, [Buf]
- lds si, [_AEntry]
- mov cx, SizeOfAEntry {20h {20h = 32; = SizeOf(AEntry) = SizeOf(TDirectoryEntry)}
- xor ah, ah
- mov al, Index
- mul cl
- mov bx, ax
- xor bp, bp
- @Loop:
- mov al, Byte Ptr es:[di+bx]
- mov Byte Ptr ds:[si+bp], al
- inc bx
- inc bp
- cmp bp, cx
- jb @Loop
- pop bp
- pop si
- pop di
- pop ds
- pop es
- end;
-
- function ConvertDriveLetterToPhisicalDriveNumber(Drv: Char): Byte;
- var DrvN: Byte;
- begin
- Drv:=UpCase(Drv);
- if Drv in ['A', 'B']
- then DrvN:=Ord(Drv)-65 {A - 0, floppy}
- else DrvN:=Ord(Drv)-67+128; {C - 128, phisical harddisk}
- ConvertDriveLetterToPhisicalDriveNumber:=DrvN;
- end;
-
- function ConvertStatusByteToString(StatusByte: Byte): String;
- begin
- case StatusByte of $00: ConvertStatusByteToString:='Successful completion (NO ERROR)';
- $01: ConvertStatusByteToString:='Invalid function in AH or invalid parameter';
- $02: ConvertStatusByteToString:='Address mark not found';
- $03: ConvertStatusByteToString:='Disk write-protected';
- $04: ConvertStatusByteToString:='Sector not found/read error';
- $05: ConvertStatusByteToString:='Reset failed (HDD)';
- $06: ConvertStatusByteToString:='Disk changed (floppy)';
- $07: ConvertStatusByteToString:='Drive parameter activity failed (HDD)';
- $08: ConvertStatusByteToString:='DMA overrun';
- $09: ConvertStatusByteToString:='Data boundary error';
- {(attempted DMA across 64K boundary or >80h sectors)}
- $0A: ConvertStatusByteToString:='Bad sector detected (HDD)';
- $0B: ConvertStatusByteToString:='Bad track detected (HDD)';
- $0C: ConvertStatusByteToString:='Unsupported track or invalid media';
- $0D: ConvertStatusByteToString:='Invalid number of sectors on format (PS/2 HDD)';
- $0E: ConvertStatusByteToString:='Control data address mark detected (HDD)';
- $0F: ConvertStatusByteToString:='DMA arbitration level out of range (HDD)';
- $10: ConvertStatusByteToString:='Uncorrectable CRC or ECC error on read';
- $11: ConvertStatusByteToString:='Data ECC corrected (hard disk)';
- $20: ConvertStatusByteToString:='Controller failure';
- $31: ConvertStatusByteToString:='No such drive (Compaq)';
- $32: ConvertStatusByteToString:='Incorrect drive type stored in CMOS (Compaq)';
- $40: ConvertStatusByteToString:='Seek failed';
- $15,
- $80: ConvertStatusByteToString:='Drive not ready - Timeout (FDD)';
- $AA: ConvertStatusByteToString:='Drive not ready (HDD)';
- $BB: ConvertStatusByteToString:='Undefined error (HDD)';
- $CC: ConvertStatusByteToString:='Write fault (HDD)';
- $E0: ConvertStatusByteToString:='Status register error (HDD)';
- $FF: ConvertStatusByteToString:='Sense operation failed (HDD)';
- else ConvertStatusByteToString:='Unknown Error';
- end;
- end;
-
- function ConvertAttrByteToAttrStr(Attribute: Byte): String;
- var S: String[5];
- begin
- S:='';
- if ((Attribute and ReadOnly ) = ReadOnly ) then S:=S+'R';
- if ((Attribute and Hidden ) = Hidden ) then S:=S+'H';
- if ((Attribute and SysFile ) = SysFile ) then S:=S+'S';
- if ((Attribute and VolumeID ) = VolumeID ) then S:=S+'V';
- if ((Attribute and Directory) = Directory) then S:='<DIR>';
- if ((Attribute and Archive ) = Archive ) then S:=S+'A';
- S:=FillToSizeB(S, 5);
- ConvertAttrByteToAttrStr:=S;
- end;
-
- procedure ConvertTimeWordToRecord(FileTimeW: Word; var FileTime: TFileTime);
- var TempB: Byte;
- begin
- asm
- mov ax, FileTimeW
- and al, 00011111b
- mov cl, 2
- mul cl
- mov TempB, al
- end;
- FileTime.Second:=TempB;
- asm
- mov ax, FileTimeW
- shr ax, 3
- shr al, 2
- mov TempB, al
- end;
- FileTime.Minute:=TempB;
- asm
- mov ax, FileTimeW
- shr ax, 11
- mov TempB, al
- end;
- FileTime.Hour:=TempB;
- end;
-
- procedure ConvertDateWordToRecord(FileDateW: Word; var FileDate: TFileDate);
- var TempB: Byte;
- begin
- asm
- mov ax, FileDateW
- and al, 00011111b
- mov TempB, al
- end;
- FileDate.Day:=TempB;
- asm
- mov ax, FileDateW
- shr ax, 1
- shr al, 4
- mov TempB, al
- end;
- FileDate.Month:=TempB;
- asm
- mov ax, FileDateW
- shr ax, 9
- mov TempB, al
- end;
- FileDate.Year:=1980 + TempB;
- end;
-
- function ConvertTimeAndDateToString(FileTimeW, FileDateW: Word): String;
- var
- FileDate: TFileDate;
- FileTime: TFileTime;
- begin
- ConvertTimeWordToRecord(FileTimeW, FileTime);
- ConvertDateWordToRecord(FileDateW, FileDate);
- ConvertTimeAndDateToString:=
- FillToSizeA0(ConvertByteToString(FileDate.Month), 2)+'-'+
- FillToSizeA0(ConvertByteToString(FileDate.Day), 2)+'-'+
- ConvertWordToString(FileDate.Year)+' '+
- FillToSizeA0(ConvertByteToString(FileTime.Hour), 2)+':'+
- FillToSizeA0(ConvertByteToString(FileTime.Minute), 2);
-
- end;
-
-
- END.