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

📄 enum.c

📁 The Disk sample is used with Classpnp.sys as disk driver. The sample supports Plug and Play, Power M
💻 C
📖 第 1 页 / 共 3 页
字号:

            if (partitionStyle == PARTITION_STYLE_GPT) {

                DebugPrint ((1, "DiskUpdatePartitions: EFI Partition %ws\n",
                      pdoData->Efi.PartitionName
                      ));
            }
            //
            // no matching entry in the partition list - throw this partition
            // object away
            //

            pdoExtension->CommonExtension.PartitionLength.QuadPart = 0;

            //
            // grab a pointer to the next child before we mark this one as
            // missing since missing devices could vanish at any time.
            //

            oldChildList = pdoExtension->CommonExtension.ChildList;
            pdoExtension->CommonExtension.ChildList = (PVOID) -1;

            //
            // Now tell the class driver that this child is "missing" - this
            // will cause it to be deleted.
            //


            ClassMarkChildMissing(pdoExtension, FALSE);
        }
    }

    //
    // At this point the old child list had best be empty.
    //

    ASSERT(oldChildList == NULL);

    //
    // Iterate through the partition entries and create any partition
    // objects that don't already exist
    //

    partitionOrdinal = 0;
    newPartitionNumber = 0;

    for(partitionNumber = 0;
        partitionNumber < partitionCount;
        partitionNumber++) {

        PDEVICE_OBJECT pdo;

        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;
            }
        }

        //
        // Increment the count of interesting partitions
        //

        partitionOrdinal++;
        newPartitionNumber++;

        //
        // Has this already been matched
        //

        if(partitionEntry->PartitionNumber == 0) {

            LONG i;

            //
            // find the first safe partition number for this device
            //

            for(i = 0; i < (LONG) partitionCount; i++) {


                PPARTITION_INFORMATION_EX tmp = &(PartitionList->PartitionEntry[i]);

                if (partitionStyle == PARTITION_STYLE_MBR) {
                    if (tmp->Mbr.PartitionType == PARTITION_ENTRY_UNUSED ||
                        IsContainerPartition(tmp->Mbr.PartitionType)) {
                        continue;
                    }
                } 

                if(tmp->PartitionNumber == newPartitionNumber) {

                    //
                    // Found a matching partition number - increment the count
                    // and restart the scan.
                    //

                    newPartitionNumber++;
                    i = -1;
                    continue;
                }
            }

            //
            // Assign this partition a partition number
            //

            partitionEntry->PartitionNumber = newPartitionNumber;

            DebugPrint((1, "DiskUpdatePartitions: Found new partition #%d, ord %d "
                           "starting at %#016I64x and running for %#016I64x\n",
                           partitionEntry->PartitionNumber,
                           partitionOrdinal,
                           partitionEntry->StartingOffset.QuadPart,
                           partitionEntry->PartitionLength.QuadPart));

            ClassReleaseChildLock(fdoExtension);

            status = DiskCreatePdo(Fdo,
                                   partitionOrdinal,
                                   partitionEntry,
                                   partitionStyle,
                                   &pdo);

            ClassAcquireChildLock(fdoExtension);

            if(!NT_SUCCESS(status)) {

                DebugPrint((1, "DiskUpdatePartitions: error %lx creating "
                               "new PDO for partition ordinal %d, number %d\n",
                               status,
                               partitionOrdinal,
                               partitionEntry->PartitionNumber));

                //
                // don't increment the partition number - we'll try to reuse
                // it for the next child.
                //

                partitionEntry->PartitionNumber = 0;
                newPartitionNumber--;

                continue;
            }

            //
            // mark the new device as enumerated
            //

            pdoExtension = pdo->DeviceExtension;
            pdoExtension->IsMissing = FALSE;

            //
            // This number's taken already - try to scanning the partition
            // table more than once for a new number.
            //

        }
    }

    //
    // ISSUE - 2000/02/09 - math: Review.
    // Is PartitionStyle the only field that needs updating?
    //

    {
        PCOMMON_DEVICE_EXTENSION commonExtension;
        PDISK_DATA diskData;

        commonExtension = Fdo->DeviceExtension;
        diskData = (PDISK_DATA)(commonExtension->DriverData);

        diskData->PartitionStyle = partitionStyle;
    }
        
    ClassReleaseChildLock(fdoExtension);
    return;
}


NTSTATUS
DiskCreatePdo(
    IN PDEVICE_OBJECT Fdo,
    IN ULONG PartitionOrdinal,
    IN PPARTITION_INFORMATION_EX PartitionEntry,
    IN PARTITION_STYLE PartitionStyle,
    OUT PDEVICE_OBJECT *Pdo
    )

/*++

Routine Description:

    This routine will create and initialize a new partition device object
    (PDO) and insert it into the FDO partition list.

Arguments:

    Fdo - a pointer to the functional device object this PDO will be a child
          of

    PartitionOrdinal - the partition ordinal for this PDO

    PartitionEntry - the partition information for this device object

    PartitionStyle - what style of partition table entry PartitionEntry is;
            currently either MBR or EFI

    Pdo - a location to store the pdo pointer upon successful completion

Return Value:

    status

--*/

