home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1998 March / pcx19_9803.iso / PC-XUSER / PC-XUSER.14 / TT / PCXDRIVE.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-01-31  |  16.0 KB  |  518 lines

  1. {*********************************************************}
  2. {                                                         }
  3. {   A unit forráskódja az IDG - PC-X szerkesztôségének,   }
  4. {   és Bérczi László-nak a tulajdona.                     }
  5. {   A forráskód a kereskedelmi célokat kivéve szabadon    }
  6. {                    terjeszthetô !                       }
  7. {                                                         }
  8. {   PC-X User (c) 1998, március                           }
  9. {*********************************************************}
  10. {$G+}
  11. unit PCXDrive;
  12.  
  13. INTERFACE
  14. type
  15.  
  16.   PChar13 = ^TChar13;
  17.   TChar13 = Array[1..13] of Char;
  18.  
  19.   PChar11 = ^TChar11;
  20.   TChar11 = Array[1..11] of Char;
  21.  
  22.   PChar8 = ^TChar8;
  23.   TChar8 = Array[1..8] of Char;
  24.  
  25.   PChar3 = ^TChar3;
  26.   TChar3 = Array[1..3] of Char;
  27.  
  28.   PFCB = ^TFCB;
  29.   TFCB = record {for DOS 5.0+}
  30.     DriveNumber   : Byte;
  31.     FileName      : TChar8;
  32.     FileExt       : TChar3;
  33.     CurrBlockNum  : Word; {current block number; each block is 128 Byte long}
  34.     LogicalRecSize: Word;
  35.     FileSize      : Longint;
  36.     FileDate,             {Date of last write}
  37.     FileTime      : Word; {Time of last write}
  38. {S+}SysFileEntry  : Byte; {EXT FUNCS} {number of system file table entry for file}
  39.     Attribute     : Byte; {bits 7,6 - SHARE.exe ... ; bits 5-0 device attribute word}
  40.     ExtraInfo     : Byte; {b7: RO attr from SFT; b6 archive attr from SFT
  41.                            b5-0: high number of sector number}
  42.     StartCluster  : Word; {starting cluster of file}
  43.     SectorNumber  : Word; {low word of sector number containing directory entry}
  44. {E+}DirEntrypSec  : Byte; {END EXT FUNCS} {number of directory entry within sector}
  45.     RecordInCurBlk: Byte; {record within current block 0-127}
  46.     RndAccRecNum  : Longint; {random access record number (if record size is > 64 bytes, high byte is omitted)}
  47.     R4sFCBsPos    : Byte;
  48.   end;
  49.  
  50.   (*PRFCB = ^TRFCB;
  51.   TRFCB = record {TRFCB: FCB for renaming}
  52.     DriveNumber: Byte;
  53.     OldFileName: TChar8;
  54.     OldFileExt : TChar3;
  55.     NillAreaLow: Array[1..5] of Char;
  56.     NewFileName: TChar8;
  57.     NewFileExt : TChar3;
  58.     NillAreaHi : Array[1..9] of Char;
  59.   end;*)
  60.  
  61.   (*PHandle = ^THandle;
  62.   THandle = record
  63.     Path    : String[80]; {temporary}
  64.     Entry   : TDirectoryEntry;
  65.     Position: Longint; {in Byte from start of file}
  66.     PosZero : Boolean;
  67.     OwnerDIR: Word;    {Owner directory's cluster number}
  68.   end;*)
  69.  
  70.   {R4s_Symb includes these types}
  71.   PDirectoryEntry = ^TDirectoryEntry;
  72.   TDirectoryEntry = record
  73.     FileName : TChar8;
  74.     Extension: TChar3;
  75.     Attribute: Byte;
  76.     Reserved : Array[1..10] of Byte;
  77.     Time,
  78.     Date,
  79.     ClusterNumber: Word;
  80.     FileSize     : Longint;
  81.   end;
  82.  
  83.   (*PDriveParameterBlock = ^TDriveParameterBlock;
  84.   TDriveParameterBlock = record
  85.     Drive             : Byte; {0: A, 1: B . . .}
  86.     UNWDeviceDriver   : Byte;
  87.     BytePerSector     : Word;
  88.     SectorPerCluster  : Byte;
  89.     SqrNSectorACluster: Byte;
  90.     BootSizeInSector  : Word;
  91.     FATNumber         : Byte;
  92.     MaxDirectories    : Word;
  93.     FirstDataSector   : Word;
  94.     MaxCluster        : Word;
  95.     SectorPerFAT      : Word;
  96.     FirstDIRsSector   : Word;
  97.     DeviceHeader      : PDeviceHeader;
  98.     MediaID           : Byte;
  99.     AccessByte        : Byte;
  100.     NextDPB           : PDriveParameterBlock;
  101.     FirstFreeCluster  : Word;
  102.     FreeClusterssNumb : Word
  103.   end;  {R4s_REM}*)
  104.  
  105.   PFileTime = ^TFileTime;
  106.   TFileTime = record
  107.     Hour,
  108.     Minute,
  109.     Second: Byte;
  110.   end;
  111.  
  112.   PFileDate = ^TFileDate;
  113.   TFileDate = record
  114.     Year : Word;
  115.     Month,
  116.     Day  : Byte;
  117.   end;
  118.  
  119.   PBootSecInforms = ^TBootSecInforms; {SizeOf(TBootSecInforms) = 62 Byte}
  120.   TBootSecInforms = record
  121.     JMP            : Array[1..3] of Byte;
  122.     OEMName        : Array[1..8] of Char;
  123.     Byte_Sector    : Word;
  124.     Sector_Cluster : Byte;
  125.     ReservedSecs   : Word;
  126.     FATCount       : Byte;    {FATCount * SectorInOneFAT          }
  127.     MaxRootEntries,           {(MaxRootEntries * 32) / Byte_Sector}
  128.     Total_Sector   : Word;    {DataStart = ReservedSecs + FATSize + RootSize}
  129.     MediaDescriptor: Byte;
  130.     SectorInOneFAT,
  131.     Sector_Track,
  132.     Head_Number,
  133.     Hidden_Sector  : Word;    {if partitions > 32M then It's the Lo Word    }
  134.     Hidden_SectorHi: Word;    {if partitions > 32M then used else not used  }
  135.     BIGTotal_Sector: Longint; {if (partitions > 32M) And (Total_Sector = 0) }
  136.     PhisicalDriveNo: Byte;    {   then used else not used                   }
  137.     InfoLevel      : Word;    {Must be 0 ???}
  138.     SerialNumber   : Longint; {In Hex (bin) }
  139.     VolumeLabel    : Array[1..11] of Char; {'NO NAME    ' if none present}
  140.     FileSystemType : Array[1..8] of Char;  {'FAT12   ' or 'FAT16   ' or 'FAT     ' (OS2)}
  141.     TempArray      : Array[1..1024-62] of Byte;
  142.   end;
  143.  
  144.   (*
  145.   PFindFileDataType = ^TFindFileDataType;
  146.   TFindFileDataType = record
  147.     DriveLetter      : Byte;
  148.     SearchTemp       : TChar11;
  149.     SearchAttribute  : Byte;
  150.     EnrtyCountwDIR   : Word;
  151.     OwnerDIRStartClus: Word;
  152.     OwnerDIRSector   : Longint;
  153.     {Reserved         : Array[1..4] of Char;}
  154.     FoundAttribute   : Byte;
  155.     FileTime,
  156.     FileDate         : Word;
  157.     FileSize         : Longint;
  158.     FileName         : TChar13; {ASCIIZ !!!}    
  159.   end;
  160.  
  161.   PNameBuffer = ^TNameBuffer;
  162.   TNameBuffer = Array[1..128] of Char;
  163.  
  164.   PDiskInfo_Serial = ^TDiskInfo_Serial;
  165.   TDiskInfo_Serial = record
  166.     InfoLevel     : Word; {Must be 0}
  167.     SerialNumber  : Longint;
  168.     VolumeLabel   : Array[1..11] of Char; {'NO NAME    ' if none present}
  169.     FileSystemType: Array[1..8] of Char;  {'FAT12   ' or 'FAT16   '}
  170.   end;*)
  171.   (*
  172.   PCurrentDIR = ^TCurrentDIR;
  173.   TCurrentDIR = record
  174.     Sector: Longint;
  175.     Path  : String;
  176.   end;*)
  177.  
  178.   PBuffer4k = ^TBuffer4k;
  179.   TBuffer4k = Array[1..4096] of Char;
  180.  
  181.   PBuffer = ^TBuffer;
  182.   TBuffer = Array[1..16384] of Char;
  183.  
  184.   PBuffer64k = ^TBuffer64k;
  185.   TBuffer64k = Array[1..65535] of Char;
  186.  
  187.   PBooleanArray = ^TBooleanArray;
  188.   TBooleanArray = Array[0..5760] of Boolean;
  189.  
  190.   PSector = ^TSector;
  191.   TSector = Array[1..4096] of Char; {Usually the Sector size is 512 Byte}
  192.  
  193. const
  194.   ReadOnly     =  $01;
  195.   Hidden       =  $02;
  196.   SysFile      =  $04;
  197.   VolumeID     =  $08;
  198.   Directory    =  $10;
  199.   Archive      =  $20;
  200.   AnyFile      =  $3F;
  201.  
  202.  
  203. var
  204.   LastStatus: Byte;
  205.   CF        : Boolean;
  206.  
  207. function  ResetDisk(ADrive: Byte): Byte;
  208. function  ReadSectorsIntoMemory(var Buf; ADrive, Head: Byte; Track: Word; Sector,
  209.             SecCount: Byte; var Status, ReadedSecCount: Byte): Boolean;
  210. function  WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
  211.                SecToWrite: Byte; var Status, SecWrited: Byte): Boolean;
  212. function  VerifySectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
  213.                SecToVerify: Byte; var Status, SecVerified: Byte): Boolean;
  214. function  ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
  215.             BootInf: PBootSecInforms; var Status, ReadedSecCount: Byte): Boolean;
  216. function  GetBootSecInforms(Drive: Byte; var Informs: TBootSecInforms): Boolean;
  217. function  GetStatusOfLastDriveOperation(Drive: Byte): Byte;
  218.  
  219. procedure CopyBufToDirEntry(var Buf; Index: Byte; var _AEntry: TDirectoryEntry);
  220.  
  221. function  ConvertDriveLetterToPhisicalDriveNumber(Drv: Char): Byte;
  222. function  ConvertStatusByteToString(StatusByte: Byte): String;
  223. function  ConvertAttrByteToAttrStr(Attribute: Byte): String;
  224.  
  225. procedure ConvertTimeWordToRecord(FileTimeW: Word; var FileTime: TFileTime);
  226. procedure ConvertDateWordToRecord(FileDateW: Word; var FileDate: TFileDate);
  227.  
  228. function  ConvertTimeAndDateToString(FileTimeW, FileDateW: Word): String;
  229.  
  230.  
  231. IMPLEMENTATION
  232. uses TTUtil;
  233.  
  234. function  ResetDisk(ADrive: Byte): Byte; Assembler;
  235. asm
  236.   xor  ah, ah
  237.   mov  dl, ADrive
  238.   int  13h
  239.   mov  al, ah
  240. end;
  241.  
  242. function  ReadSectorsIntoMemory(var Buf; ADrive, Head: Byte; Track: Word; Sector,
  243.             SecCount: Byte; var Status, ReadedSecCount: Byte): Boolean; Assembler;
  244. asm
  245.   push es
  246.   push di
  247.  
  248.   cmp  SecCount, 00h
  249.   jne  @Cont
  250.   mov  ah, 0FFh
  251.   xor  al, al
  252.   jmp  @Error
  253.  
  254. @Cont:
  255.   mov  ax, Track  {CylNum -> ax (ah, al)}
  256.   shl  ah, 6      {xxxx xxBB -> BBxx xxxx}
  257.   mov  bl, Sector {SecNum -> bl}
  258.   and  al, 00111111b     {xxBBBB BB -> 00BB BBBB}
  259.   add  ah, bl     {ah -> ah felsô két bit  és  bl alsô 6 bit}
  260.   xchg al, ah     {ah, al között csere}
  261.   mov  cx, ax
  262.  
  263.   mov  ah, 02h
  264.   mov  al, SecCount
  265.   mov  dh, Head
  266.   mov  dl, ADrive
  267.   les  bx, [Buf]
  268.   int  13h
  269.   jc   @Error
  270.  
  271.   mov  LastStatus, ah
  272.   mov  CF, False
  273.   les  di, Status
  274.   mov  Byte Ptr es:[di], ah
  275.   les  di, ReadedSecCount
  276.   mov  Byte Ptr es:[di], al
  277.  
  278.   mov  al, True
  279.   jmp  @Exit
  280.  
  281. @Error:
  282.   mov  LastStatus, ah
  283.   mov  CF, True
  284.   les  di, Status
  285.   mov  Byte Ptr es:[di], ah
  286.   les  di, ReadedSecCount
  287.   mov  Byte Ptr es:[di], al
  288.   mov  al, False
  289. @Exit:
  290.   pop  di
  291.   pop  es
  292. end;
  293.  
  294. function  WriteSectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
  295.                SecToWrite: Byte; var Status, SecWrited: Byte): Boolean;
  296. begin
  297. end;
  298.  
  299. function  VerifySectors(var Buf; ADrive, Head: Byte; Track: Word; Sector,
  300.                SecToVerify: Byte; var Status, SecVerified: Byte): Boolean;
  301. begin
  302. end;
  303.  
  304. function  ReadLogicalSectorIntoMemory(var Buf; ADrive: Byte; StartSec: Longint; SecCount: Byte;
  305.             BootInf: PBootSecInforms; var Status, ReadedSecCount: Byte): Boolean;
  306. var
  307.   Track : Word;
  308.   Sector,
  309.   Head : Byte;
  310. begin
  311.   Sector:=Byte(((StartSec) mod BootInf^.Sector_Track)+1);
  312.   Track:=Word(((StartSec) div BootInf^.Sector_Track) div BootInf^.Head_Number);
  313.   if ADrive > $7F then Head:=Byte(((((StartSec) div BootInf^.Sector_Track) mod BootInf^.Head_Number))+1) {HDD}
  314.                   else Head:=Byte((((StartSec) div BootInf^.Sector_Track) mod BootInf^.Head_Number));    {FDD}
  315.   ReadLogicalSectorIntoMemory:=ReadSectorsIntoMemory(Buf, ADrive, Head, Track,
  316.     Sector, SecCount, Status, ReadedSecCount);
  317. end;
  318.  
  319. function  GetBootSecInforms(Drive: Byte; var Informs: TBootSecInforms): Boolean; Assembler;
  320. var B: Boolean;
  321. asm
  322.   push es
  323.   mov  dl, Drive
  324.   shr  dl, 7
  325.   or   dl, dl
  326.   jne  @HDD
  327.   xor  dh, dh
  328.   jmp  @Cont
  329. @HDD:
  330.   mov  dh, 1
  331. @Cont:
  332.   mov  dl, Drive
  333.   mov  cl, 1
  334.   xor  ch, ch
  335.   les  bx, [Informs]
  336.  
  337.   {mov  ax, Informs.Word[2]
  338.   mov  ax, Informs.Word[0]}
  339.  
  340.   mov  al, 1
  341.   mov  ah, 02h
  342.   int  13h
  343.   jc   @Error
  344.   mov  B, True
  345.   jmp  @Exit
  346. @Error:
  347.   mov  B, False
  348. @Exit:
  349.   mov  al, B
  350.   pop  es
  351. end;
  352.  
  353. function  GetStatusOfLastDriveOperation(Drive: Byte): Byte; Assembler;
  354. asm
  355.   mov ah, 01h
  356.   mov dl, Drive
  357.   int 13h
  358.   xchg al, ah
  359. end;
  360.  
  361. procedure CopyBufToDirEntry(var Buf; Index: Byte; var _AEntry: TDirectoryEntry); Assembler;
  362. const SizeOfAEntry: Word = SizeOf(TDirectoryEntry);
  363. asm
  364.   push es
  365.   push ds
  366.   push di
  367.   push si
  368.   push bp
  369.   les  di, [Buf]
  370.   lds  si, [_AEntry]
  371.   mov  cx, SizeOfAEntry {20h {20h = 32;  = SizeOf(AEntry)  = SizeOf(TDirectoryEntry)}
  372.   xor  ah, ah
  373.   mov  al, Index
  374.   mul  cl
  375.   mov  bx, ax
  376.   xor  bp, bp
  377. @Loop:
  378.   mov  al, Byte Ptr es:[di+bx]
  379.   mov  Byte Ptr ds:[si+bp], al
  380.   inc  bx
  381.   inc  bp
  382.   cmp  bp, cx
  383.   jb   @Loop
  384.   pop  bp
  385.   pop  si
  386.   pop  di
  387.   pop  ds
  388.   pop  es
  389. end;
  390.  
  391. function  ConvertDriveLetterToPhisicalDriveNumber(Drv: Char): Byte;
  392. var DrvN: Byte;
  393. begin
  394.   Drv:=UpCase(Drv);
  395.   if Drv in ['A', 'B']
  396.   then DrvN:=Ord(Drv)-65 {A - 0, floppy}
  397.   else DrvN:=Ord(Drv)-67+128; {C - 128, phisical harddisk}
  398.   ConvertDriveLetterToPhisicalDriveNumber:=DrvN;
  399. end;
  400.  
  401. function  ConvertStatusByteToString(StatusByte: Byte): String;
  402. begin
  403.   case StatusByte of $00: ConvertStatusByteToString:='Successful completion (NO ERROR)';
  404.                      $01: ConvertStatusByteToString:='Invalid function in AH or invalid parameter';
  405.                      $02: ConvertStatusByteToString:='Address mark not found';
  406.                      $03: ConvertStatusByteToString:='Disk write-protected';
  407.                      $04: ConvertStatusByteToString:='Sector not found/read error';
  408.                      $05: ConvertStatusByteToString:='Reset failed (HDD)';
  409.                      $06: ConvertStatusByteToString:='Disk changed (floppy)';
  410.                      $07: ConvertStatusByteToString:='Drive parameter activity failed (HDD)';
  411.                      $08: ConvertStatusByteToString:='DMA overrun';
  412.                      $09: ConvertStatusByteToString:='Data boundary error';
  413.                                                      {(attempted DMA across 64K boundary or >80h sectors)}
  414.                      $0A: ConvertStatusByteToString:='Bad sector detected (HDD)';
  415.                      $0B: ConvertStatusByteToString:='Bad track detected (HDD)';
  416.                      $0C: ConvertStatusByteToString:='Unsupported track or invalid media';
  417.                      $0D: ConvertStatusByteToString:='Invalid number of sectors on format (PS/2 HDD)';
  418.                      $0E: ConvertStatusByteToString:='Control data address mark detected (HDD)';
  419.                      $0F: ConvertStatusByteToString:='DMA arbitration level out of range (HDD)';
  420.                      $10: ConvertStatusByteToString:='Uncorrectable CRC or ECC error on read';
  421.                      $11: ConvertStatusByteToString:='Data ECC corrected (hard disk)';
  422.                      $20: ConvertStatusByteToString:='Controller failure';
  423.                      $31: ConvertStatusByteToString:='No such drive (Compaq)';
  424.                      $32: ConvertStatusByteToString:='Incorrect drive type stored in CMOS (Compaq)';
  425.                      $40: ConvertStatusByteToString:='Seek failed';
  426.                      $15,
  427.                      $80: ConvertStatusByteToString:='Drive not ready - Timeout (FDD)';
  428.                      $AA: ConvertStatusByteToString:='Drive not ready (HDD)';
  429.                      $BB: ConvertStatusByteToString:='Undefined error (HDD)';
  430.                      $CC: ConvertStatusByteToString:='Write fault (HDD)';
  431.                      $E0: ConvertStatusByteToString:='Status register error (HDD)';
  432.                      $FF: ConvertStatusByteToString:='Sense operation failed (HDD)';
  433.                      else ConvertStatusByteToString:='Unknown Error';
  434.   end;
  435. end;
  436.  
  437. function  ConvertAttrByteToAttrStr(Attribute: Byte): String;
  438. var S: String[5];
  439. begin
  440.   S:='';
  441.   if ((Attribute and ReadOnly ) = ReadOnly ) then S:=S+'R';
  442.   if ((Attribute and Hidden   ) = Hidden   ) then S:=S+'H';
  443.   if ((Attribute and SysFile  ) = SysFile  ) then S:=S+'S';
  444.   if ((Attribute and VolumeID ) = VolumeID ) then S:=S+'V';
  445.   if ((Attribute and Directory) = Directory) then S:='<DIR>';
  446.   if ((Attribute and Archive  ) = Archive  ) then S:=S+'A';
  447.   S:=FillToSizeB(S, 5);
  448.   ConvertAttrByteToAttrStr:=S;
  449. end;
  450.  
  451. procedure ConvertTimeWordToRecord(FileTimeW: Word; var FileTime: TFileTime);
  452. var TempB: Byte;
  453. begin
  454.   asm
  455.     mov  ax, FileTimeW
  456.     and  al, 00011111b
  457.     mov  cl, 2
  458.     mul  cl
  459.     mov  TempB, al
  460.   end;
  461.   FileTime.Second:=TempB;
  462.   asm
  463.     mov  ax, FileTimeW
  464.     shr  ax, 3
  465.     shr  al, 2
  466.     mov  TempB, al
  467.   end;
  468.   FileTime.Minute:=TempB;
  469.   asm
  470.     mov  ax, FileTimeW
  471.     shr  ax, 11
  472.     mov  TempB, al
  473.   end;
  474.   FileTime.Hour:=TempB;
  475. end;
  476.  
  477. procedure ConvertDateWordToRecord(FileDateW: Word; var FileDate: TFileDate);
  478. var TempB: Byte;
  479. begin
  480.   asm
  481.     mov  ax, FileDateW
  482.     and  al, 00011111b
  483.     mov  TempB, al
  484.   end;
  485.   FileDate.Day:=TempB;
  486.   asm
  487.     mov  ax, FileDateW
  488.     shr  ax, 1
  489.     shr  al, 4
  490.     mov  TempB, al
  491.   end;
  492.   FileDate.Month:=TempB;
  493.   asm
  494.     mov  ax, FileDateW
  495.     shr  ax, 9
  496.     mov  TempB, al
  497.   end;
  498.   FileDate.Year:=1980 + TempB;
  499. end;
  500.  
  501. function  ConvertTimeAndDateToString(FileTimeW, FileDateW: Word): String;
  502. var
  503.   FileDate: TFileDate;
  504.   FileTime: TFileTime;
  505. begin
  506.    ConvertTimeWordToRecord(FileTimeW, FileTime);
  507.    ConvertDateWordToRecord(FileDateW, FileDate);
  508.    ConvertTimeAndDateToString:=
  509.      FillToSizeA0(ConvertByteToString(FileDate.Month), 2)+'-'+
  510.      FillToSizeA0(ConvertByteToString(FileDate.Day), 2)+'-'+
  511.      ConvertWordToString(FileDate.Year)+' '+
  512.      FillToSizeA0(ConvertByteToString(FileTime.Hour), 2)+':'+
  513.      FillToSizeA0(ConvertByteToString(FileTime.Minute), 2);
  514.  
  515. end;
  516.  
  517.  
  518. END.