335 lines
9.6 KiB
C
335 lines
9.6 KiB
C
/*++
|
||
|
||
Copyright (c) 1989 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
drivesup.c
|
||
|
||
Abstract:
|
||
|
||
This module contains the subroutines for drive support. This includes
|
||
such things as how drive letters are assigned on a particular platform,
|
||
how device partitioning works, etc.
|
||
|
||
Author:
|
||
|
||
Darryl E. Havens (darrylh) 23-Apr-1992
|
||
|
||
Environment:
|
||
|
||
Kernel mode
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
#include "halp.h"
|
||
#include "bugcodes.h"
|
||
|
||
#include "ntddft.h"
|
||
#include "ntdddisk.h"
|
||
#include "ntdskreg.h"
|
||
#include "stdio.h"
|
||
#include "string.h"
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(PAGE, IoAssignDriveLetters)
|
||
#pragma alloc_text(PAGE, IoReadPartitionTable)
|
||
#pragma alloc_text(PAGE, IoSetPartitionInformation)
|
||
#pragma alloc_text(PAGE, IoWritePartitionTable)
|
||
#endif
|
||
|
||
VOID
|
||
IoAssignDriveLetters(
|
||
PLOADER_PARAMETER_BLOCK LoaderBlock,
|
||
PSTRING NtDeviceName,
|
||
OUT PUCHAR NtSystemPath,
|
||
OUT PSTRING NtSystemPathString
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine assigns DOS drive letters to eligible disk partitions
|
||
and CDROM drives. It also maps the partition containing the NT
|
||
boot path to \SystemRoot. In NT, objects are built for all partition
|
||
types except 0 (unused) and 5 (extended). But drive letters are assigned
|
||
only to recognized partition types (1, 4, 6, and 7).
|
||
|
||
Drive letter assignment is done in several stages:
|
||
|
||
1) For each CdRom:
|
||
Determine if sticky letters are assigned and reserve the letter.
|
||
|
||
2) For each disk:
|
||
Determine how many primary partitions and which is bootable.
|
||
Determine which partitions already have 'sticky letters'
|
||
and create their symbolic links.
|
||
Create a bit map for each disk that idicates which partitions
|
||
require default drive letter assignments.
|
||
|
||
3) For each disk:
|
||
Assign default drive letters for the bootable
|
||
primary partition or the first nonbootable primary partition.
|
||
|
||
4) For each disk:
|
||
Assign default drive letters for the partitions in
|
||
extended volumes.
|
||
|
||
5) For each disk:
|
||
Assign default drive letters for the remaining (ENHANCED)
|
||
primary partitions.
|
||
|
||
6) Assign A: and B: to the first two floppies in the system if they
|
||
exist. Then assign remaining floppies next available drive letters.
|
||
|
||
7) Assign drive letters to CdRoms (either sticky or default).
|
||
|
||
Arguments:
|
||
|
||
LoaderBlock - pointer to a loader parameter block.
|
||
|
||
NtDeviceName - pointer to the boot device name string used
|
||
to resolve NtSystemPath.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
//
|
||
// Stub to call extensible routine in ke so that hal vendors
|
||
// don't have to support.
|
||
//
|
||
|
||
HalIoAssignDriveLetters(
|
||
LoaderBlock,
|
||
NtDeviceName,
|
||
NtSystemPath,
|
||
NtSystemPathString
|
||
);
|
||
|
||
} // end IoAssignDriveLetters()
|
||
|
||
NTSTATUS
|
||
IoReadPartitionTable(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN ULONG SectorSize,
|
||
IN BOOLEAN ReturnRecognizedPartitions,
|
||
OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine walks the disk reading the partition tables and creates
|
||
an entry in the partition list buffer for each partition.
|
||
|
||
The algorithm used by this routine is two-fold:
|
||
|
||
1) Read each partition table and for each valid, recognized
|
||
partition found, to build a descriptor in a partition list.
|
||
Extended partitions are located in order to find other
|
||
partition tables, but no descriptors are built for these.
|
||
The partition list is built in nonpaged pool that is allocated
|
||
by this routine. It is the caller's responsibility to free
|
||
this pool after it has gathered the appropriate information
|
||
from the list.
|
||
|
||
2) Read each partition table and for each and every entry, build
|
||
a descriptor in the partition list. Extended partitions are
|
||
located to find each partition table on the disk, and entries
|
||
are built for these as well. The partition list is build in
|
||
nonpaged pool that is allocated by this routine. It is the
|
||
caller's responsibility to free this pool after it has copied
|
||
the information back to its caller.
|
||
|
||
The first algorithm is used when the ReturnRecognizedPartitions flag
|
||
is set. This is used to determine how many partition device objects
|
||
the device driver is to create, and where each lives on the drive.
|
||
|
||
The second algorithm is used when the ReturnRecognizedPartitions flag
|
||
is clear. This is used to find all of the partition tables and their
|
||
entries for a utility such as fdisk, that would like to revamp where
|
||
the partitions live.
|
||
|
||
Arguments:
|
||
|
||
DeviceObject - Pointer to device object for this disk.
|
||
|
||
SectorSize - Sector size on the device.
|
||
|
||
ReturnRecognizedPartitions - A flag indicated whether only recognized
|
||
partition descriptors are to be returned, or whether all partition
|
||
entries are to be returned.
|
||
|
||
PartitionBuffer - Pointer to the pointer of the buffer in which the list
|
||
of partition will be stored.
|
||
|
||
Return Value:
|
||
|
||
The functional value is STATUS_SUCCESS if at least one sector table was
|
||
read.
|
||
|
||
Notes:
|
||
|
||
It is the responsibility of the caller to deallocate the partition list
|
||
buffer allocated by this routine.
|
||
|
||
--*/
|
||
|
||
{
|
||
//
|
||
// Stub to call extensible routine in ke so that hal vendors
|
||
// don't have to support.
|
||
//
|
||
|
||
return HalIoReadPartitionTable(
|
||
DeviceObject,
|
||
SectorSize,
|
||
ReturnRecognizedPartitions,
|
||
PartitionBuffer
|
||
);
|
||
}
|
||
|
||
NTSTATUS
|
||
IoSetPartitionInformation(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN ULONG SectorSize,
|
||
IN ULONG PartitionNumber,
|
||
IN ULONG PartitionType
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is invoked when a disk device driver is asked to set the
|
||
partition type in a partition table entry via an I/O control code. This
|
||
control code is generally issued by the format utility just after it
|
||
has formatted the partition. The format utility performs the I/O control
|
||
function on the partition and the driver passes the address of the base
|
||
physical device object and the number of the partition associated with
|
||
the device object that the format utility has open. If this routine
|
||
returns success, then the disk driver should updates its notion of the
|
||
partition type for this partition in its device extension.
|
||
|
||
Arguments:
|
||
|
||
DeviceObject - Pointer to the base physical device object for the device
|
||
on which the partition type is to be set.
|
||
|
||
SectorSize - Supplies the size of a sector on the disk in bytes.
|
||
|
||
PartitionNumber - Specifies the partition number on the device whose
|
||
partition type is to be changed.
|
||
|
||
PartitionType - Specifies the new type for the partition.
|
||
|
||
Return Value:
|
||
|
||
The function value is the final status of the operation.
|
||
|
||
Notes:
|
||
|
||
This routine is synchronous. Therefore, it MUST be invoked by the disk
|
||
driver's dispatch routine, or by a disk driver's thread. Likewise, all
|
||
users, FSP threads, etc., must be prepared to enter a wait state when
|
||
issuing the I/O control code to set the partition type for the device.
|
||
|
||
Note also that this routine assumes that the partition number passed
|
||
in by the disk driver actually exists since the driver itself supplies
|
||
this parameter.
|
||
|
||
Finally, note that this routine may NOT be invoked at APC_LEVEL. It
|
||
must be invoked at PASSIVE_LEVEL. This is due to the fact that this
|
||
routine uses a kernel event object to synchronize I/O completion on the
|
||
device. The event cannot be set to the signaled state without queueing
|
||
the I/O system's special kernel APC routine for I/O completion and
|
||
executing it. (This rules is a bit esoteric since it only holds true
|
||
if the device driver returns something other than STATUS_PENDING, which
|
||
it will probably never do.)
|
||
|
||
--*/
|
||
|
||
{
|
||
//
|
||
// Stub to call extensible routine in ke so that hal vendors
|
||
// don't have to support.
|
||
//
|
||
|
||
return HalIoSetPartitionInformation(
|
||
DeviceObject,
|
||
SectorSize,
|
||
PartitionNumber,
|
||
PartitionType
|
||
);
|
||
|
||
}
|
||
|
||
NTSTATUS
|
||
IoWritePartitionTable(
|
||
IN PDEVICE_OBJECT DeviceObject,
|
||
IN ULONG SectorSize,
|
||
IN ULONG SectorsPerTrack,
|
||
IN ULONG NumberOfHeads,
|
||
IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine walks the disk writing the partition tables from
|
||
the entries in the partition list buffer for each partition.
|
||
|
||
Applications that create and delete partitions should issue a
|
||
IoReadPartitionTable call with the 'return recognized partitions'
|
||
boolean set to false to get a full description of the system.
|
||
|
||
Then the drive layout structure can be modified by the application to
|
||
reflect the new configuration of the disk and then is written back
|
||
to the disk using this routine.
|
||
|
||
Arguments:
|
||
|
||
DeviceObject - Pointer to device object for this disk.
|
||
|
||
SectorSize - Sector size on the device.
|
||
|
||
SectorsPerTrack - Track size on the device.
|
||
|
||
NumberOfHeads - Same as tracks per cylinder.
|
||
|
||
PartitionBuffer - Pointer drive layout buffer.
|
||
|
||
Return Value:
|
||
|
||
The functional value is STATUS_SUCCESS if all writes are completed
|
||
without error.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
//
|
||
// Stub to call extensible routine in ke so that hal vendors
|
||
// don't have to support.
|
||
//
|
||
|
||
return HalIoWritePartitionTable(
|
||
DeviceObject,
|
||
SectorSize,
|
||
SectorsPerTrack,
|
||
NumberOfHeads,
|
||
PartitionBuffer
|
||
);
|
||
}
|