📄 initdisk.c
字号:
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, ®s);
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, ®s);
}
/*
thats what MSDN says:
How Windows 2000 Assigns, Reserves, and Stores Drive Letters
ID: q234048
BASIC Disk - Drive Letter Assignment Rules
The 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 Letters
ID: q51978
MORE INFORMATION
The 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 second
physical 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,MSDN
I 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, ®s); /* 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, ®s);
}
#endif
/* Reset the drives */
BIOS_drive_reset(0);
ReadAllPartitionTables();
return nUnits;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -