home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 10 / mycd10.iso / share / os2 / utilidad / ext2fl / e2init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-31  |  13.7 KB  |  413 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 "e2router.h"
  28. #include "e2wrap.h"
  29. #include "e2inutil.h"
  30. #include "e2init.h"
  31.  
  32. USHORT    StartInitData= 0;    /* Use addr as pointer to start of init data */
  33.  
  34. /* Initialization function for the driver. Only called once. */
  35. void E2Init (PRPINITOUT Req)
  36. {
  37.  int        UnitCount;
  38.  char FAR    *pCmdLine;
  39.  
  40.  /* Initialize some of the important global variables. */
  41.  DevHelp= ((PRPINITIN) Req)->DevHlpEP;        /* Get pointer to DevHelp */
  42.  pDataSeg= (PVOID) &pDataSeg;            /* Get pointer to data seg */
  43.  OFFSETOF(pDataSeg)= 0;
  44.  VirtToPhys (pDataSeg,&ppDataSeg);        /* Get the physical address */
  45.                         /* of the data segment */
  46.  for (MountCount= 0; MountCount<MAX_LINUX_PARTITIONS; MountCount++)
  47.   MountTable[MountCount]= MountCount;
  48.                          /* MountCount= max num of */
  49.                         /* partitions to mount. */
  50.  
  51.  pCmdLine= ((PRPINITIN) Req)->InitArgs;        /* Get command line args */
  52.  OFFSETOF(pCmdLine)=(USHORT) ((PDDD_PARM_LIST) pCmdLine)->cmd_line_args;
  53.  
  54.  ProcessCmdline (pCmdLine);
  55.  InitPrint ("Linux partition filter. Copyright 1995, Deon van der Westhuysen."
  56.             " v1.2b\n\r"
  57.             "Development version (Beta).\n\r");
  58.  
  59.  InitScanDrivers();                /* Scan for partitions... */
  60.  InitGetUnitFS();                /* Determine FS for each unit */
  61.  InitSortUnits();                /* Sort the units */
  62.  
  63.  if (MountCount>NumVirtUnits)            
  64.   MountCount =NumVirtUnits;            /* Get correct number of */
  65.                         /* units to be mounted. */
  66.  
  67.  /* Check that each entry points to a valid unit. If not valid, point to */
  68.  /* first unit. (Which can only be allocated once, thus one drive letter.) */
  69.  for (UnitCount=0;UnitCount<MountCount;UnitCount++)
  70.   if (MountTable[UnitCount]>=NumVirtUnits)
  71.    MountTable[UnitCount]= 0;
  72.  
  73.  if (!NumVirtUnits)
  74.  {
  75.   InitPrint ("No Linux partitions were found: filter not installed.");
  76.   Req->Unit= 0;
  77.   Req->CodeEnd= 0;                /* No code to keep */
  78.   Req->DataEnd= 0;                /* No data to keep */
  79.   Req->rph.Status= STDON+STERR+ERROR_I24_QUIET_INIT_FAIL;
  80.                         /* Indicate failure */
  81.   return;
  82.  }
  83.  
  84.  ADDHandle= RegisterADD (E2FilterIORBWrapper,FILTER_ADD_NAME);
  85.                         /* Register filter */
  86.  if (!ADDHandle)                /* Check registration */
  87.  {
  88.   InitPrint ("Could't register filter. Installation aborted.");
  89.   while (NumBaseUnits) InitRemoveBaseUnit();    /* Free all base units */
  90.   Req->Unit= 0;
  91.   Req->CodeEnd= 0;                /* No code to keep */
  92.   Req->DataEnd= 0;                /* No data to keep */
  93.   Req->rph.Status= STDON+STERR+ERROR_I24_QUIET_INIT_FAIL;
  94.                         /* Indicate failure */
  95.   return;
  96.  }
  97.  
  98.  for (UnitCount= 0; UnitCount<NumBaseUnits; UnitCount++)
  99.   InitFilterBaseUnit (UnitCount);        /* Filter all base units... */
  100.  
  101.  InitPrintVerbose ("Filter installed.");
  102.  Req->Unit= 0;
  103.  
  104.  Req->CodeEnd= ((USHORT)E2Init);        /* Pointer to end of code */
  105.  Req->DataEnd= ((USHORT)&StartInitData);    /* Pointer to end of data */
  106.  Req->rph.Status= STDON;            /* Everything is OK */
  107. }
  108.  
  109. /* Scan the system for installed device drivers. Scan the drivers for */
  110. /* adapters in turn. */
  111. void InitScanDrivers (void)
  112. {
  113.  PADDEntryPoint        pADDEntry;    /* .ADD entry point adapter */
  114.  PDevClassTableStruc    pDCTable;    /* Pointer to list of ADDs */
  115.  PDevClassTableEntry    pDCEntry;    /* Pointer to device entry */
  116.  int            DeviceCount;
  117.  
  118.  pDCTable= E2GetADDTable();
  119.  InitPrintVerbose ("Scanning Adapter device drivers:");
  120.  for (DeviceCount= pDCTable->DCCount,pDCEntry= pDCTable->DCTableEntries;
  121.       DeviceCount--;
  122.       pDCEntry++)
  123.  {
  124.   InitPrintVerbose (pDCEntry->DCName);
  125.   pADDEntry = (PVOID) MAKEP(pDCEntry->DCSelector,pDCEntry->DCOffset);
  126.   InitScanAdapter (pADDEntry);
  127.  }
  128. }
  129.  
  130. /* This function scans a driver for all the adapters it controls. */
  131. void InitScanAdapter (PADDEntryPoint pADDEntry)
  132. {
  133.  static UCHAR    DeviceTable[MAX_DEVTABLE_SIZE];    /* Holds info about adapters */
  134.  PADAPTERINFO    pAdapterInfo;            /* Pointer to adapter info */
  135.  int        NumAdapters;
  136.  int        AdapterCount;
  137.  
  138.  if (InitReadDevTable(pADDEntry,(PDEVICETABLE) &DeviceTable,
  139.                       sizeof(DeviceTable)))    /* Get list of adapters */
  140.  {
  141.   InitPrintVerbose ("Error reading the device table... skipping device.");
  142.   return;
  143.  }
  144.  
  145.  NumAdapters= ((PDEVICETABLE)&DeviceTable)->TotalAdapters;
  146.  for (AdapterCount= 0;AdapterCount< NumAdapters;AdapterCount++)
  147.  {
  148.   pAdapterInfo= ((PDEVICETABLE) &DeviceTable)->pAdapter[AdapterCount];
  149.   InitPrintVerbose ("Scanning adapter...");
  150.   if (pAdapterInfo->AdapterFlags&AF_ASSOCIATED_DEVBUS)
  151.    InitPrintVerbose ("Skipping associated device bus of the adapter.");
  152.   else
  153.    InitScanUnits (pADDEntry,pAdapterInfo);
  154.  }
  155. }
  156.  
  157. /* This function scans an adapter for all the units it controls. */
  158. void InitScanUnits (PADDEntryPoint pADDEntry, PADAPTERINFO pAdapterInfo)
  159. {
  160.  PUNITINFO    pUnitInfo;            /* Information about unit */
  161.  USHORT        UnitFlags;            /* Flags for current unit */
  162.  USHORT        UnitType;            /* Type flag for units */
  163.  USHORT        FilterHandle;            /* Handle of unit filter */
  164.  PADDEntryPoint    pUnitADDEntry;            /* Entry point for unit */
  165.  NPBaseUnitRec    pBaseUnit;            /* Pointer to base unit rec */
  166.  int        NumUnits;            /* Num units on adapter */
  167.  int        UnitCount;
  168.  
  169.  NumUnits= pAdapterInfo->AdapterUnits;
  170.  pUnitInfo= pAdapterInfo->UnitInfo;
  171.  
  172.  /* Modify some fields in adapter info for later use by base units. */
  173.  memcpy (pAdapterInfo->AdapterName,FILTER_ADD_NAME,sizeof(FILTER_ADD_NAME));
  174.  pAdapterInfo->AdapterUnits= 1;
  175.  pAdapterInfo->AdapterFlags&=~(AF_IBM_SCB|AF_CHS_ADDRESSING);
  176.  
  177.  for (UnitCount= 0;UnitCount<NumUnits;UnitCount++)
  178.  {
  179.   InitPrintVerbose ("Scanning unit...");
  180.   if (UnitCount)                /* If not first unit: */
  181.    memcpy (pUnitInfo,pAdapterInfo->UnitInfo+UnitCount,sizeof(UNITINFO));
  182.                         /* Copy UnitInfo into first */
  183.                         /* slot in the array */
  184.   UnitFlags= pUnitInfo->UnitFlags;
  185.   UnitType= pUnitInfo->UnitType;
  186.   FilterHandle= pUnitInfo->FilterADDHandle;
  187.   if (FilterHandle)
  188.    pUnitADDEntry= InitGetDriverEP (FilterHandle);
  189.   else
  190.    pUnitADDEntry= pADDEntry;
  191.   if (UnitType!=UIB_TYPE_DISK)
  192.   {
  193.    InitPrintVerbose ("Unit is not a disk, skipping.");
  194.    continue;
  195.   }
  196.   if (UnitFlags&UF_REMOVABLE)
  197.   {
  198.    InitPrintVerbose ("Unit is removable (=not partitioned), skipping.");
  199.    continue;
  200.   }
  201.   if (UnitFlags&(UF_NODASD_SUPT|UF_DEFECTIVE))
  202.   {
  203.    InitPrintVerbose ("Unit defective or no OS2DASD.DMD support, skipping.");
  204.    continue;
  205.   }
  206.   if (!InitAddBaseUnit(pUnitADDEntry,pAdapterInfo))
  207.    if (!InitScanPartitions(pUnitADDEntry))    /* If no partitions found: */
  208.     InitRemoveBaseUnit();            /* Free base unit again */
  209.  }
  210. }
  211.  
  212. /* Return the entry point for a driver given its handle */
  213. PADDEntryPoint InitGetDriverEP (USHORT FilterHandle)
  214. {
  215.  PDevClassTableStruc    pDCTable;    /* Pointer to list of ADDs */
  216.  PDevClassTableEntry    pDCEntry;    /* Pointer to device entry points */
  217.  
  218.  pDCTable= E2GetADDTable();        /* Get device class list */
  219.  pDCEntry= pDCTable->DCTableEntries+FilterHandle-1;
  220.                     /* Point to entry for ADDHandle */
  221.  return (PVOID) MAKEP(pDCEntry->DCSelector,pDCEntry->DCOffset);
  222.                     /* Return the entry point */
  223. }
  224.  
  225. /* Scan for partitions on a given unit. */
  226. USHORT InitScanPartitions (PADDEntryPoint pAddEP)
  227. {
  228.  static MBR    BootRecord= {0};
  229.  NPBaseUnitRec    pBaseUnit;
  230.  USHORT        UnitHandle;
  231.  USHORT        Result;
  232.  int        FoundExt;
  233.  int        NumAdded;
  234.  int        Count;
  235.  PARTITIONENTRY    *pPartInfo;
  236.  ULONG        PartRBA= 0;
  237.  ULONG        ExtPartRBA= 0;
  238.  
  239.  pBaseUnit= BaseUnits+NumBaseUnits-1;
  240.  UnitHandle= pBaseUnit->UnitHandle;
  241.  NumAdded= 0;                    /* Number partitions added */
  242.                         /* to partition list */
  243.  InitPrintVerbose ("Reading master boot record.");
  244.  do
  245.  {
  246.   FoundExt= 0;
  247.   if (InitReadSector (pAddEP,UnitHandle,PartRBA,
  248.                       ppDataSeg+((USHORT)&BootRecord)))
  249.   {                        /* If error reading sector */
  250.    InitPrint ("Read failure... :-(");
  251.    break;                    /* Done with this unit */
  252.   }
  253.   if (BootRecord.Signature!=0xAA55)        /* Test MBR signature */
  254.   {
  255.    InitPrint ("Invalid signature in partition table.");
  256.    break;                    /* Done with this unit */
  257.   }
  258.   pPartInfo= BootRecord.PartitionTable;        /* Ptr to partition entry */
  259.   
  260.   for (Count=0;Count<4;Count++)        /* Scan for linux partitions... */
  261.    if (InitIsVirtType(pPartInfo[Count].SysIndicator))
  262.    {
  263.     InitPrintVerbose ("Found a partition to virtualize.");
  264.     NumAdded+= InitAddVirtualUnit (PartRBA+pPartInfo[Count].RelativeSectors,
  265.                                    pPartInfo[Count].NumSectors,
  266.                                    pPartInfo[Count].SysIndicator);
  267.    }
  268.   for (Count=0;Count<4;Count++)        /* Scan for extended partitions... */
  269.    if (pPartInfo[Count].SysIndicator==PARTITION_EXTENDED)
  270.    {
  271.     InitPrintVerbose ("Found an extended partition.");
  272.     FoundExt= 1;
  273.     PartRBA= ExtPartRBA+ pPartInfo[Count].RelativeSectors;
  274.     if (!ExtPartRBA) ExtPartRBA= PartRBA;
  275.    }
  276.  } while (FoundExt);
  277.  return NumAdded;
  278. }
  279.  
  280. /* Return 1 if the partition should be virtualized; else returns 0. */
  281. int InitIsVirtType(UCHAR PartType)
  282. {
  283.  if ((PartType==PARTITION_LINUX)||
  284.      (PartType==(PARTITION_LINUX|PARTITION_HIDDEN)))
  285.   return 1;
  286.  if (!(InstallFlags&FI_ALLPART))
  287.   return 0;
  288.  switch (PartType)
  289.  {
  290.   case PARTITION_DOSSMALL:
  291.   case PARTITION_DOSMED:
  292.   case PARTITION_DOSLARGE:
  293.   case PARTITION_IFS:
  294.  
  295.   case PARTITION_DOSSMALL | PARTITION_HIDDEN:
  296.   case PARTITION_DOSMED | PARTITION_HIDDEN:
  297.   case PARTITION_DOSLARGE | PARTITION_HIDDEN:
  298.   case PARTITION_IFS | PARTITION_HIDDEN:
  299.         return 1;
  300.   default:    return 0;
  301.  }
  302. }
  303.  
  304. /* Function to scan the command line and set global variables based on */
  305. /* options specified in the command line. */
  306. void ProcessCmdline (char FAR *pCmdLine)
  307. {
  308.  int    TempInt;
  309.  char    TempChar;
  310.  
  311.  /* InstallFlags= 0 on entry... */
  312.  
  313.  while (*pCmdLine)
  314.  {
  315.   if (*(pCmdLine++)!='/')            /* Scan for a '/' on cmdline */
  316.    continue;
  317.   switch (*(pCmdLine++))
  318.   {
  319.    case 'm':
  320.    case 'M':    MountCount= 0;            /* Assume nothing to mount */
  321.         while (1)            /* Loop to read numbers */
  322.         {
  323.          while ((*pCmdLine==' ')||(*pCmdLine=='\t')) pCmdLine++;
  324.                         /* Skip any spaces */
  325.          if (!*pCmdLine) break;        /* Exit if end-of-line */
  326.  
  327.          /* Read a number here... */
  328.          TempChar= *pCmdLine;
  329.          TempInt= 0;
  330.          while ((TempChar>='0')&&(TempChar<='9'))
  331.                  {
  332.           TempInt= TempInt*10+TempChar-'0';
  333.                   TempChar= *(++pCmdLine);
  334.          }
  335.                  MountTable[MountCount++]= TempInt;
  336.  
  337.          while ((*pCmdLine==' ')||(*pCmdLine=='\t')) pCmdLine++;
  338.                         /* Skip any spaces */
  339.          if (!*pCmdLine) return;    /* Exit if end-of-line */
  340.                  if (*pCmdLine!=',') break;    /* Stop if no next number */
  341.          pCmdLine++;
  342.                 }
  343.         break;
  344.    case 'q':
  345.    case 'Q':    InstallFlags |= FI_QUIET;
  346.         break;
  347.    case 'v':
  348.    case 'V':    InstallFlags |= FI_VERBOSE;
  349.         break;
  350.    case 'a':
  351.    case 'A':    InstallFlags |= FI_ALLPART;
  352.         break;
  353.    case 'w':
  354.    case 'W':    InstallFlags |= FI_ALLOWWRITE;
  355.         break;
  356.    default:    InitPrintVerbose ("Unknown command line option encountered");
  357.         break;
  358.   }
  359.  }
  360. }
  361.  
  362. void InitGetUnitFS (void)
  363. {
  364.  static UCHAR    SectorBuf[SECTOR_SIZE]= {0};
  365.  int        Count;
  366.  NPVirtUnitRec    pUnitRec;
  367.  NPBaseUnitRec    pSourceRec;
  368.  
  369.  for (Count= 0;Count<NumVirtUnits; Count++)
  370.  {
  371.   pUnitRec=VirtUnits+Count;
  372.   pSourceRec=pUnitRec->pSourceUnitRec;
  373.  
  374.   if (InitReadSector (pSourceRec->pADDEntry,pSourceRec->UnitHandle,
  375.                       pUnitRec->StartRBA,ppDataSeg+((USHORT)&SectorBuf)))
  376.                             /* Error- shouldn't happen */
  377.    pUnitRec->Hdr.Flags|=F_ALLOCATED;        /* Allocate so that no one */
  378.                         /* else can use this unit */
  379.   else
  380.    pUnitRec->HiddenSectors=*((ULONG *)(SectorBuf+0x1C));
  381.                         /* Save num of hidden sectors */
  382.  
  383.   switch ((pUnitRec->PartSysIndicator)&~PARTITION_HIDDEN)
  384.   {
  385.    case PARTITION_DOSSMALL:
  386.    case PARTITION_DOSMED:
  387.    case PARTITION_DOSLARGE:
  388.     pUnitRec->FSType=FS_DOSFAT;        /* Assume this partitions of */
  389.                         /* this type will always be */
  390.                         /* FAT partitions. */
  391.    default:
  392.     pUnitRec->FSType=FS_UNKNOWN;
  393.                 break;
  394.   }
  395.  }
  396. }
  397.  
  398. void InitSortUnits (void)
  399. {
  400. }
  401.  
  402. void InitPrint (char FAR *Message)
  403. {
  404.  if (!(InstallFlags&FI_QUIET))
  405.   E2Print (Message);
  406. }
  407.  
  408. void InitPrintVerbose (char FAR *Message)
  409. {
  410.  if (InstallFlags&FI_VERBOSE)
  411.   InitPrint (Message);
  412. }
  413.