home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 10 / mycd10.iso / share / os2 / utilidad / ext2fl / e2virtio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-31  |  6.4 KB  |  177 lines

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