{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;

    PDEVICE_OBJECT pdo = NULL;
    PPHYSICAL_DEVICE_EXTENSION pdoExtension = NULL;

    PUCHAR deviceName = NULL;

    PDISK_DATA diskData = fdoExtension->CommonExtension.DriverData;

    ULONG numberListElements;

    NTSTATUS status = STATUS_SUCCESS;

    PAGED_CODE();

    //
    // Create partition object and set up partition parameters.
    //

    status = DiskGenerateDeviceName(FALSE,
                                    fdoExtension->DeviceNumber,
                                    PartitionEntry->PartitionNumber,
                                    &PartitionEntry->StartingOffset,
                                    &PartitionEntry->PartitionLength,
                                    &deviceName);

    if(!NT_SUCCESS(status)) {

        DebugPrint((1, "DiskCreatePdo - Can't generate name %lx\n", status));
        return status;
    }

    DebugPrint((2, "DiskCreatePdo: Create device object %s\n", deviceName));

    status = ClassCreateDeviceObject(Fdo->DriverObject,
                                     deviceName,
                                     Fdo,
                                     FALSE,
                                     &pdo);

    if (!NT_SUCCESS(status)) {

        DebugPrint((1, "DiskEnumerateDevice: Can't create device object for %s\n", deviceName));

        return status;
    }

    //
    // Set up device extension fields.
    //

    pdoExtension = pdo->DeviceExtension;

    //
    // Set up device object fields.
    //

    SET_FLAG(pdo->Flags, DO_DIRECT_IO);

    pdo->StackSize = (CCHAR)
        pdoExtension->CommonExtension.LowerDeviceObject->StackSize + 1;

    //
    // Get pointer to new disk data.
    //

    diskData = (PDISK_DATA) pdoExtension->CommonExtension.DriverData;

    //
    // Set the alignment requirements for the device based on the
    // host adapter requirements
    //

    if (Fdo->AlignmentRequirement > pdo->AlignmentRequirement) {
        pdo->AlignmentRequirement = Fdo->AlignmentRequirement;
    }

    if (fdoExtension->SrbFlags & SRB_FLAGS_QUEUE_ACTION_ENABLE) {
        numberListElements = 30;
    } else {
        numberListElements = 8;
    }

    //
    // Build the lookaside list for srb's for this partition based on
    // whether the adapter and disk can do tagged queueing.  Don't bother to 
    // check the status - this can't fail when called for a PDO.
    //

    ClassInitializeSrbLookasideList((PCOMMON_DEVICE_EXTENSION) pdoExtension,
                                    numberListElements);

    //
    // Set the sense-data pointer in the device extension.
    //

    diskData->PartitionOrdinal = PartitionOrdinal;
    pdoExtension->CommonExtension.PartitionNumber = PartitionEntry->PartitionNumber;

    //
    // Initialize relevant data.
    //
    
    if (PartitionStyle == PARTITION_STYLE_MBR) {
    
        diskData->Mbr.PartitionType = PartitionEntry->Mbr.PartitionType;
        diskData->Mbr.BootIndicator = PartitionEntry->Mbr.BootIndicator;
        diskData->Mbr.HiddenSectors = PartitionEntry->Mbr.HiddenSectors;

    } else {

        diskData->Efi.PartitionType = PartitionEntry->Gpt.PartitionType;
        diskData->Efi.PartitionId = PartitionEntry->Gpt.PartitionType;
        diskData->Efi.Attributes = PartitionEntry->Gpt.Attributes;
        RtlCopyMemory (diskData->Efi.PartitionName,
                       PartitionEntry->Gpt.Name,
                       sizeof (diskData->Efi.PartitionName)
                       );
    }

    DebugPrint((2, "DiskEnumerateDevice: Partition type is %x\n",
        diskData->Mbr.PartitionType));

    pdoExtension->CommonExtension.StartingOffset  =
        PartitionEntry->StartingOffset;

    pdoExtension->CommonExtension.PartitionLength =
        PartitionEntry->PartitionLength;


    DebugPrint((1, "DiskCreatePdo: hidden sectors value for pdo %#p set to %#x\n",
                pdo,
                diskData->Mbr.HiddenSectors));

    //
    // Check for removable media support.
    //

    if (fdoExtension->DeviceDescriptor->RemovableMedia) {
        SET_FLAG(pdo->Characteristics, FILE_REMOVABLE_MEDIA);
    }

    pdoExtension->CommonExtension.DeviceObject = pdo;

    CLEAR_FLAG(pdo->Flags, DO_DEVICE_INITIALIZING);

    *Pdo = pdo;

    return status;
}





VOID
DiskAcquirePartitioningLock(
    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
    )
{
    PDISK_DATA diskData = FdoExtension->CommonExtension.DriverData;

    PAGED_CODE();

    ASSERT_FDO(FdoExtension->DeviceObject);

    KeWaitForSingleObject(&(diskData->PartitioningEvent),
                          UserRequest,
                          UserMode,
                          FALSE,
                          NULL);
    return;
}


VOID
DiskReleasePartitioningLock(
    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
    )
{
    PDISK_DATA diskData = FdoExtension->CommonExtension.DriverData;

    PAGED_CODE();

    ASSERT_FDO(FdoExtension->DeviceObject);

    KeSetEvent(&(diskData->PartitioningEvent), IO_NO_INCREMENT, FALSE);
    return;
}

⌨️ 快捷键说明

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