⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 initdisk.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 3 页
字号:
             partitionName, pEntry->FileSystem);      printCHS(" start ", &chs);      printCHS(", end ", &end);      printf("\n");#endif    }    /*       here we have a partition table in our hand !!     */    partitionsToIgnore |= 1 << i;    DosDefinePartition(driveParam, partitionStart, pEntry,                       extendedPartNo, i);    if (scan_type == SCAN_PRIMARYBOOT || scan_type == SCAN_PRIMARY)    {      return partitionsToIgnore;    }  }  return partitionsToIgnore;}void BIOS_drive_reset(unsigned drive);int Read1LBASector(struct DriveParamS *driveParam, unsigned drive,                   ULONG LBA_address, void * buffer){  static struct _bios_LBA_address_packet dap = {    16, 0, 0, 0, 0, 0, 0  };  struct CHS chs;  iregs regs;  int num_retries;/* disabled because this should not happen and if it happens the BIOS   should complain; also there are weird disks around with   CMOS geometry < real geometry */#if 0  if (LBA_address >= driveParam->total_sectors)  {    printf("LBA-Transfer error : address overflow = %lu > %lu max\n",           LBA_address + 1, driveParam->total_sectors);    return 1;  }#endif  for (num_retries = 0; num_retries < N_RETRY; num_retries++)  {    regs.d.b.l = drive | 0x80;    if (driveParam->descflags & DF_LBA)    {      dap.number_of_blocks = 1;      dap.buffer_address = buffer;      dap.block_address_high = 0;       /* clear high part */      dap.block_address = LBA_address;  /* clear high part */      /* Load the registers and call the interrupt. */      regs.a.x = LBA_READ;      regs.si = FP_OFF(&dap);      regs.ds = FP_SEG(&dap);    }    else    {                           /* transfer data, using old bios functions */      LBA_to_CHS(&chs, LBA_address, driveParam);      /* avoid overflow at end of track */      if (chs.Cylinder > 1023)      {        printf("LBA-Transfer error : cylinder %u > 1023\n", chs.Cylinder);        return 1;      }      regs.a.x = 0x0201;      regs.b.x = FP_OFF(buffer);      regs.c.x =          ((chs.Cylinder & 0xff) << 8) + ((chs.Cylinder & 0x300) >> 2) +          chs.Sector;      regs.d.b.h = chs.Head;      regs.es = FP_SEG(buffer);    }                           /* end of retries */    init_call_intr(0x13, &regs);    if ((regs.flags & FLG_CARRY) == 0)      break;    BIOS_drive_reset(driveParam->driveno);  }  return regs.flags & FLG_CARRY ? 1 : 0;}/* Load the Partition Tables and get information on all drives */int ProcessDisk(int scanType, unsigned drive, int PartitionsToIgnore){  struct PartTableEntry PTable[4];  ULONG RelSectorOffset;  ULONG ExtendedPartitionOffset;  int iPart;  int strangeHardwareLoop;  int num_extended_found = 0;  struct DriveParamS driveParam;  /* Get the hard drive parameters and ensure that the drive exists. */  /* If there was an error accessing the drive, skip that drive. */  if (!LBA_Get_Drive_Parameters(drive, &driveParam))  {    printf("can't get drive parameters for drive %02x\n", drive);    return PartitionsToIgnore;  }  RelSectorOffset = 0;          /* boot sector */  ExtendedPartitionOffset = 0;  /* not found yet */  /* Read the Primary Partition Table. */ReadNextPartitionTable:  strangeHardwareLoop = 0;strange_restart:  if (Read1LBASector      (&driveParam, drive, RelSectorOffset, InitDiskTransferBuffer))  {    printf("Error reading partition table drive %02x sector %lu", drive,           RelSectorOffset);    return PartitionsToIgnore;  }  if (!ConvPartTableEntryToIntern(PTable, InitDiskTransferBuffer))  {    /* there is some strange hardware out in the world,       which returns OK on first read, but the data are       rubbish. simply retrying works fine.       there is no logic behind this, but it works TE */    if (++strangeHardwareLoop < 3)      goto strange_restart;    printf("illegal partition table - drive %02x sector %lu\n", drive,           RelSectorOffset);    return PartitionsToIgnore;  }  if (scanType == SCAN_PRIMARYBOOT ||      scanType == SCAN_PRIMARY ||      scanType == SCAN_PRIMARY2 || num_extended_found != 0)  {    PartitionsToIgnore = ScanForPrimaryPartitions(&driveParam, scanType,                                                  PTable, RelSectorOffset,                                                  PartitionsToIgnore,                                                  num_extended_found);  }  if (scanType != SCAN_EXTENDED)  {    return PartitionsToIgnore;  }  /* scan for extended partitions now */  PartitionsToIgnore = 0;  for (iPart = 0; iPart < 4; iPart++)  {    if (IsExtPartition(PTable[iPart].FileSystem))    {      RelSectorOffset = ExtendedPartitionOffset + PTable[iPart].RelSect;      if (ExtendedPartitionOffset == 0)      {        ExtendedPartitionOffset = PTable[iPart].RelSect;	/* grand parent LBA -> all children and grandchildren LBA */        ExtLBAForce = (PTable[iPart].FileSystem == EXTENDED_LBA);      }      num_extended_found++;      if (num_extended_found > 30)      {        printf("found more then 30 extended partitions, terminated\n");        return 0;      }      goto ReadNextPartitionTable;    }  }  return PartitionsToIgnore;}int BIOS_nrdrives(void){  iregs regs;  regs.a.b.h = 0x08;  regs.d.b.l = 0x80;  init_call_intr(0x13, &regs);  if (regs.flags & 1)  {    printf("no hard disks detected\n");    return 0;  }  return regs.d.b.l;}void BIOS_drive_reset(unsigned drive){  iregs regs;  regs.d.b.l = drive | 0x80;  regs.a.b.h = 0;  init_call_intr(0x13, &regs);}/*     thats what MSDN says:    How Windows 2000 Assigns, Reserves, and Stores Drive Letters    ID: q234048    BASIC Disk - Drive Letter Assignment RulesThe following are the basic disk drive letter assignment rules for Windows 2000: Scan all fixed hard disks as they are enumerated, assign drive letters starting with any active primary partitions (if there is one), otherwise,scan the first primary partition on each drive. Assign next available letter starting with C:Repeat scan for all fixed hard disks and removable (JAZ, MO) disks and assign drive letters to all logical drives in an extended partition, or the removable disk(s) as enumerated. Assign next available letter starting with C: Finally, repeat scan for all fixed hard disk drives, and assign drive letters to all remaining primary partitions. Assign next available letter starting with C:Floppy drives. Assign letter starting with A:CD-ROM drives. Assign next available letter starting with D:*************************************************************************Order in Which MS-DOS and Windows Assign Drive LettersID: q51978  MORE INFORMATIONThe following occurs at startup: MS-DOS checks all installed disk devices, assigning the drive letter A to the first physical floppy disk drive that is found.If a second physical floppy disk drive is present, it is assigned drive letter B. If it is not present, a logical drive B is created that uses the first physical floppy disk drive.Regardless of whether a second floppy disk drive is present, MS-DOS then assigns the drive letter C to the primary MS-DOS partition on the first physical hard disk, and then goes on to check for a second hard disk. If a second physical hard disk is found, and a primary partition exists on the second physical drive, the primary MS-DOS partition on the secondphysical hard drive is assigned the letter D. MS-DOS version 5.0, which supports up to eight physical drives, will continue to search for more physical hard disk drives at this point. For example, if a third physical hard disk is found, and a primary partition exists on the third physical drive, the primary MS-DOS partition on the third physical hard drive is assigned the letter E.MS-DOS returns to the first physical hard disk drive and assigns drive letters to any additional logical drives (in extended MS-DOS partitions) on that drive in sequence.MS-DOS repeats this process for the second physical hard disk drive, if present. MS-DOS 5.0 will repeat this process for up to eight physical hard drives, if present. After all logical drives (in extended MS-DOS partitions) have been assigned drive letters, MS-DOS 5.0 returns to the first physical drive and assigns drive letters to any other primary MS-DOS partitions that exist, then searches other physical drives for additional primary MS-DOS partitions. This support for multiple primary MS-DOS partitions was added to version 5.0 for backward compatibility with the previous OEM MS-DOS versions that support multiple primary partitions.After all logical drives on the hard disk(s) have been assigned drive letters, drive letters are assigned to drives installed using DRIVER.SYS or created using RAMDRIVE.SYS in the order in which the drivers are loaded in the CONFIG.SYS file. Which drive letters are assigned to which devices can be influenced by changing the order of the device drivers or, if necessary, by creating "dummy" drive letters with DRIVER.SYS.********************************************************or  as rather well documented, DOS searches 1st) 1 primary patitions on     all drives, 2nd) all extended partitions. that     makes many people (including me) unhappy, as all DRIVES D:,E:...     on 1st disk will move up/down, if other disk with     primary partitions are added/removed, but     thats the way it is (hope I got it right)     TE (with a little help from my friends)     see also above for WIN2000,DOS,MSDNI don't know, if I did it right, but I tried to do it that way. TE***********************************************************************/STATIC void make_ddt (ddt *pddt, int Unit, int driveno, int flags){  pddt->ddt_next = MK_FP(0, 0xffff);  pddt->ddt_logdriveno = Unit;  pddt->ddt_driveno = driveno;  pddt->ddt_type = init_getdriveparm(driveno, &pddt->ddt_defbpb);  pddt->ddt_ncyl = (pddt->ddt_type & 7) ? 80 : 40;  pddt->ddt_descflags = init_readdasd(driveno) | flags;  pddt->ddt_offset = 0;  pddt->ddt_serialno = 0x12345678l;  memcpy(&pddt->ddt_bpb, &pddt->ddt_defbpb, sizeof(bpb));  push_ddt(pddt);}void ReadAllPartitionTables(void){  UBYTE foundPartitions[MAX_HARD_DRIVE];  int HardDrive;  int nHardDisk;  ddt nddt;  static iregs regs;  /* quick adjustment of diskette parameter table */  fmemcpy(int1e_table, *(char FAR * FAR *)MK_FP(0, 0x1e*4), sizeof(int1e_table));  /* enforce min. 9 sectors per track */  if (int1e_table[4] < 9)    int1e_table[4] = 9;  /* and adjust int1e */  setvec(0x1e, (intvec)int1e_table);  /* Setup media info and BPBs arrays for floppies */  make_ddt(&nddt, 0, 0, 0);  /*     this is a quick patch - see if B: exists     test for A: also, need not exist   */  init_call_intr(0x11, &regs);  /* get equipment list *//*if ((regs.AL & 1)==0)*//* no floppy drives installed  */  if ((regs.AL & 1) && (regs.AL & 0xc0))  {    /* floppy drives installed and a B: drive */    make_ddt(&nddt, 1, 1, 0);  }  else  {    /* set up the DJ method : multiple logical drives */    make_ddt(&nddt, 1, 0, DF_MULTLOG);  }  /* Initial number of disk units                                 */  nUnits = 2;  nHardDisk = BIOS_nrdrives();  if (nHardDisk > LENGTH(foundPartitions))    nHardDisk = LENGTH(foundPartitions);  DebugPrintf(("DSK init: found %d disk drives\n", nHardDisk));  /* Reset the drives                                             */  for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)  {    BIOS_drive_reset(HardDrive);    foundPartitions[HardDrive] = 0;  }  if (InitKernelConfig.DLASortByDriveNo == 0)  {    /* printf("Drive Letter Assignment - DOS order\n"); */    /* Process primary partition table   1 partition only      */    for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)    {      foundPartitions[HardDrive] =          ProcessDisk(SCAN_PRIMARYBOOT, HardDrive, 0);      if (foundPartitions[HardDrive] == 0)        foundPartitions[HardDrive] =            ProcessDisk(SCAN_PRIMARY, HardDrive, 0);    }    /* Process extended partition table                      */    for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)    {      ProcessDisk(SCAN_EXTENDED, HardDrive, 0);    }    /* Process primary a 2nd time */    for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)    {      ProcessDisk(SCAN_PRIMARY2, HardDrive, foundPartitions[HardDrive]);    }  }  else  {    UBYTE bootdrv = peekb(0,0x5e0);    /* printf("Drive Letter Assignment - sorted by drive\n"); */    /* Process primary partition table   1 partition only      */    for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)    {      struct DriveParamS driveParam;      if (LBA_Get_Drive_Parameters(HardDrive, &driveParam) &&          driveParam.driveno == bootdrv)      {        foundPartitions[HardDrive] =          ProcessDisk(SCAN_PRIMARYBOOT, HardDrive, 0);        break;      }    }    for (HardDrive = 0; HardDrive < nHardDisk; HardDrive++)    {      if (foundPartitions[HardDrive] == 0)      {        foundPartitions[HardDrive] =          ProcessDisk(SCAN_PRIMARYBOOT, HardDrive, 0);        if (foundPartitions[HardDrive] == 0)          foundPartitions[HardDrive] =            ProcessDisk(SCAN_PRIMARY, HardDrive, 0);      }      /* Process extended partition table                      */      ProcessDisk(SCAN_EXTENDED, HardDrive, 0);      /* Process primary a 2nd time */      ProcessDisk(SCAN_PRIMARY2, HardDrive, foundPartitions[HardDrive]);    }  }}/* disk initialization: returns number of units */COUNT dsk_init(){  printf(" - InitDisk");#ifdef DEBUG  {    iregs regs;    regs.a.x = 0x1112;          /* select 43 line mode - more space for partinfo */    regs.b.x = 0;    init_call_intr(0x10, &regs);  }#endif  /* Reset the drives                                             */  BIOS_drive_reset(0);  ReadAllPartitionTables();  return nUnits;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -