home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / DASD / OS2DASD / DMBPB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-14  |  33.6 KB  |  863 lines

  1. /*DDK*************************************************************************/
  2. /*                                                                           */
  3. /* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
  4. /*                                                                           */
  5. /*    The following IBM OS/2 WARP source code is provided to you solely for  */
  6. /*    the purpose of assisting you in your development of OS/2 WARP device   */
  7. /*    drivers. You may use this code in accordance with the IBM License      */
  8. /*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
  9. /*    Copyright statement may not be removed.                                */
  10. /*                                                                           */
  11. /*****************************************************************************/
  12. /*static char *SCCSID = "src/dev/dasd/os2dasd/dmbpb.c, dsdm, r205apar 93/06/02";*/
  13. #define SCCSID  "src/dev/dasd/os2dasd/dmbpb.c, dsdm, r205apar 93/06/02"
  14.  
  15. /**************************************************************************
  16.  *
  17.  * SOURCE FILE NAME = DMBPB.C
  18.  *
  19.  * DESCRIPTIVE NAME = OS2DASD.DMD - OS/2 DASD Device Manager
  20.  *
  21.  *
  22.  *
  23.  * VERSION = V2.0
  24.  *
  25.  * DATE
  26.  *
  27.  * DESCRIPTION : Partition/BPB Management Routines
  28.  *
  29.  *
  30.  *
  31. */
  32. #include "dmh.h"
  33.  
  34. /*--------------------------------------------------------------------------
  35. ;
  36. ;** Process_Partition - Process the partition table of the fixed disk
  37. ;
  38. ;   Process_Partition processes the partition table obtained from the
  39. ;   fixed disk and determines where the DOS boot sector is found on the
  40. ;   disk.
  41. ;
  42. ;   USHORT Process_Partition (NPVOLCB pVolCB, PULONG VolBootRBA,
  43. ;                                             PULONG NumSectors)
  44. ;
  45. ;   ENTRY:    pVolCB           - input pointer to VolCB
  46. ;             VolBootRBA       - returned RBA of Volume Boot Sector
  47. ;             NumSectors       - returned number of sectors in partition
  48. ;
  49. ;   RETURN:   USHORT           - Result Code (NO_ERROR if valid partition)
  50. ;
  51. ;   EFFECTS:
  52. ;
  53. ;   NOTES:    Global variable ScratchBuffer contains boot sector
  54. ;             on input.
  55. ;
  56. ;----------------------------------------------------------------------------*/
  57.  
  58. USHORT Process_Partition (pVolCB, VolBootRBA, NumSectors)
  59.  
  60. NPVOLCB pVolCB;
  61. PULONG  VolBootRBA;
  62. PULONG  NumSectors;
  63. {
  64.    BOOL   found;
  65.    USHORT i;
  66.    MBR    *pMBR = (MBR *) ScratchBuffer;
  67.    ULONG  temp;
  68.    fBigFat = 0;
  69.  
  70.    pVolCB->Flags &= ~vf_NoDOSPartition;         /* Partition ok so far */
  71.  
  72.    if (pMBR->Signature != 0xAA55)               /* Check for signature word */
  73.       pVolCB->Flags |= vf_NoDOSPartition;       /* Partition invalid */
  74.    else
  75.    {
  76.       found = FALSE;
  77.       for (i = 0; i < 4 && found == FALSE ; i++)
  78.       {
  79.          found = TRUE;
  80.          switch (pMBR->PartitionTable[i].SysIndicator)
  81.          {
  82.             case PARTITION_16M:         /* Partition up to 16M */
  83.                    break;
  84.             case PARTITION_16Mto32M:    /* Partition > 16M and <= 32 M */
  85.                    break;
  86.             case PARTITION_32M:         /* Partition > 32M  */
  87.                    break;
  88.             case PARTITION_IFS:         /* IFS Partition */
  89.                    break;
  90.             case PARTITION_FTACTIVE:    /* Active Fault Tolerant partition */
  91.                    pVolCB->Flags |= vf_FTPartition;
  92.                    break;
  93.             case PARTITION_FTINACTIVE:  /* Inactive Fault Tolerant partition */
  94.                    pVolCB->Flags |= vf_FTPartition;
  95.                    break;
  96.             default:
  97.                found = FALSE;
  98.          }
  99.       }
  100.  
  101.       /* If invalid partition type or valid found and < 32K in size */
  102.       /* then indicate not a valid partition.                       */
  103.  
  104.       i--;
  105.       if (!found || pMBR->PartitionTable[i].NumSectors < 64)
  106.          pVolCB->Flags |= vf_NoDOSPartition;    /* Partition invalid */
  107.       else
  108.       {
  109.          if ((DDFlags & DDF_INIT_TIME) &&                            /*@V64818*/
  110.                                  (pVolCB->Flags & vf_FTPartition))   /*@V64818*/
  111.             NumFTPartitions ++;
  112.  
  113.          pVolCB->PartitionType = pMBR->PartitionTable[i].SysIndicator;
  114.  
  115.          /* Make sure end of partition within 4G sectors of start of disk */
  116.          if (f_add32(pMBR->PartitionTable[i].RelativeSectors,
  117.              pMBR->PartitionTable[i].NumSectors) == 0)
  118.                  fBigFat |= vf_TooBig;
  119.  
  120.          pVolCB->MediaBPB.HiddenSectors=pMBR->PartitionTable[i].RelativeSectors;
  121.  
  122.          if (pMBR->PartitionTable[i].NumSectors <= (ULONG) 0xffff)
  123.             pVolCB->MediaBPB.TotalSectors=(USHORT)pMBR->PartitionTable[i].NumSectors;
  124.          else
  125.          {
  126.             pVolCB->MediaBPB.TotalSectors = 0;
  127.             pVolCB->MediaBPB.BigTotalSectors=pMBR->PartitionTable[i].NumSectors;
  128.          }
  129.  
  130.          /* Return RBA of Volume Boot Sector and NumSectors in Partition */
  131.  
  132.          *VolBootRBA = pVolCB->MediaBPB.HiddenSectors;
  133.  
  134.          *NumSectors = pMBR->PartitionTable[i].NumSectors;
  135.       }
  136.    }
  137.    if (pVolCB->Flags & vf_NoDOSPartition)
  138.       return(ERROR);
  139.    else
  140.       return(NO_ERROR);
  141. }
  142.  
  143.  
  144.  
  145. /*--------------------------------------------------------------------------
  146. ;
  147. ;** Process_Boot - Process the boot sector of the fixed disk
  148. ;
  149. ;   Process_Boot examines the boot sector read off the fixed disk
  150. ;   and builds a BPB for it in the BDS for the drive. If the boot
  151. ;   sector is not valid, it assumes a default BPB from a table.
  152. ;   If this is a > 32M partition and the boot sector does not have
  153. ;   a valid BPB, 'C' is returned. The caller should then set up a
  154. ;   "minimum" BPB and set the fTooBig bit.
  155. ;
  156. ;   USHORT Process_Boot (NPVOLCB pVolCB, ULONG SectorsInPartition)
  157. ;
  158. ;   ENTRY:    pVolCB             - input pointer to VolCB
  159. ;             SectorsInPartition - Number of sectors in partition
  160. ;
  161. ;   RETURN:   USHORT           - Result Code (NO_ERROR if valid partition)
  162. ;
  163. ;   EFFECTS:
  164. ;
  165. ;   NOTES:    Global variable ScratchBuffer contains boot sector
  166. ;             on input.
  167. ;
  168. ;----------------------------------------------------------------------------*/
  169.  
  170. USHORT Process_Boot(pVolCB, SectorsInPartition)
  171.  
  172. NPVOLCB  pVolCB;
  173. ULONG    SectorsInPartition;
  174.  
  175. {
  176.    USHORT rc, i;
  177.    ULONG  TotalSectors, temp;
  178.    USHORT Unknown = YES;
  179.    PDOSBOOTREC pBootRec = (PDOSBOOTREC) ScratchBuffer;
  180.  
  181.    /*--------------------------------------------------------*/
  182.    /* Check for a valid boot sector and use the BPB in it to */
  183.    /* build the MediaBPB in the VolCB.  It is assumed that   */
  184.    /* ONLY SectorsPerCluster, NumFatSectors, MaxDirEntries   */
  185.    /* and MediaType need to be set.                          */
  186.    /*--------------------------------------------------------*/
  187.  
  188.    if (Is_BPB_Boot(pVolCB,pBootRec) == NO_ERROR)                     /*@V64818*/
  189.    {
  190.       pVolCB->MediaBPB.MediaType = pBootRec->bpb.MediaType;
  191.       if (pBootRec->bpb.TotalSectors != 0)
  192.           TotalSectors = pBootRec->bpb.TotalSectors;
  193.       else
  194.           TotalSectors = pBootRec->bpb.BigTotalSectors;
  195.  
  196.       /* Make sure there are enough sectors for the boot sector, */
  197.       /* plus the FAT sectors plus the directory sectors.        */
  198.  
  199.       if (TotalSectors > (1 + (pBootRec->bpb.NumFATSectors * 2) +
  200.                          (pBootRec->bpb.MaxDirEntries / 16)))
  201.       {
  202.         pVolCB->MediaBPB.NumFATSectors = pBootRec->bpb.NumFATSectors;
  203.         pVolCB->MediaBPB.MaxDirEntries = pBootRec->bpb.MaxDirEntries;
  204.         pVolCB->MediaBPB.SectorsPerCluster = pBootRec->bpb.SectorsPerCluster;
  205.  
  206.         /* Calculate sectors left for data sectors */
  207.  
  208.         TotalSectors = TotalSectors - (1 + (pBootRec->bpb.NumFATSectors * 2) +
  209.                                       (pBootRec->bpb.MaxDirEntries / 16));
  210.  
  211.         if ( (pVolCB->PartitionType != PARTITION_IFS) &&             /*@V64818*/
  212.              !(pVolCB->Flags & vf_FTPartition)        &&             /*@V64818*/
  213.              (pVolCB->MediaBPB.SectorsPerCluster)     &&             /*@V64818*/
  214.              (TotalSectors / pVolCB->MediaBPB.SectorsPerCluster) > 4096-10 )
  215.            fBigFat |= vf_Big;           /* Set FBIG if 16 bit FAT */
  216.  
  217.         Unknown = NO;
  218.       }
  219.    }
  220.  
  221.    if (Unknown == YES)
  222.    {
  223.       /* If IFS, zero out FAT related fields */
  224.  
  225.       if (pVolCB->PartitionType == PARTITION_IFS)
  226.       {
  227.          pVolCB->MediaBPB.SectorsPerCluster = 0;
  228.          pVolCB->MediaBPB.ReservedSectors = 0;
  229.          pVolCB->MediaBPB.NumFATs = 0;
  230.          pVolCB->MediaBPB.MaxDirEntries = 512;
  231.          if (pVolCB->MediaBPB.TotalSectors != 0)
  232.             pVolCB->MediaBPB.BigTotalSectors = pVolCB->MediaBPB.TotalSectors;
  233.          pVolCB->MediaBPB.TotalSectors = 0;
  234.          pVolCB->MediaBPB.MediaType = MEDIA_FIXED_DISK;              /*@V64818*/
  235.          pVolCB->MediaBPB.NumFATSectors = 0;
  236.       }
  237.       else
  238.       {
  239.  
  240.          /* Find appropriate DiskTable entry based on SectorsInPartition */
  241.  
  242.          for (i = 0; i < DISKTABLECOUNT; i++)
  243.            if (SectorsInPartition <= DiskTable[i].NumSectors)
  244.               break;
  245.  
  246.          fBigFat = DiskTable[i].Flags;
  247.          pVolCB->MediaBPB.MaxDirEntries = DiskTable[i].MaxDirEntries;
  248.          pVolCB->MediaBPB.SectorsPerCluster= DiskTable[i].SectorsPerCluster;
  249.          pVolCB->MediaBPB.MediaType = MEDIA_FIXED_DISK;
  250.  
  251.          /* Calculate number of FAT table sectors */
  252.  
  253.          if (fBigFat & vf_Big)
  254.          {
  255.             temp = (pVolCB->MediaBPB.SectorsPerCluster * 256) + 2;
  256.             pVolCB->MediaBPB.NumFATSectors = (SectorsInPartition -
  257.                ((pVolCB->MediaBPB.MaxDirEntries / 16) + 1) + /* Dir + Reserved*/
  258.                temp - 1 +
  259.                (pVolCB->MediaBPB.SectorsPerCluster * 2)) / temp;
  260.          }
  261.          else
  262.          {
  263.             TotalSectors = SectorsInPartition +
  264.                            pVolCB->MediaBPB.SectorsPerCluster - 1;
  265.  
  266.             TotalSectors >>= DiskTable[i].Log2SectorsPerCluster;
  267.  
  268.             TotalSectors = ((TotalSectors + 1) & (0xFFFFFFFE)) + 2;
  269.  
  270.             temp = TotalSectors;
  271.  
  272.             TotalSectors >>= 1;
  273.  
  274.             pVolCB->MediaBPB.NumFATSectors = (TotalSectors + temp + 511) / 512;
  275.          }
  276.       }
  277.    }
  278.  
  279.    pVolCB->Flags |= vf_BigFat;
  280.  
  281.    pVolCB->RecBPB = pVolCB->MediaBPB;   /* Copy media BPB to recommended BPB */
  282. }
  283.  
  284.  
  285. /*--------------------------------------------------------------------------
  286. ;
  287. ;** BPBFromBoot - Get BPB from the boot sector passed in
  288. ;
  289. ;   BPBFromBoot builds a BPB for the disk/media type from the boot
  290. ;   sector passed to it.
  291. ;
  292. ;   USHORT BPBFromBoot (NPVOLCB pVolCB, PDOSBOOTREC pBootSector)
  293. ;
  294. ;   ENTRY:    pVolCB           - VolCB for the drive
  295. ;             pBootSector      - DOS Boot Sector
  296. ;
  297. ;   RETURN:   USHORT           - Result Code (NO_ERROR if valid boot sector)
  298. ;
  299. ;   EFFECTS:
  300. ;
  301. ;   NOTES:  This code assumes that the media you are attempting to
  302. ;           build on is
  303. ;               a)  a DOS disk
  304. ;               b)  if it is a >2.x disk, the boot sector
  305. ;                   lies at sector 1 on track 0 (head 0).  The first
  306. ;                   3 bytes are a JMP, the next 8 bytes are a media
  307. ;                   ID ASCII string, and the 11 bytes following that
  308. ;                   are the BPB for that disk.
  309. ;               c)  if the above conditions (3 byte jump, 8 ascii ID
  310. ;                   string) are not met, then we assume the media is
  311. ;                   a DOS 1.x disk.  On a 1.x disk sector 2 on
  312. ;                   track 0 (head 0) contains the first FAT sector.
  313. ;                   The first byte of the first FAT sector contains
  314. ;                   the "FAT ID byte" which is the media ID byte for
  315. ;                   this disk.
  316. ;
  317. ;----------------------------------------------------------------------------*/
  318. USHORT FAR f_BPBFromBoot (pVolCB, pBootSector)
  319.  
  320. NPVOLCB     pVolCB;
  321. PDOSBOOTREC pBootSector;
  322. {
  323.    return(BPBFromBoot (pVolCB, pBootSector));
  324. }
  325.  
  326. USHORT BPBFromBoot (pVolCB, pBootSector)
  327.  
  328. NPVOLCB pVolCB;
  329. PDOSBOOTREC pBootSector;
  330. {
  331.    USHORT rc = NO_ERROR;
  332.  
  333.    if (!(pVolCB->Flags & vf_ReturnFakeBPB))    /* Do nothing if this is set */
  334.    {
  335.       if ( (rc = Is_BPB_Boot(pVolCB,pBootSector)) == NO_ERROR)       /*@V64818*/
  336.       {
  337.          BootBPB_To_MediaBPB (pVolCB, pBootSector);
  338.  
  339.          /*------------------------------------------------------------------
  340.          ; In pre-DOS 3.20 versions of Format, there was a     that caused
  341.          ; the sectors per cluster field in the BPB in the boot sector to
  342.          ; be set to 2 even when the medium was single-sided. We "fix" this
  343.          ; by setting the field to 1 on the diskettes that may have been
  344.          ; affected. This will ensure that whatever has been recorded on
  345.          ; those media will remain intact.  Also, we fix the     in the
  346.          ; EZ-FORMAT utility which incorrectly set the hidden sectors field
  347.          ; to 1. We'll reset it back to 0 so those diskettes can be read.
  348.          ------------------------------------------------------------------*/
  349.  
  350.          if (pVolCB->pUnitCB->UnitInfo.UnitFlags & UF_REMOVABLE)
  351.          {
  352.  
  353.            if ( ((pVolCB->MediaBPB.MediaType == MEDIA_160KB) ||
  354.                  (pVolCB->MediaBPB.MediaType == MEDIA_180KB)) &&
  355.                  (GetBootVersion(pBootSector) < 32) )
  356.  
  357.                 pVolCB->MediaBPB.SectorsPerCluster = 1;
  358.  
  359.  
  360.            if ( (pVolCB->MediaBPB.HiddenSectors != 0) &&
  361.                 ( *((PBYTE)pBootSector + 0xA1) == 'F') &&
  362.                 ( *((PBYTE)pBootSector + 0xA2) == 'a') &&
  363.                 ( *((PBYTE)pBootSector + 0xA3) == 'l') &&
  364.                 ( *((PBYTE)pBootSector + 0xA4) == 'k') )
  365.  
  366.                 pVolCB->MediaBPB.HiddenSectors = 0;
  367.          }
  368.       }
  369.    }
  370.  
  371.    return(rc);
  372. }
  373.  
  374. /*--------------------------------------------------------------------------
  375. ;
  376. ;** BPBFromScratch - Build a BPB for the disk
  377. ;
  378. ;   BPBFromScratch builds a BPB for the drive where the boot sector
  379. ;   contains an invalid BPB in it.
  380. ;
  381. ;   For fixed disks, the partition table is read and from it the
  382. ;   location of the boot sector is obtained. The boot sector is then
  383. ;   read and the BPB built from there. An error is returned if the
  384. ;   partition table is invalid or is too small (< 32K bytes).
  385. ;
  386. ;   USHORT BPBFromScratch (NPVOLCB pVolCB, PRP pRP)
  387. ;
  388. ;   ENTRY:    pVolCB           - VolCB for the drive
  389. ;             pRP              - Request Packet
  390. ;
  391. ;   RETURN:   USHORT           - Packet Status
  392. ;
  393. ;   EFFECTS:
  394. ;
  395. ;----------------------------------------------------------------------------*/
  396. USHORT FAR f_BPBFromScratch (pVolCB)
  397.  
  398. NPVOLCB  pVolCB;
  399.  
  400. {
  401.    return(BPBFromScratch(pVolCB));
  402. }
  403.  
  404.  
  405. USHORT BPBFromScratch (pVolCB)
  406.  
  407. NPVOLCB  pVolCB;
  408.  
  409. {
  410.    UCHAR   MediaType;
  411.    USHORT  rc;
  412.    ULONG   VolBootRBA, NumSectors;
  413.  
  414.    /* Wait for the ScratchBuffer to be free before doing a read */
  415.  
  416.    f_SWait (&ScratchBufSem);
  417.  
  418.    if (pVolCB->pUnitCB->UnitInfo.UnitFlags & UF_REMOVABLE)      /* If floppy drive */
  419.    {
  420.       /* Read in the first FAT sector */
  421.  
  422.       if ((rc = ReadSecInScratch_RBA (pVolCB, 1L, 0)) == NO_ERROR)
  423.       {
  424.          MediaType = ScratchBuffer[0];
  425.          if (pVolCB->MediaBPB.MediaType != MediaType)
  426.          {
  427.             switch(MediaType)
  428.             {
  429.                case MEDIA_144MB:                         /* 1.44MB & 2.88MB */
  430.                      if (pVolCB->RecBPB.SectorsPerTrack == 18)
  431.                         pVolCB->MediaBPB = BPB_144MB;    /* 1.44 MB */
  432.                      else
  433.                         pVolCB->MediaBPB = BPB_288MB;    /* 2.88 MB */
  434.                      break;
  435.  
  436.                case MEDIA_12MB:                          /* 1.2MB & 720 KB */
  437.                      if (pVolCB->RecBPB.SectorsPerTrack == 15)
  438.                         pVolCB->MediaBPB = BPB_12MB;     /* 1.2 MB */
  439.                      else
  440.                         pVolCB->MediaBPB = BPB_720KB;    /* 720 KB */
  441.                      break;
  442.  
  443.                case MEDIA_360KB:
  444.                         pVolCB->MediaBPB = BPB_360KB;
  445.                         break;
  446.  
  447.                case MEDIA_320KB:
  448.                         pVolCB->MediaBPB = BPB_320KB;
  449.                         break;
  450.  
  451.                case MEDIA_180KB:
  452.                         pVolCB->MediaBPB = BPB_180KB;
  453.                         break;
  454.  
  455.                case MEDIA_160KB:
  456.                         pVolCB->MediaBPB = BPB_160KB;
  457.                         break;
  458.  
  459.                default:
  460.                         rc = STDON + STERR + ERROR_I24_NOT_DOS_DISK;
  461.             }
  462.          }
  463.       }
  464.    }
  465.    else  /* Fixed disk */
  466.    {
  467.       /* Read RBA 0 - Master Boot Record  */
  468.  
  469.       if ((rc = ReadSecInScratch_RBA (pVolCB, 0, 1)) == NO_ERROR)
  470.       {
  471.          if ((rc = Process_Partition (pVolCB, &VolBootRBA, &NumSectors))
  472.                                                             == NO_ERROR)
  473.          {
  474.             if ((rc = ReadSecInScratch_RBA (pVolCB, VolBootRBA, 1))
  475.                                                             == NO_ERROR)
  476.                Process_Boot (pVolCB, NumSectors);
  477.          }
  478.          else
  479.          {
  480.             pVolCB->MediaBPB = BPB_Minimum;      /* Setup minimum BPB */
  481.             pVolCB->RecBPB = pVolCB->MediaBPB;   /* Copy MinBPB to recommended*/
  482.             rc = NO_ERROR;
  483.          }
  484.       }
  485.    }
  486.  
  487.    f_SSig (&ScratchBufSem);     /* Release scratch buffer */
  488.  
  489.    return (rc);
  490. }
  491.  
  492. /*--------------------------------------------------------------------------
  493. ;
  494. ;**  BootBPB_To_MediaBPB
  495. ;
  496. ;   Copies the BPB from the passed boot sector to the media BPB in the
  497. ;   Volume Control Block. If the boot sector is older than DOS 3.2,
  498. ;   the 12 byte extended BPB is not copied because it may contain garbage.
  499. ;
  500. ;   VOID BootBPB_to_MediaBPB (NPVOLCB pVolCB, PDOSBOOTREC pBootSector
  501. ;                              USHORT Type)
  502. ;
  503. ;   ENTRY:    pVolCB           - input pointer to VolCB
  504. ;             pBootSector      - Boot Sector
  505. ;             Type             - 0 = disk, 1 = diskette
  506. ;
  507. ;   RETURN:   VOID
  508. ;
  509. ;   EFFECTS:
  510. ;
  511. ;   NOTES:
  512. ;
  513. --------------------------------------------------------------------------*/
  514.  
  515. VOID BootBPB_To_MediaBPB (pVolCB, pBootSector)
  516.  
  517. NPVOLCB    pVolCB;
  518. PDOSBOOTREC pBootSector;
  519. {
  520.    USHORT  i;
  521.    BOOL    done = FALSE;
  522.    USHORT  version = 0;
  523.  
  524.    version = GetBootVersion(pBootSector);
  525.  
  526.  
  527. /* There's a     in DR DOS which incorrectly adds the partition offset */
  528. /* to the hidden sectors field in the BPB.  We recognize this case     */
  529. /* by checking for version 3.3 and subtracting out the partition offset.*/
  530.  
  531.    if ( (version == 33) &&
  532.         ( !(pVolCB->pUnitCB->UnitInfo.UnitFlags & UF_REMOVABLE) ) &&
  533.         (pVolCB->PartitionOffset > 0) &&
  534.         (pBootSector->bpb.HiddenSectors ==
  535.               (pVolCB->MediaBPB.HiddenSectors + pVolCB->PartitionOffset) ) )
  536.  
  537.            pBootSector->bpb.HiddenSectors = pVolCB->MediaBPB.HiddenSectors;
  538.  
  539.  
  540.    /* Boot sector < DOS 4.0 (and known version!) */
  541.  
  542.    if ((version > 0) && (version < 40))                             /*@V108555*/
  543.       if (version != 33)     //P62137
  544.           pBootSector->bpb.HiddenSectors &= 0xffffff7f;
  545.  
  546.    /* Copy over BPB */
  547.  
  548.    pVolCB->MediaBPB = pBootSector->bpb;
  549.  
  550.  
  551.    /* If version < DOS 3.3 (and known!) or its a diskette and using */
  552.    /* TotalSectors then zero out the extended portion of the BPB    */
  553.  
  554.    if ( ((version > 0) && (version < 33)) ||                        /*@V108555*/
  555.       ((pVolCB->pUnitCB->UnitInfo.UnitFlags & UF_REMOVABLE) &&
  556.        (pBootSector->bpb.TotalSectors != 0))  )
  557.    {
  558.       pVolCB->MediaBPB.HiddenSectors &= 0x0000FFFF;
  559.       pVolCB->MediaBPB.BigTotalSectors = 0;
  560.       for (i = 0; i < sizeof(pVolCB->MediaBPB.Reserved_1); i++)
  561.          pVolCB->MediaBPB.Reserved_1[i] = 0;
  562.    }
  563. }
  564.  
  565. /*--------------------------------------------------------------------------
  566. ;
  567. ;** f_BPBfromGeom - Initialize BPB using Geometry info
  568. ;
  569. ;   Initialize the BPB for a VolCB from the Geometry info returned by
  570. ;   the adapter driver.
  571. ;
  572. ;   VOID InitBPBfromGeom (NPVOLCB pVolCB, NPBPB pBPB, PGEOMETRY pGeometry)
  573. ;
  574. ;   ENTRY:    pVolCB           - input pointer to VolCB
  575. ;             pBPB             - pointer to BPB to fill in
  576. ;             pGeometry        - pointer to Geometry info
  577. ;
  578. ;   RETURN:   VOID
  579. ;
  580. ;   EFFECTS:
  581. ;
  582. ;----------------------------------------------------------------------------*/
  583.  
  584. /* Moved from DMINIT */                                              /*@V63867*/
  585.                                                                      /*@V63867*/
  586. VOID FAR f_BPBfromGeom (pVolCB, pBPB, pGeometry)                     /*@V63867*/
  587.  
  588. NPVOLCB   pVolCB;
  589. NPBPB     pBPB;
  590. PGEOMETRY pGeometry;
  591.  
  592. {
  593.    ULONG  TotalCylinders, TotalSectors, TotalDataSectors, temp;
  594.    ULONG  SectorsPerCyl;                                             /*@V63867*/
  595.    USHORT i;
  596.    NPUNITCB pUnitCB;
  597.  
  598.    pUnitCB = pVolCB->pUnitCB;
  599.    TotalSectors = pGeometry->TotalSectors;
  600.  
  601.    /* If removable SCSI device which doesnt return geometry data when */
  602.    /* no media is in the drive, then just put a default size in.      */
  603.  
  604.    if (TotalSectors == 0)                                            /*@V46569*/
  605.       TotalSectors = 5760;                                           /*@V46569*/
  606.  
  607.    pUnitCB->LastRBA = TotalSectors;
  608.  
  609.    /* If the unit is removable and it's not bigger than a 2.88M drive  */
  610.    /* then use one of the canned BPBs we have for the specified drive. */
  611.  
  612.    if ((pUnitCB->UnitInfo.UnitFlags & UF_REMOVABLE) && (TotalSectors <= 5760))
  613.    {
  614.       pVolCB->NumPhysCylinders = pGeometry->TotalCylinders;
  615.       pVolCB->NumLogCylinders  = pGeometry->TotalCylinders;
  616.       pVolCB->BootRecCyl       = 0;                                  /*@V89787*/
  617.  
  618.       switch (TotalSectors)
  619.       {
  620.           case 720:         /* 5.25 inch - 360 KB Drive */
  621.             *pBPB = BPB_360KB;
  622.             break;
  623.  
  624.           case 1440:        /* 3.5 inch - 720 KB Drive */
  625.             *pBPB = BPB_720KB;
  626.             break;
  627.  
  628.           case 2400:        /* 5.25 inch - 1.2M Drive */
  629.             *pBPB = BPB_12MB;
  630.             break;
  631.  
  632.           case 2880:        /* 3.5 inch - 1.44M Drive */
  633.             *pBPB = BPB_144MB;
  634.             break;
  635.  
  636.           case 5760:        /* 3.5 inch - 2.88M Drive */
  637.             *pBPB = BPB_288MB;
  638.             break;
  639.  
  640.           default:
  641.             *pBPB = BPB_144MB;
  642.             break;
  643.       }
  644.    }
  645.  
  646.    /* If it's a fixed disk, or a removable drive we dont have a canned */
  647.    /* BPB for, then calculate the rest of the BPB.                     */
  648.  
  649.    else
  650.    {
  651.       /* If the drive doesnt return any Geometry information other *//*@V63867*/
  652.       /* than TotalSectors, then create a virtual geometry for     *//*@V63867*/
  653.       /* the drive, else copy the Geometry data into the BPB.      *//*@V63867*/
  654.                                                                      /*@V63867*/
  655.       if (pGeometry->NumHeads != 0                                   /*@V63867*/
  656.            && pGeometry->BytesPerSector != 0                         /*@V63867*/
  657.                && pGeometry->SectorsPerTrack != 0)                   /*@V63867*/
  658.       {                                                              /*@V63867*/
  659.          pBPB->BytesPerSector  = pGeometry->BytesPerSector;          /*@V63867*/
  660.          pBPB->NumHeads        = pGeometry->NumHeads;                /*@V63867*/
  661.          pBPB->SectorsPerTrack = pGeometry->SectorsPerTrack;         /*@V63867*/
  662.       }                                                              /*@V63867*/
  663.       else                                                           /*@V63867*/
  664.       {                                                              /*@V63867*/
  665.          pBPB->BytesPerSector  = 512;                                /*@V63867*/
  666.          pBPB->NumHeads        = 64;                                 /*@V63867*/
  667.          pBPB->SectorsPerTrack = 32;                                 /*@V63867*/
  668.       }                                                              /*@V63867*/
  669.                                                                      /*@V63867*/
  670.       /* Make TotalSectors consistent with CHS geometry     */       /*@V63867*/
  671.       /*                                                    */       /*@V63867*/
  672.       /* This prevents later problems during FORMAT if the  */       /*@V63867*/
  673.       /* last partial cylinder is accessed.                 */       /*@V63867*/
  674.                                                                      /*@V63867*/
  675.       TotalSectors  = pGeometry->TotalSectors;                       /*@V63867*/
  676.                                                                      /*@V63867*/
  677.       SectorsPerCyl = (ULONG) pBPB->SectorsPerTrack *                /*@V63867*/
  678.                       (ULONG) pBPB->NumHeads;                        /*@V63867*/
  679.                                                                      /*@V63867*/
  680.       TotalCylinders = TotalSectors / SectorsPerCyl;                 /*@V63867*/
  681.                                                                      /*@V63867*/
  682.       TotalSectors = TotalCylinders * SectorsPerCyl;                 /*@V63867*/
  683.                                                                      /*@V63867*/
  684.       pVolCB->NumLogCylinders  = TotalCylinders;                     /*@V63867*/
  685.       pVolCB->NumPhysCylinders = TotalCylinders;                     /*@V63867*/
  686.       pVolCB->BootRecCyl       = 0;                                  /*@V89787*/
  687.                                                                      /*@V63867*/
  688.       if (TotalSectors > 0xffff)                                     /*@V63867*/
  689.       {                                                              /*@V63867*/
  690.          pBPB->BigTotalSectors = TotalSectors;                       /*@V63867*/
  691.          pBPB->TotalSectors = 0;                                     /*@V63867*/
  692.       }                                                              /*@V63867*/
  693.       else                                                           /*@V63867*/
  694.       {                                                              /*@V63867*/
  695.          pBPB->BigTotalSectors = 0;                                  /*@V63867*/
  696.          pBPB->TotalSectors = TotalSectors;                          /*@V63867*/
  697.       }                                                              /*@V63867*/
  698.                                                                      /*@V63867*/
  699.  
  700.       /* If it's a removable drive, then calculate the file system fields */
  701.       /* i.e. NumFATSectors, etc. in the BPB.                             */
  702.  
  703.       if (pUnitCB->UnitInfo.UnitFlags & UF_REMOVABLE)
  704.       {
  705.          /* Find appropriate DiskTable entry based on TotalSectors */
  706.  
  707.          for (i = 0; i < DISKTABLECOUNT; i++)
  708.            if (TotalSectors <= DiskTable[i].NumSectors)
  709.               break;
  710.  
  711.          fBigFat = DiskTable[i].Flags;
  712.          pBPB->ReservedSectors = 1;
  713.          pBPB->MaxDirEntries = DiskTable[i].MaxDirEntries;
  714.          pBPB->SectorsPerCluster = DiskTable[i].SectorsPerCluster;
  715.          pBPB->NumFATs = 2;
  716.          pBPB->MediaType = 0xF0;
  717.  
  718.          /* Calculate number of FAT table sectors */
  719.  
  720.          if (fBigFat & vf_Big)
  721.          {
  722.             temp = (pBPB->SectorsPerCluster * 256) + 2;
  723.             pBPB->NumFATSectors = (TotalSectors -
  724.                ((pBPB->MaxDirEntries / 16) + 1) +        /* Dir + Reserved*/
  725.                temp - 1 + (pBPB->SectorsPerCluster * 2)) / temp;
  726.          }
  727.          else
  728.          {
  729.             TotalDataSectors = TotalSectors + pBPB->SectorsPerCluster - 1;
  730.  
  731.             TotalDataSectors >>= DiskTable[i].Log2SectorsPerCluster;
  732.  
  733.             TotalDataSectors = ((TotalDataSectors + 1) & (0xFFFFFFFE)) + 2;
  734.  
  735.             temp = TotalDataSectors;
  736.  
  737.             TotalDataSectors >>= 1;
  738.  
  739.             pBPB->NumFATSectors = (TotalDataSectors + temp + 511) / 512;
  740.          }
  741.       }
  742.    }
  743. }
  744.  
  745. /*--------------------------------------------------------------------------
  746. ;
  747. ;** Is_BPB_Boot - Is this a valid boot sector ?
  748. ;
  749. ;   ScratchBuffer points to the boot sector.  In theory, the BPB is
  750. ;   correct.  We can, therefore, get all the relevant information
  751. ;   from the media (those that we cannot get from the partition
  752. ;   table) if we can recognize it.
  753. ;
  754. ;   USHORT Is_BPB_Boot (PDOSBOOTREC pBootSector)
  755. ;
  756. ;   ENTRY:    pBootSector      - DOS Boot Sector
  757. ;
  758. ;   RETURN:   USHORT           - Result Code (NO_ERROR if valid boot sector)
  759. ;
  760. ;   EFFECTS:
  761. ;
  762. ;   NOTES:
  763. ;
  764. --------------------------------------------------------------------------*/
  765. USHORT Is_BPB_Boot (pVolCB, pBootSector)                             /*@V64818*/
  766.                                                                      /*@V64818*/
  767. PDOSBOOTREC pBootSector;                                             /*@V64818*/
  768. NPVOLCB     pVolCB;                                                  /*@V64818*/
  769. {                                                                    /*@V64818*/
  770.    USHORT rc = NO_ERROR;                                             /*@V64818*/
  771.    UCHAR  MediaType;                                                 /*@V64818*/
  772.    UCHAR  PartType;                                                  /*@V64818*/
  773.                                                                      /*@V64818*/
  774.    /* 1. Make sure short or near jmp is at start of boot sector */   /*@V64818*/
  775.    /* 2.     and high nibble of MediaType in BPB is 0xF         */   /*@V64818*/
  776.    /* 3.         and SectorsPerCluster in BPB is a power of 2   */   /*@V64818*/
  777.                                                                      /*@V64818*/
  778.    MediaType = pBootSector->bpb.MediaType & 0xF0;                    /*@V64818*/
  779.    PartType  = pVolCB->PartitionType;                                /*@V64818*/
  780.                                                                      /*@V64818*/
  781.    if (!((pBootSector->JmpCode == 0xE9) ||                           /*@V64818*/
  782.          (pBootSector->JmpCode == 0xEB && pBootSector->nop == 0x90)))/*@V64818*/
  783.    {                                                                 /*@V64818*/
  784.       rc = ERROR;                                                    /*@V64818*/
  785.    }                                                                 /*@V64818*/
  786.    else if ( !pBootSector->bpb.MaxDirEntries )                       /*@V64818*/
  787.    {                                                                 /*@V64818*/
  788.       rc = ERROR;                                                    /*@V64818*/
  789.    }                                                                 /*@V64818*/
  790.    /* Checks are relaxed for IFS partitions or clones */             /*@V64818*/
  791.    /* of IFS partitions                               */             /*@V64818*/
  792.                                                                      /*@V64818*/
  793.    else if ( PartType == PARTITION_IFS       ||                      /*@V64818*/
  794.              PartType == PARTITION_FTACTIVE  ||                      /*@V64818*/
  795.              PartType == PARTITION_FTINACTIVE   )                    /*@V64818*/
  796.    {                                                                 /*@V64818*/
  797.      if ( MediaType && (MediaType != 0xF0) )                         /*@V64818*/
  798.      {                                                               /*@V64818*/
  799.         rc = ERROR;                                                  /*@V64818*/
  800.      }                                                               /*@V64818*/
  801.    }                                                                 /*@V64818*/
  802.    else                                                              /*@V64818*/
  803.    {                                                                 /*@V64818*/
  804.      if ( MediaType != 0xF0 )                                        /*@V64818*/
  805.      {                                                               /*@V64818*/
  806.         rc = ERROR;                                                  /*@V64818*/
  807.      }                                                               /*@V64818*/
  808.      else if ( !PowerOF2(pBootSector->bpb.SectorsPerCluster) )       /*@V64818*/
  809.      {                                                               /*@V64818*/
  810.         rc = ERROR;                                                  /*@V64818*/
  811.      }                                                               /*@V64818*/
  812.    }                                                                 /*@V64818*/
  813.                                                                      /*@V64818*/
  814.    return(rc);                                                       /*@V64818*/
  815. }                                                                    /*@V64818*/
  816.  
  817. /*--------------------------------------------------------------------------
  818. ;
  819. ;** GetBootVersion - Get boot version from boot record
  820. ;
  821. ;   Get the boot version of the DOS boot sector which appears as a
  822. ;   set of characters in the form 'XX.XX' after the 'DOS' or 'IBM'
  823. ;   characters.
  824. ;
  825. ;   USHORT GetBootVersion (PDOSBOOTREC pBootSector)
  826. ;
  827. ;   ENTRY:    pBootSector      - DOS Boot Sector
  828. ;
  829. ;   RETURN:   USHORT           - Boot Version
  830. ;
  831. ;   EFFECTS:
  832. ;
  833. ;   NOTES:
  834. ;
  835. --------------------------------------------------------------------------*/
  836. USHORT GetBootVersion (pBootSector)
  837.  
  838. PDOSBOOTREC pBootSector;
  839. {
  840.    USHORT i;
  841.    USHORT version = 0;
  842.  
  843.    for (i = 0; i < sizeof(pBootSector->Release); i++)
  844.    {
  845.       if (pBootSector->Release[i] >= '0' && pBootSector->Release[i] <= '9')
  846.       {
  847.          version = version * 10;
  848.          version = version + (pBootSector->Release[i] - '0');
  849.          if (pBootSector->Release[i+1] == '.')
  850.          {
  851.             version = version * 10;
  852.             version = version + (pBootSector->Release[i+2] - '0');
  853.             break;
  854.          }
  855.       }
  856.    }
  857.    return(version);
  858. }
  859.  
  860.  
  861.  
  862.  
  863.