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

📄 disk.c

📁 The Disk sample is used with Classpnp.sys as disk driver. The sample supports Plug and Play, Power M
💻 C
📖 第 1 页 / 共 5 页
字号:
    //
    // Set up an object directory to contain the objects for this
    // device and all its partitions.
    //

    do {

        WCHAR buffer[64];
        UNICODE_STRING unicodeDirectoryName;

        swprintf(buffer, L"\\Device\\Harddisk%d", *DeviceCount);

        RtlInitUnicodeString(&unicodeDirectoryName, buffer);

        InitializeObjectAttributes(&objectAttributes,
                                   &unicodeDirectoryName,
                                   OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                                   NULL,
                                   NULL);

        status = ZwCreateDirectoryObject(&handle,
                                         DIRECTORY_ALL_ACCESS,
                                         &objectAttributes);

        (*DeviceCount)++;

    } while((status == STATUS_OBJECT_NAME_COLLISION) ||
            (status == STATUS_OBJECT_NAME_EXISTS));

    if (!NT_SUCCESS(status)) {

        DebugPrint((1, "DiskCreateFdo: Could not create directory - %lx\n",
                    status));

        return(status);
    }

    //
    // When this loop exits the count is inflated by one - fix that.
    //

    (*DeviceCount)--;

    //
    // Claim the device.
    //

    lowerDevice = IoGetAttachedDeviceReference(PhysicalDeviceObject);

    status = ClassClaimDevice(lowerDevice, FALSE);

    if (!NT_SUCCESS(status)) {
        ZwMakeTemporaryObject(handle);
        ZwClose(handle);
        ObDereferenceObject(lowerDevice);
        return status;
    }

    //
    // Create a device object for this device. Each physical disk will
    // have at least one device object. The required device object
    // describes the entire device. Its directory path is
    // \Device\HarddiskN\Partition0, where N = device number.
    //

    status = DiskGenerateDeviceName(TRUE,
                                    *DeviceCount,
                                    0,
                                    NULL,
                                    NULL,
                                    &deviceName);

    if(!NT_SUCCESS(status)) {
        DebugPrint((1, "DiskCreateFdo - couldn't create name %lx\n",
                       status));

        goto DiskCreateFdoExit;

    }

    status = ClassCreateDeviceObject(DriverObject,
                                     deviceName,
                                     PhysicalDeviceObject,
                                     TRUE,
                                     &deviceObject);

    if (!NT_SUCCESS(status)) {

        DebugPrint((1,
                    "DiskCreateFdo: Can not create device object %s\n",
                    ntNameBuffer));

        goto DiskCreateFdoExit;
    }

    //
    // Indicate that IRPs should include MDLs for data transfers.
    //

    SET_FLAG(deviceObject->Flags, DO_DIRECT_IO);

    fdoExtension = deviceObject->DeviceExtension;

    if(DasdAccessOnly) {

        //
        // Inidicate that only RAW should be allowed to mount on the root
        // partition object.  This ensures that a file system can't doubly
        // mount on a super-floppy by mounting once on P0 and once on P1.
        //

        SET_FLAG(deviceObject->Vpb->Flags, VPB_RAW_MOUNT);
    }

    //
    // Initialize lock count to zero. The lock count is used to
    // disable the ejection mechanism on devices that support
    // removable media. Only the lock count in the physical
    // device extension is used.
    //

    fdoExtension->LockCount = 0;

    //
    // Save system disk number.
    //

    fdoExtension->DeviceNumber = *DeviceCount;

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

    if (lowerDevice->AlignmentRequirement > deviceObject->AlignmentRequirement) {
        deviceObject->AlignmentRequirement = lowerDevice->AlignmentRequirement;
    }

    //
    // Finally, attach to the pdo
    //

    fdoExtension->LowerPdo = PhysicalDeviceObject;

    fdoExtension->CommonExtension.LowerDeviceObject =
        IoAttachDeviceToDeviceStack(
            deviceObject,
            PhysicalDeviceObject);

    if(fdoExtension->CommonExtension.LowerDeviceObject == NULL) {

        //
        // Uh - oh, we couldn't attach
        // cleanup and return
        //

        status = STATUS_UNSUCCESSFUL;
        goto DiskCreateFdoExit;
    }

    {
        PDISK_DATA diskData = fdoExtension->CommonExtension.DriverData;

        //
        // Initialize the partitioning lock as it may be used in the remove
        // code.
        //

        KeInitializeEvent(&(diskData->PartitioningEvent),
                          SynchronizationEvent,
                          TRUE);
    }


    //
    // Clear the init flag.
    //

    CLEAR_FLAG(deviceObject->Flags, DO_DEVICE_INITIALIZING);

    //
    // Store a handle to the device object directory for this disk
    //

    fdoExtension->DeviceDirectory = handle;

    ObDereferenceObject(lowerDevice);

    return STATUS_SUCCESS;

DiskCreateFdoExit:

    //
    // Release the device since an error occurred.
    //

    if (deviceObject != NULL) {
        IoDeleteDevice(deviceObject);
    }

    //
    // Delete directory and return.
    //

    if (!NT_SUCCESS(status)) {
        ZwMakeTemporaryObject(handle);
        ZwClose(handle);
    }

    ObDereferenceObject(lowerDevice);

    return(status);
}


NTSTATUS
DiskReadWriteVerification(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    I/O System entry for read and write requests to SCSI disks.

Arguments:

    DeviceObject - Pointer to driver object created by system.
    Irp - IRP involved.

Return Value:

    NT Status

--*/

{
    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;

    PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
    ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
    LARGE_INTEGER startingOffset;

    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension =
        commonExtension->PartitionZeroExtension;

    ULONG residualBytes;
    NTSTATUS status;

    //
    // Verify parameters of this request.
    // Check that ending sector is within partition and
    // that number of bytes to transfer is a multiple of
    // the sector size.
    //

    startingOffset.QuadPart =
        (currentIrpStack->Parameters.Read.ByteOffset.QuadPart +
         transferByteCount);

    residualBytes = transferByteCount &
                    (fdoExtension->DiskGeometry.BytesPerSector - 1);


    if ((startingOffset.QuadPart > commonExtension->PartitionLength.QuadPart) ||
        (residualBytes != 0)) {

        //
        // This error may be caused by the fact that the drive is not ready.
        //

        status = ((PDISK_DATA) commonExtension->DriverData)->ReadyStatus;

        if (!NT_SUCCESS(status)) {

            //
            // Flag this as a user errror so that a popup is generated.
            //

            DebugPrint((1, "DiskReadWriteVerification: ReadyStatus is %lx\n",
                        status));

            IoSetHardErrorOrVerifyDevice(Irp, DeviceObject);

            //
            // status will keep the current error
            //

            ASSERT( status != STATUS_INSUFFICIENT_RESOURCES );

        } else if((commonExtension->IsFdo == TRUE) && (residualBytes == 0)) {

            //
            // This failed because we think the physical disk is too small.
            // Send it down to the drive and let the hardware decide for
            // itself.
            //

            status = STATUS_SUCCESS;

        } else {

            //
            // Note fastfat depends on this parameter to determine when to
            // remount due to a sector size change.
            //

            status = STATUS_INVALID_PARAMETER;

        }

    } else {

        //
        // the drive is ready, so ok the read/write
        //

        status = STATUS_SUCCESS;

    }

    Irp->IoStatus.Status = status;
    return status;

} // end DiskReadWrite()



NTSTATUS
DiskDetermineMediaTypes(
    IN PDEVICE_OBJECT Fdo,
    IN PIRP     Irp,
    IN UCHAR    MediumType,
    IN UCHAR    DensityCode,
    IN BOOLEAN  MediaPresent,
    IN BOOLEAN  IsWritable
    )

/*++

Routine Description:

    Determines number of types based on the physical device, validates the user buffer
    and builds the MEDIA_TYPE information.

Arguments:

    DeviceObject - Pointer to functional device object created by system.
    Irp - IOCTL_STORAGE_GET_MEDIA_TYPES_EX Irp.
    MediumType - byte returned in mode data header.
    DensityCode - byte returned in mode data block descriptor.
    NumberOfTypes - pointer to be updated based on actual device.

Return Value:

    Status is returned.

--*/

{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
    PPHYSICAL_DEVICE_EXTENSION pdoExtension = Fdo->DeviceExtension;
    PCOMMON_DEVICE_EXTENSION   commonExtension = Fdo->DeviceExtension;
    PIO_STACK_LOCATION         irpStack = IoGetCurrentIrpStackLocation(Irp);

    PGET_MEDIA_TYPES  mediaTypes = Irp->AssociatedIrp.SystemBuffer;
    PDEVICE_MEDIA_INFO mediaInfo = &mediaTypes->MediaInfo[0];
    BOOLEAN deviceMatched = FALSE;

    PAGED_CODE();

    //
    // this should be checked prior to calling into this routine
    // as we use the buffer as mediaTypes
    //
    ASSERT(irpStack->Parameters.DeviceIoControl.OutputBufferLength >=
           sizeof(GET_MEDIA_TYPES));


    //
    // Determine if this device is removable or fixed.
    //

    if (!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {

        //
        // Fixed disk.
        //

        mediaTypes->DeviceType = FILE_DEVICE_DISK;
        mediaTypes->MediaInfoCount = 1;

        mediaInfo->DeviceSpecific.DiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
        mediaInfo->DeviceSpecific.DiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
        mediaInfo->DeviceSpecific.DiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
        mediaInfo->DeviceSpecific.DiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
        mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;

        mediaInfo->DeviceSpecific.DiskInfo.MediaCharacteristics = (MEDIA_CURRENTLY_MOUNTED | MEDIA_READ_WRITE);

        if (!IsWritable) {
            SET_FLAG(mediaInfo->DeviceSpecific.DiskInfo.MediaCharacteristics,
                     MEDIA_WRITE_PROTECTED);
        }

        mediaInfo->DeviceSpecific.DiskInfo.MediaType = FixedMedia;


    } else {

        PUCHAR vendorId = (PUCHAR) fdoExtension->DeviceDescriptor + fdoExtension->DeviceDescriptor->VendorIdOffset;
        PUCHAR productId = (PUCHAR) fdoExtension->DeviceDescriptor + fdoExtension->DeviceDescriptor->ProductIdOffset;
        PUCHAR productRevision = (PUCHAR) fdoExtension->DeviceDescriptor + fdoExtension->DeviceDescriptor->ProductRevisionOffset;

⌨️ 快捷键说明

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