home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / e2fltsrc.zip / e2virtio.c < prev    next >
C/C++ Source or Header  |  1995-07-25  |  6KB  |  166 lines

  1. /************************************************************************/
  2. /*  Linux partition filter (C) Deon van der Westhuysen.                 */
  3. /*                                                                      */
  4. /*  Dedicated to Jesus Christ, my Lord and Saviour.                     */
  5. /*                                                                      */
  6. /*  Permission is granted to freely use and modify this code for non-   */
  7. /*  profit use on the condition that this notice is not removed. All    */
  8. /*  other rights are reserved. No warranty, etc.                        */
  9. /*                                                                      */
  10. /*  This code is still under development; expect some rough edges.      */
  11. /*                                                                      */
  12. /************************************************************************/
  13.  
  14. #include "debug.h"
  15. #include "e2data.h"
  16. #include "e2virtio.h"
  17. #include "e2wrap.h"
  18.  
  19. USHORT DoVirtualIO (USHORT Modifier, NPVirtUnitRec pUnitRec, ULONG SectorRBA,
  20.                     PSCATGATENTRY pSGList, USHORT cSGList,ULONG XferOffset)
  21. {
  22.  USHORT    Result;
  23.  
  24.  switch (Modifier)
  25.  {
  26.   case IOCM_READ:
  27.     Result= ReadFakeSector(pUnitRec,SectorRBA,pSGList,cSGList,XferOffset);
  28.     break;
  29.   case IOCM_READ_VERIFY:
  30.     Result= 0;        /* Nothing to do for verify. */
  31.     break;    
  32.   case IOCM_WRITE:
  33.   case IOCM_WRITE_VERIFY:
  34.     Result= WriteFakeSector(pUnitRec,SectorRBA,pSGList,cSGList,XferOffset);
  35.     break;
  36.  }
  37.  return Result;
  38. }
  39.  
  40. USHORT ReadFakeSector (NPVirtUnitRec pUnitRec, ULONG SectorRBA,
  41.                        PSCATGATENTRY pSGList, USHORT cSGList,
  42.                        ULONG XferOffset)
  43. {
  44.  MBR        FakeMBR;
  45.  ULONG        DiskSize;
  46.  
  47.  USHORT        GeoNumHeads=    pUnitRec->pSourceUnitRec->GeoNumHeads;
  48.  USHORT        GeoTrackSec=    pUnitRec->pSourceUnitRec->GeoTrackSec;
  49.  ULONG        SectorsPerCylinder= GeoNumHeads*GeoTrackSec;
  50.  
  51.  memset (&FakeMBR,0,sizeof(MBR));
  52.  
  53.  DiskSize= pUnitRec->NumSectors+pUnitRec->NumExtraSectors;
  54.  
  55. /*BREAK*/
  56.  
  57.  if (SectorRBA==0)
  58.  {
  59.   FakeMBR.Signature=0xAA55;
  60.   FakeMBR.PartitionTable[0].SysIndicator= PARTITION_EXTENDED;
  61.   FakeMBR.PartitionTable[0].RelativeSectors= SectorsPerCylinder;
  62.   FakeMBR.PartitionTable[0].NumSectors= DiskSize-SectorsPerCylinder;
  63.   ComputeCHS (SectorsPerCylinder,GeoNumHeads,GeoTrackSec,
  64.               &(FakeMBR.PartitionTable[0].BegSecCyl),
  65.               &(FakeMBR.PartitionTable[0].BegHead));
  66.   ComputeCHS (DiskSize-1,GeoNumHeads,GeoTrackSec,
  67.               &(FakeMBR.PartitionTable[0].EndSecCyl),
  68.               &(FakeMBR.PartitionTable[0].EndHead));
  69.  }
  70.  else if (SectorRBA==SectorsPerCylinder)
  71.  { 
  72.   FakeMBR.Signature=0xAA55;
  73.   if (pUnitRec->PartSysIndicator==PARTITION_LINUX)
  74.    FakeMBR.PartitionTable[0].SysIndicator= PARTITION_IFS;
  75.   else
  76.    FakeMBR.PartitionTable[0].SysIndicator= pUnitRec->PartSysIndicator;
  77.   FakeMBR.PartitionTable[0].RelativeSectors= pUnitRec->NumExtraSectors-
  78.                                              SectorsPerCylinder;
  79.   FakeMBR.PartitionTable[0].NumSectors= pUnitRec->NumSectors;
  80.   ComputeCHS (pUnitRec->NumExtraSectors,GeoNumHeads,GeoTrackSec,
  81.               &(FakeMBR.PartitionTable[0].BegSecCyl),
  82.               &(FakeMBR.PartitionTable[0].BegHead));
  83.   ComputeCHS (DiskSize-1,GeoNumHeads,GeoTrackSec,
  84.               &(FakeMBR.PartitionTable[0].EndSecCyl),
  85.               &(FakeMBR.PartitionTable[0].EndHead));
  86.  }
  87.  return CopyToSGList (&FakeMBR,sizeof(MBR),pSGList,cSGList,XferOffset);
  88.  
  89. #undef pMBR
  90. }
  91.  
  92. #pragma argsused
  93. USHORT WriteFakeSector (NPVirtUnitRec pUnitRec, ULONG SectorRBA,
  94.                        PSCATGATENTRY pSGList, USHORT cSGList,
  95.                        ULONG XferOffset)
  96. {
  97.  return IOERR_MEDIA_WRITE_PROTECT;    /* Tell 'em they can't write to disk */
  98. }
  99.  
  100. /* Function to compute the Cylinder/Head/Sector value for a specified */
  101. /* relative block address. Will set cylinder to 1023 if real cylinder>1023 */
  102. VOID ComputeCHS (ULONG RBA, USHORT GeoNumHeads, USHORT GeoTrackSec,
  103.                  USHORT FAR *CylSec, UCHAR FAR *Head)
  104. {
  105.  ULONG        SectorsPerCylinder= GeoNumHeads*GeoTrackSec;
  106.  ULONG        CHSCylinder;
  107.  USHORT        CHSHead;
  108.  USHORT        CHSSector;
  109.  
  110.  /* Convert DiskSize into a CHS address... */
  111.  CHSCylinder= RBA/SectorsPerCylinder;
  112.  RBA= RBA%SectorsPerCylinder;
  113.  CHSHead= RBA/GeoTrackSec;
  114.  CHSSector= (RBA%GeoTrackSec)+1;
  115.  if (CHSCylinder>1023) CHSCylinder= 1023;
  116.  *Head= CHSHead;
  117.  *CylSec= MAKE_SEC_CYL(CHSSector,CHSCylinder);
  118. }
  119.  
  120. /* Copies Count bytes to the SG list pointed to by pSGList at the offset */
  121. /* specified by XferOffset. */
  122. USHORT CopyToSGList (void FAR *Buffer, ULONG Count, PSCATGATENTRY pSGList,
  123.                      USHORT cSGList, ULONG XferOffset)
  124. {
  125.  ULONG    ppXferBuf;
  126.  ULONG    XferBufLen;
  127.  USHORT    XferLength;
  128.  void    far* VirtAddr;
  129.  
  130.  while ((cSGList)&&(pSGList->XferBufLen<=XferOffset)) 
  131.  {                    /* Seek into the scatgat list */
  132.   XferOffset-=(pSGList++)->XferBufLen;
  133.   cSGList--;
  134.  }
  135.  XferBufLen= 0;
  136.  while (Count)
  137.  {
  138.   if (!XferBufLen)            /* Need to use next SG entry */
  139.   {
  140.    if (!(cSGList--))            /* We run out of SG list elements */
  141.     return IOERR_CMD_SGLIST_BAD;
  142.    ppXferBuf= pSGList->ppXferBuf+ XferOffset;
  143.    XferBufLen= pSGList->XferBufLen- XferOffset;
  144.    pSGList++;
  145.    XferOffset= 0;
  146.   }
  147.  
  148.   XferLength= 32768;    /* To fit in USHORT */
  149.   if (Count<XferLength) XferLength= Count;
  150.   if (XferBufLen<XferLength) XferLength= XferBufLen;
  151.  
  152.   if (!(VirtAddr= PhysToVirt(ppXferBuf,XferLength)))
  153.   {
  154.    ENABLE
  155.    return IOERR_CMD_SGLIST_BAD;
  156.   }
  157.   memcpy (VirtAddr,Buffer,XferLength);
  158.   ENABLE
  159.   ppXferBuf+= XferLength;
  160.   ((char far *)Buffer)+= XferLength;
  161.   Count-= XferLength;
  162.   XferBufLen-= XferLength;
  163.  }
  164.  return 0;
  165. }
  166.