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