📄 enum.c
字号:
partitionEntry->PartitionNumber = 0;
}
//
// Get exclusive access to the child list while repartitioning.
//
ClassAcquireChildLock(fdoExtension);
//
// Removable media should never have more than one PDO.
//
pdoExtension = fdoExtension->CommonExtension.ChildList;
if(pdoExtension == NULL) {
PARTITION_INFORMATION_EX tmpPartitionEntry;
PDEVICE_OBJECT pdo;
//
// There is no PDO currently. Create one and pre-initialize it with
// a zero length.
//
RtlZeroMemory(&tmpPartitionEntry, sizeof(tmpPartitionEntry));
tmpPartitionEntry.PartitionNumber = 1;
DebugPrint((1, "DiskUpdateRemovablePartitions: Creating RM partition\n"));
status = DiskCreatePdo(Fdo,
0,
&tmpPartitionEntry,
partitionStyle,
&pdo);
if(!NT_SUCCESS(status)) {
DebugPrint((1, "DiskUpdateRemovablePartitions: error %lx creating "
"new PDO for RM partition\n",
status));
ClassReleaseChildLock(fdoExtension);
return;
}
//
// mark the new device as enumerated
//
pdoExtension = pdo->DeviceExtension;
pdoExtension->IsMissing = FALSE;
}
pdoData = pdoExtension->CommonExtension.DriverData;
//
// Search the partition list for a valid entry. We're looking for a
// primary partition since we only support the one.
//
for(partitionNumber = 0;
partitionNumber < partitionCount;
partitionNumber++) {
partitionEntry = &(PartitionList->PartitionEntry[partitionNumber]);
//
// Is this partition interesting?
//
if (partitionStyle == PARTITION_STYLE_MBR) {
if(partitionEntry->Mbr.PartitionType == PARTITION_ENTRY_UNUSED ||
IsContainerPartition(partitionEntry->Mbr.PartitionType)) {
continue;
}
}
partitionOrdinal++;
//
// We have found the first and thus only partition allowed on
// this disk. Update the information in the PDO to match the new
// partition.
//
DebugPrint((1, "DiskUpdateRemovablePartitions: Matched %wZ to #%d, "
"ordinal %d\n",
&pdoExtension->CommonExtension.DeviceName,
partitionEntry->PartitionNumber,
partitionOrdinal));
partitionEntry->PartitionNumber = 1;
pdoData->PartitionStyle = partitionStyle;
pdoData->PartitionOrdinal = partitionOrdinal;
ASSERT(partitionEntry->PartitionLength.LowPart != 0x23456789);
pdoExtension->CommonExtension.StartingOffset =
partitionEntry->StartingOffset;
pdoExtension->CommonExtension.PartitionLength =
partitionEntry->PartitionLength;
if (partitionStyle == PARTITION_STYLE_MBR) {
pdoData->Mbr.HiddenSectors = partitionEntry->Mbr.HiddenSectors;
pdoData->Mbr.BootIndicator = partitionEntry->Mbr.BootIndicator;
//
// If this partition is being re-written then update the type
// information as well
//
if (partitionEntry->RewritePartition) {
pdoData->Mbr.PartitionType = partitionEntry->Mbr.PartitionType;
}
} else {
pdoData->Efi.PartitionType = partitionEntry->Gpt.PartitionType;
pdoData->Efi.PartitionId = partitionEntry->Gpt.PartitionId;
pdoData->Efi.Attributes = partitionEntry->Gpt.Attributes;
RtlCopyMemory(
pdoData->Efi.PartitionName,
partitionEntry->Gpt.Name,
sizeof (pdoData->Efi.PartitionName)
);
}
//
// Mark this one as found
//
pdoExtension->IsMissing = FALSE;
ClassReleaseChildLock(fdoExtension);
return;
}
//
// No interesting partition was found.
//
if (partitionStyle == PARTITION_STYLE_MBR) {
pdoData->Mbr.HiddenSectors = 0;
pdoData->Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
} else {
RtlZeroMemory (&pdoData->Efi,
sizeof (pdoData->Efi)
);
}
pdoExtension->CommonExtension.StartingOffset.QuadPart = 0;
pdoExtension->CommonExtension.PartitionLength.QuadPart = 0;
ClassReleaseChildLock(fdoExtension);
return;
}
VOID
DiskUpdatePartitions(
IN PDEVICE_OBJECT Fdo,
IN OUT PDRIVE_LAYOUT_INFORMATION_EX PartitionList
)
/*++
Routine Description:
This routine will synchronize the information held in the partition list
with the device objects hanging off this Fdo. Any new partition objects
will be created, any non-existant ones will be marked as un-enumerated.
This will be done in several stages:
* Clear state (partition number) from every entry in the partition
list
* Set IsMissing flag on every child of this FDO
* For each child of the FDO:
if a matching partition exists in the partition list,
update the partition number in the table, update the
ordinal in the object and mark the object as enumerated
* For each un-enumerated device object
zero out the partition information to invalidate the device
delete the symbolic link if any
* For each un-matched entry in the partition list:
create a new partition object
update the partition number in the list entry
create a new symbolic link if necessary
Arguments:
Fdo - a pointer to the functional device object this partition list is for
PartitionList - a pointer to the partition list being updated
Return Value:
none
--*/
{
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
PPHYSICAL_DEVICE_EXTENSION oldChildList = NULL;
PPHYSICAL_DEVICE_EXTENSION pdoExtension = NULL;
ULONG partitionCount;
ULONG partitionNumber;
ULONG partitionOrdinal;
ULONG newPartitionNumber;
PPARTITION_INFORMATION_EX partitionEntry;
PDISK_DATA pdoData;
PARTITION_STYLE partitionStyle;
NTSTATUS status;
PAGED_CODE();
//
// Get exclusive access to the child list.
//
ClassAcquireChildLock(fdoExtension);
partitionStyle = PartitionList->PartitionStyle;
partitionCount = PartitionList->PartitionCount;
//
// Pull all the child device objects off the children list. We'll
// add them back later.
//
oldChildList = fdoExtension->CommonExtension.ChildList;
fdoExtension->CommonExtension.ChildList = NULL;
//
// Clear the partition numbers from the list entries
//
for(partitionNumber = 0;
partitionNumber < partitionCount;
partitionNumber++) {
partitionEntry = &(PartitionList->PartitionEntry[partitionNumber]);
partitionEntry->PartitionNumber = 0;
}
//
// Now match each child partition to it's entry (if any) in the partition
// list.
//
while(oldChildList != NULL) {
pdoExtension = oldChildList;
pdoData = pdoExtension->CommonExtension.DriverData;
//
// Check all partition entries for a match on offset and length
//
partitionOrdinal = 0;
for(partitionNumber = 0;
partitionNumber < partitionCount;
partitionNumber++) {
partitionEntry = &(PartitionList->PartitionEntry[partitionNumber]);
//
// Is this an interesting partition entry?
//
if (partitionStyle == PARTITION_STYLE_MBR) {
if((partitionEntry->Mbr.PartitionType == PARTITION_ENTRY_UNUSED) ||
(IsContainerPartition(partitionEntry->Mbr.PartitionType))) {
continue;
}
}
partitionOrdinal++;
if(partitionEntry->PartitionNumber) {
//
// This partition has already been found - skip it
//
continue;
}
//
// Let's see if the partition information matches
//
if(partitionEntry->StartingOffset.QuadPart !=
pdoExtension->CommonExtension.StartingOffset.QuadPart) {
continue;
}
if(partitionEntry->PartitionLength.QuadPart !=
pdoExtension->CommonExtension.PartitionLength.QuadPart) {
continue;
}
//
// Yep - it matches. Update the information in the entry
//
partitionEntry->PartitionNumber = pdoExtension->CommonExtension.PartitionNumber;
if (partitionStyle == PARTITION_STYLE_MBR) {
pdoData->Mbr.HiddenSectors = partitionEntry->Mbr.HiddenSectors;
}
break;
}
if(partitionNumber != partitionCount) {
DebugPrint((1, "DiskUpdatePartitions: Matched %wZ to #%d, ordinal "
"%d\n",
&pdoExtension->CommonExtension.DeviceName,
partitionEntry->PartitionNumber,
partitionOrdinal));
ASSERT(partitionEntry->PartitionLength.LowPart != 0x23456789);
// ASSERT(pdoExtension->CommonExtension.PartitionLength.QuadPart != 0);
pdoData->PartitionStyle = partitionStyle;
//
// we found a match - update the information in the device object
// extension and driverdata
//
pdoData->PartitionOrdinal = partitionOrdinal;
//
// If this partition is being re-written then update the type
// information as well
//
if (partitionStyle == PARTITION_STYLE_MBR) {
if(partitionEntry->RewritePartition) {
pdoData->Mbr.PartitionType = partitionEntry->Mbr.PartitionType;
}
} else {
DebugPrint((1, "DiskUpdatePartitions: EFI Partition %ws\n",
pdoData->Efi.PartitionName
));
pdoData->Efi.PartitionType = partitionEntry->Gpt.PartitionType;
pdoData->Efi.PartitionId = partitionEntry->Gpt.PartitionId;
pdoData->Efi.Attributes = partitionEntry->Gpt.Attributes;
RtlCopyMemory(
pdoData->Efi.PartitionName,
partitionEntry->Gpt.Name,
sizeof (pdoData->Efi.PartitionName)
);
}
//
// Mark this one as found.
//
pdoExtension->IsMissing = FALSE;
//
// Pull it out of the old child list and add it into the
// real one.
//
oldChildList = pdoExtension->CommonExtension.ChildList;
pdoExtension->CommonExtension.ChildList =
fdoExtension->CommonExtension.ChildList;
fdoExtension->CommonExtension.ChildList = pdoExtension;
} else {
PDEVICE_OBJECT nextPdo;
DebugPrint ((1, "DiskUpdatePartitions: Deleting %wZ\n",
&pdoExtension->CommonExtension.DeviceName));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -