
 PrintDoc v1.1 - John Baldwin "E:\PHOENIX\CODE\PFS\PFSTYPES.PAS"       Page 1

 {$A+,B-,D+,E-,F-,G+,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V-,X+,Y+}
 Unit PFSTypes;
 
 Interface
 
 (**************************************************************************)
 
 {Generic Stuff}
 
 Const
    PFS_SectorSize=512;
 
 Type
    DWord=LongInt;
    QWord=Record
       {00}  Lo,
       {04}  Hi:DWord;
       {08}
          End;
    TPFS_MagicNumber=DWord;
    TObjectID=DWord;  {this really belongs in a security code file}
    TPFS_Date=DWord;
    TPFS_Sector=Array[1..PFS_SectorSize] of Byte;
    PPFS_Sector=^TPFS_Sector;
 
 (**************************************************************************)
 
 {Disk Locations}
 
 Type
    {CHS Location record}
    TCHS=Record
      {00}  Head:Byte;
      {01}  Sector:Byte;  {bits 6-7 are cylinder bits 8-9}
      {02}  Cylinder:Byte; {bits 0-7}
      {03}
         End;
 
    {Logical Sectors}
    TPFS_LogicalSectorNumber=QWord;
 
 

 PrintDoc v1.1 - John Baldwin "E:\PHOENIX\CODE\PFS\PFSTYPES.PAS"       Page 2

 
 (**************************************************************************)
 
 {Drive ID}
 
 Const
    PFS_DriveIDLength=20;
 
 Type
    TPFS_DriveID=Array [1..PFS_DriveIDLength] of Byte;
 
    {Drive ID is determined by summing the Model and Serial Number fields
     from the ATA Identify Drive command as follows:
 
 Field             Bytes:
 =============     ===========================================================
 Model              0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
                   20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
 Serial Number      0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
                --------------------------------------------------------------
 Drive ID           0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19
 
 
   Note: If the Model and Serial Number cannot be obtained, then a random
   number is chosen for the Drive ID so long that it does not conflict with
   any existing Drive ID in the system.  Also, if when forming a Drive ID as
   prescribed above the resulting ID conflicts with an existing ID, then a
   unique random number will be chosen as well. }
 
 (**************************************************************************)
 
 {Partition Record Entry}
 
 Const
    preBootable=$80;  {value of PRE.Bootable if partition is bootable}
 
    {System ID's for a partition}
    idPhoenixFS=$B9;
 
 Type
    {Entry in MBR for a partition}
    TPartitionRecordEntry=Record
                       {00}  Bootable:Byte;
                       {01}  StartLocation:TCHS;
                       {04}  SystemID:Byte;
                       {05}  EndLocation:TCHS;
                       {08}  SectorsBefore:DWord; {sectors preceding partition
                                                   start}
                       {0C}  Length:DWord; {length of partition in sectors}
                       {10}
                          End;
 
 

 PrintDoc v1.1 - John Baldwin "E:\PHOENIX\CODE\PFS\PFSTYPES.PAS"       Page 3

 
 (**************************************************************************)
 
 {Master Boot Record}
 
 Const
    MBRBootStrapLength=446;
    NumPartitions=4;
    SignatureValue=$AA55;
 
 Type
    TMasterBootRecord=Record
                  {000}  BootStrap:Array [1..MBRBootStrapLength] of Byte;
                  {1BE}  Partitions:Array [1..NumPartitions] of
                                    TPartitionRecordEntry;
                  {1FE}  Signature:Word;
                  {200}
                      End;
 
 (**************************************************************************)
 
 {PFS Segment Table Entry}
 
 Const
    {Bit definitions for STE.Flags}
    PFS_segBoot          =$01;
    PFS_segInterleave    =$02;
    PFS_segInUse         =$04;
    PFS_segFinalSegment  =$08;
    PFS_segSwap          =$10;
    PFS_segNextSegment   =$07;  {00000111}
    PFS_segNextPartition =$18;  {00011000}
    PFS_segNextBootRecord=$E0;  {11100000}
 
 Type
    TPFS_SegmentTableEntry=Record
                        {00}  StartSector:TPFS_LogicalSectorNumber;
                        {08}  Length:TPFS_LogicalSectorNumber;
                        {10}  NextDrive:TPFS_DriveID;
                        {24}  NextSegment:Byte;
                        {25}  NumSegments:Byte;
                        {26}  Sequence:Byte;
                        {27}  Flags:Byte;
                        {28}
                           End;
 
 

 PrintDoc v1.1 - John Baldwin "E:\PHOENIX\CODE\PFS\PFSTYPES.PAS"       Page 4

 
 (**************************************************************************)
 
 {PFS Segment Table}
 
 Const
    PFS_NumberSegmentTableEntries=8;
    PFS_BootStrapLength=154;
    PFS_segMagicNumber=$31534650; {'PFS1'}
    PFS_segNoCylTable=0;  {if ST.CylTable equals this, then there is no
                           cylinder group table present for this partition.}
 
 Type
    TPFS_SegmentTable=Record
                 {000}   BootStrap:Array [1..PFS_BootStrapLength] of Byte;
                 {09A}   Flags:Byte;  {Currently all bits are reserved}
                 {09B}   BootSectors:Byte; {Number of extra logical sectors
                                           in bootstrap}
                 {09C}   MagicNumber:TPFS_MagicNumber;
                 {0A0}   Segments:Array [1..PFS_NumberSegmentTableEntries] of
                                  TPFS_SegmentTableEntry;
                 {1E0}   CylinderTable:TPFS_LogicalSectorNumber;
                 {1E8}   LogicalSectorSize:Word;  {Currently only a value of
                                                   512 is supported}
                 {1EA}   DriveID:TPFS_DriveID;
                 {1FE}   Signature:Word;  { $AA55 like MBR}
                      End;
 
 

 PrintDoc v1.1 - John Baldwin "E:\PHOENIX\CODE\PFS\PFSTYPES.PAS"       Page 5

 
 (**************************************************************************)
 
 {Volume Descriptor}
 
 Const
    PFS_volDirty=$01;
    PFS_volMagicNumber=$316C6F76; {'vol1'}
    PFS_VolumeNameLength=64;
 
 Type
    TPFS_VolumeName=Array [0..PFS_VolumeNameLength-1] of Char;
                                                       {BP treats char arrays
                                                        that start with an
                                                        index of 0 as a null-
                                                        terminated string,
                                                        which the Volume
                                                        Names are}
    TPFS_VolumeDescriptor=Record
                      {000}  BootStubStart:Array[1..4] of Byte;
                                                            {short near jump
                                                             to start of actual

 
                                                             boot code}
                      {004}  StubSectors:Byte; {Number of logical sectors for
                                                boot stub program}
                      {005}  Flags:Byte;
                      {006}  ClusterSize:Byte;
                                           {Bits 0-3 hold the Log base 2 of
                                            the cluster size in 512 byte
                                            sectors.  The cluster size is the
                                            logical sector size for a volume.
                                            The size of a volume sector can
                                            be attained as follows:
 
                                            (2^ClusterSize)*512 bytes
 
                                            or as so in assembly:
 
                                               mov cl,[VD.ClusterSize]
                                               mov eax,1
                                               add cl,9    ;512 = 2^9
                                               shl eax,cl
 
                                            Bits 4-7 are reserved }
                      {007}  Reserved:Byte; {Must be 0}
                      {008}  Size:TPFS_LogicalSectorNumber;
                                                    {Number of Volume Sectors
                                                     in Volume}
                      {010}  SuperBlockSector:TPFS_LogicalSectorNumber;
                            {Number of Volume sector where SuperBlock currently

 
                             being used is stored.}
                      {018}  DateCreated:TPFS_Date; {Date/Time of creation}
                      {01C}  MagicNumber:TPFS_MagicNumber;
                      {020}  VolumeName:TPFS_VolumeName;
                      {060} {BootStub:Code; All the executable code}
                          End;
 


 PrintDoc v1.1 - John Baldwin "E:\PHOENIX\CODE\PFS\PFSTYPES.PAS"       Page 6

 (**************************************************************************)
 
 {Tree Node Descriptor}
 
 Type
    TPFS_TreeNodeDescriptor=Record
                         {00}  Location:QWord;
                         {08}  Length:QWord;
                         {10}
                            End;
 
 (**************************************************************************)
 
 {File Node}
 Const
    PFS_filMagicNumber=$316C6966; {'fil1'}
 
    {File Attributes}
    PFS_faArchive            =$00000001;
    PFS_faSystem             =$00000002;
    PFS_faHidden             =$00000004;
    PFS_faReadOnly           =$00000008;
    PFS_faImmediatePurge     =$00000100;
    PFS_faFileTypeMask       =$00070000;
    PFS_faCompressed         =$00100000;
    PFS_faEncrypted          =$00200000;
    PFS_faDeleted            =$00400000;
    PFS_faPurge              =$00800000;
    PFS_faInternalDataMask   =$03000000;
    PFS_faNodeHalfSize       =$10000000;
    PFS_faReserved           =$EC08FEF0;
    PFS_faGeneralFlagsMask   =$000000FF;
    PFS_faInternalFlagsMask  =$FFFFFF00;
 
    {file types}
    PFS_ftGenericFile        =$00000000;
    PFS_ftDirectory          =$00010000;
    PFS_ftSymbolicLink       =$00020000;
 
    {file internal data types}
    PFS_fidNone              =$00000000;
    PFS_fidRights            =$01000000;
    PFS_fidExtendedAttributes=$02000000;
    PFS_fidFileData          =$03000000;
 
    {Tree Node Numbers}
    PFS_NumRightsTreeNodes=1;
    PFS_NumEATreeNodes=2;
    PFS_NumDataTreeNodes=7;
 
 

 PrintDoc v1.1 - John Baldwin "E:\PHOENIX\CODE\PFS\PFSTYPES.PAS"       Page 7

 
 Type
    TPFS_FileNode=Record
              {000}  MagicNumber:TPFS_MagicNumber;
              {004}  NumHardLinks:DWord;
              {008}  Attributes:DWord;
              {00C}  Owner:TObjectID;
              {010}  Creator:TObjectID;
              {014}  Modifier:TObjectID; {Object ID of user who last modified
                                          file}
              {018}  Created:TPFS_Date; {Date/Time of file node creation}
              {01C}  LastModified:TPFS_Date; {Date/Time file node last modified}
 
              {020}  DataAccessed:TPFS_Date; {Date/Time file data last accessed}
 
              {024}  DataModified:TPFS_Date; {Date/Time file data last modified}
 
              {028}  FileSize:QWord;
              {030}  Rights:Array [1..PFS_NumRightsTreeNodes] of
                            TPFS_TreeNodeDescriptor;
              {040}  ExtendedAttributes:Array [1..PFS_NumEATreeNodes] of
                                        TPFS_TreeNodeDescriptor;
              {060}  FileData:Array [1..PFS_NumDataTreeNodes] of
                              TPFS_TreeNodeDescriptor;
              {0D0} {InternalData:Lots of bytes}
                  End;
    TPFS_FileNodeNumber=QWord;
 
 (**************************************************************************)
 
 {Rights List Entry}
 
 Const
    {Rights}
    PFS_riFind        =$00000001;
    PFS_riRead        =$00000002;
    PFS_riReadRights  =$00000004;
    PFS_riChangeRights=$00000008;
    PFS_riChangeEAs   =$00000010;
    PFS_riChangeOwner =$00000020;
    PFS_riChangeFlags =$00000040;
    PFS_riUnlink      =$00000080;
    PFS_riWrite       =$00000100;
    PFS_riRedirectLink=$00000200; {user may change file data of a symbolic link}
 
    PFS_riCreate      =$00000400; {next three apply to modifing data of
                                   directories}
    PFS_riRename      =$00000800;
    PFS_riRemove      =$00001000;
    PFS_riSupervisor  =$01000000;
    PFS_riInheritMask =$10000000; {determines if entry is an inherit mask or
                                   actual access rights}
    PFS_riReserved    =$7EFFE000;
 
 

 PrintDoc v1.1 - John Baldwin "E:\PHOENIX\CODE\PFS\PFSTYPES.PAS"       Page 8

 
 Type
    TPFS_RightsListEntry=Record
                      {00}  User:TObjectID;  {can be a group as well}
                      {04}  Rights:DWord;
                      {08}
                         End;
 
 (**************************************************************************)
 
 {Superblock} {temporary and sketchy at the moment, i.e. subject to change}
 
 Const
    PFS_MaxDirectoryBands=16;
 
 Type
    TPFS_Superblock=Record
                { 0}   FSDLTLocation:TPFS_LogicalSectorNumber;
                { 8}   BadSectorList:TPFS_FileNodeNumber;
                {10}   RootDirectory:TPFS_FileNodeNumber;
                {18}   Features:DWord; {reserved, must be 0}
                {1C}   Created:TPFS_Date;
                {20}   DirectoryBands:Array [1..PFS_MaxDirectoryBands] of
                                      TPFS_LogicalSectorNumber;
                      {VolumeCreator:TObjectID;} {?}
                {A0}   FSVersion:Record
                                    Major:Byte;
                                    Minor:Byte;
                                 End;
                {A2}   MinimumFree:Byte;  {Percentage from 0 to 100}
                {A3}   Reserved:Array[163..PFS_SectorSize] of Byte;
                    End;
 
 (**************************************************************************)
 
 Implementation
 
 End.
 
 
 

