📄 enum.c
字号:
/*++
Copyright (C) Microsoft Corporation, 1991 - 1999
Module Name:
pnp.c
Abstract:
SCSI disk class driver
Environment:
kernel mode only
Notes:
Revision History:
--*/
#include "disk.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, DiskConvertExtendedToLayout)
#pragma alloc_text(PAGE, DiskConvertPartitionToExtended)
#pragma alloc_text(PAGE, DiskConvertLayoutToExtended)
#pragma alloc_text(PAGE, DiskCreatePdo)
#pragma alloc_text(PAGE, DiskEnumerateDevice)
#pragma alloc_text(PAGE, DiskUpdateRemovablePartitions)
#pragma alloc_text(PAGE, DiskUpdatePartitions)
#pragma alloc_text(PAGE, DiskCreatePdo)
#endif
PDRIVE_LAYOUT_INFORMATION
DiskConvertExtendedToLayout(
IN CONST PDRIVE_LAYOUT_INFORMATION_EX LayoutEx
)
{
ULONG i;
ULONG LayoutSize;
PDRIVE_LAYOUT_INFORMATION Layout;
PPARTITION_INFORMATION Partition;
PPARTITION_INFORMATION_EX PartitionEx;
PAGED_CODE ();
ASSERT ( LayoutEx );
//
// The only valid conversion is from an MBR extended layout structure to
// the old structure.
//
if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR) {
ASSERT ( FALSE );
return NULL;
}
LayoutSize = FIELD_OFFSET (DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]) +
LayoutEx->PartitionCount * sizeof (PARTITION_INFORMATION);
Layout = ExAllocatePoolWithTag (
NonPagedPool,
LayoutSize,
DISK_TAG_PART_LIST
);
if ( Layout == NULL ) {
return NULL;
}
Layout->Signature = LayoutEx->Mbr.Signature;
Layout->PartitionCount = LayoutEx->PartitionCount;
for (i = 0; i < LayoutEx->PartitionCount; i++) {
Partition = &Layout->PartitionEntry[i];
PartitionEx = &LayoutEx->PartitionEntry[i];
Partition->StartingOffset = PartitionEx->StartingOffset;
Partition->PartitionLength = PartitionEx->PartitionLength;
Partition->RewritePartition = PartitionEx->RewritePartition;
Partition->PartitionNumber = PartitionEx->PartitionNumber;
Partition->PartitionType = PartitionEx->Mbr.PartitionType;
Partition->BootIndicator = PartitionEx->Mbr.BootIndicator;
Partition->RecognizedPartition = PartitionEx->Mbr.RecognizedPartition;
Partition->HiddenSectors = PartitionEx->Mbr.HiddenSectors;
}
return Layout;
}
VOID
DiskConvertPartitionToExtended(
IN PPARTITION_INFORMATION Partition,
OUT PPARTITION_INFORMATION_EX PartitionEx
)
/*++
Routine Description:
Convert a PARTITION_INFORMATION structure to a PARTITION_INFORMATION_EX
structure.
Arguments:
Partition - A pointer to the PARTITION_INFORMATION structure to convert.
PartitionEx - A pointer to a buffer where the converted
PARTITION_INFORMATION_EX structure is to be stored.
Return Values:
None.
--*/
{
PAGED_CODE ();
ASSERT ( PartitionEx != NULL );
ASSERT ( Partition != NULL );
PartitionEx->PartitionStyle = PARTITION_STYLE_MBR;
PartitionEx->StartingOffset = Partition->StartingOffset;
PartitionEx->PartitionLength = Partition->PartitionLength;
PartitionEx->RewritePartition = Partition->RewritePartition;
PartitionEx->PartitionNumber = Partition->PartitionNumber;
PartitionEx->Mbr.PartitionType = Partition->PartitionType;
PartitionEx->Mbr.BootIndicator = Partition->BootIndicator;
PartitionEx->Mbr.RecognizedPartition = Partition->RecognizedPartition;
PartitionEx->Mbr.HiddenSectors = Partition->HiddenSectors;
}
PDRIVE_LAYOUT_INFORMATION_EX
DiskConvertLayoutToExtended(
IN CONST PDRIVE_LAYOUT_INFORMATION Layout
)
/*++
Routine Description:
Convert a DRIVE_LAYOUT_INFORMATION structure into a
DRIVE_LAYOUT_INFORMATION_EX structure.
Arguments:
Layout - The source DRIVE_LAYOUT_INFORMATION structure.
Return Values:
The resultant DRIVE_LAYOUT_INFORMATION_EX structure. This buffer must
be freed by the callee using ExFreePool.
--*/
{
ULONG i;
ULONG size;
PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
PAGED_CODE ();
ASSERT ( Layout != NULL );
//
// Allocate enough space for a DRIVE_LAYOUT_INFORMATION_EX structure
// plus as many PARTITION_INFORMATION_EX structures as are in the
// source array.
//
size = FIELD_OFFSET (DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]) +
Layout->PartitionCount * sizeof ( PARTITION_INFORMATION_EX );
layoutEx = ExAllocatePoolWithTag(
NonPagedPool,
size,
DISK_TAG_PART_LIST
);
if ( layoutEx == NULL ) {
return NULL;
}
//
// Convert the disk information.
//
layoutEx->PartitionStyle = PARTITION_STYLE_MBR;
layoutEx->PartitionCount = Layout->PartitionCount;
layoutEx->Mbr.Signature = Layout->Signature;
for (i = 0; i < Layout->PartitionCount; i++) {
//
// Convert each entry.
//
DiskConvertPartitionToExtended (
&Layout->PartitionEntry[i],
&layoutEx->PartitionEntry[i]
);
}
return layoutEx;
}
NTSTATUS
DiskEnumerateDevice(
IN PDEVICE_OBJECT Fdo
)
/*++
Routine Description:
This routine is called by the class driver to update the PDO list off
of this FDO. The disk driver also calls it internally to re-create
device objects.
This routine will read the partition table and create new PDO objects as
necessary. PDO's that no longer exist will be pulled out of the PDO list
so that pnp will destroy them.
Arguments:
Fdo - a pointer to the FDO being re-enumerated
Return Value:
status
--*/
{
PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
PPHYSICAL_DEVICE_EXTENSION pdoExtension = NULL;
PDISK_DATA diskData = (PDISK_DATA) commonExtension->DriverData;
PDEVICE_OBJECT pdo = NULL;
ULONG numberListElements = 0;
PDRIVE_LAYOUT_INFORMATION_EX partitionList;
NTSTATUS status;
ASSERT(commonExtension->IsFdo);
PAGED_CODE();
//
// Update our image of the size of the drive. This may be necessary if
// the drive size is extended or we just released a reservation to
// ensure the kernel doesn't reject the partition table.
//
DiskReadDriveCapacity(Fdo);
//
// Lock out anyone else trying to repartition the disk.
//
DiskAcquirePartitioningLock(fdoExtension);
//
// Create objects for all the partitions on the device.
//
status = DiskReadPartitionTableEx(fdoExtension, FALSE, &partitionList);
//
// If the I/O read partition table failed and this is a removable device,
// then fix up the partition list to make it look like there is one
// zero length partition.
//
if ((!NT_SUCCESS(status) || partitionList->PartitionCount == 0) &&
Fdo->Characteristics & FILE_REMOVABLE_MEDIA) {
SIZE_T partitionListSize;
//
// Remember whether the drive is ready.
//
diskData->ReadyStatus = status;
//
// Allocate and zero a partition list.
//
partitionListSize =
FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[1]);
partitionList = ExAllocatePoolWithTag(NonPagedPool,
partitionListSize,
DISK_TAG_PART_LIST);
if (partitionList != NULL) {
RtlZeroMemory( partitionList, partitionListSize );
//
// Set the partition count to one and the status to success
// so one device object will be created. Set the partition type
// to a bogus value.
//
partitionList->PartitionStyle = PARTITION_STYLE_MBR;
partitionList->PartitionCount = 1;
status = STATUS_SUCCESS;
} else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
}
if (NT_SUCCESS(status)) {
diskData->UpdatePartitionRoutine(Fdo, partitionList);
//
// Record disk signature.
//
if (partitionList->PartitionStyle == PARTITION_STYLE_MBR) {
diskData->PartitionStyle = PARTITION_STYLE_MBR;
diskData->Mbr.Signature = partitionList->Mbr.Signature;
} else {
diskData->PartitionStyle = PARTITION_STYLE_GPT;
diskData->Efi.DiskId = partitionList->Gpt.DiskId;
}
}
DiskReleasePartitioningLock(fdoExtension);
return(STATUS_SUCCESS);
} // end DiskEnumerateDevice()
VOID
DiskUpdateRemovablePartitions(
IN PDEVICE_OBJECT Fdo,
IN OUT PDRIVE_LAYOUT_INFORMATION_EX PartitionList
)
/*++
Routine Description:
This routine is called by the class DLL to update the PDO list off of this
FDO. The disk driver also calls it internally to re-create device objects.
This routine will read the partition table and update the size of the
single partition device object which always exists for removable devices.
Arguments:
Fdo - a pointer to the FDO being reenumerated.
Return Value:
status
--*/
{
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
PPHYSICAL_DEVICE_EXTENSION pdoExtension = NULL;
ULONG partitionCount;
ULONG partitionNumber;
ULONG partitionOrdinal = 0;
ULONG newPartitionNumber;
PDISK_DATA pdoData;
NTSTATUS status;
PPARTITION_INFORMATION_EX partitionEntry;
PARTITION_STYLE partitionStyle;
PAGED_CODE();
ASSERT(Fdo->Characteristics & FILE_REMOVABLE_MEDIA);
partitionStyle = PartitionList->PartitionStyle;
partitionCount = PartitionList->PartitionCount;
for(partitionNumber = 0;
partitionNumber < partitionCount;
partitionNumber++) {
partitionEntry = &(PartitionList->PartitionEntry[partitionNumber]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -