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

📄 disk.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
    //

    deviceExtension->StartingOffset.QuadPart = (LONGLONG)(0);

    //
    // TargetId/LUN describes a device location on the SCSI bus.
    // This information comes from the inquiry buffer.
    //

    deviceExtension->PortNumber = (UCHAR)PortNumber;
    deviceExtension->PathId = pathId;
    deviceExtension->TargetId = targetId;
    deviceExtension->Lun = lun;

    //
    // Set timeout value in seconds.
    //

    timeOut = ScsiClassQueryTimeOutRegistryValue(RegistryPath);
    if (timeOut) {
        deviceExtension->TimeOutValue = timeOut;
    } else {
        deviceExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
    }

    //
    // Back pointer to device object.
    //

    deviceExtension->DeviceObject = deviceObject;

    //
    // If this is a removable device, then make sure it is not a floppy.
    // Perform a mode sense command to determine the media type. Note
    // IsFloppyDevice also checks for write cache enabled.
    //

    if (IsFloppyDevice(deviceObject) && deviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
        (((PINQUIRYDATA)LunInfo->InquiryData)->DeviceType == DIRECT_ACCESS_DEVICE)) {

        status = STATUS_NO_SUCH_DEVICE;
        goto CreateDiskDeviceObjectsExit;
    }

    DisableWriteCache(deviceObject,LunInfo);

    writeCache = deviceExtension->DeviceFlags & DEV_WRITE_CACHE;

    //
    // NOTE: At this point one device object has been successfully created.
    // from here on out return success.
    //

    //
    // Do READ CAPACITY. This SCSI command
    // returns the number of bytes on a device.
    // Device extension is updated with device size.
    //

    status = ScsiClassReadDriveCapacity(deviceObject);

    //
    // If the read capcity failed then just return, unless this is a
    // removable disk where a device object partition needs to be created.
    //

    if (!NT_SUCCESS(status) &&
        !(deviceObject->Characteristics & FILE_REMOVABLE_MEDIA)) {

        DebugPrint((1,
            "CreateDiskDeviceObjects: Can't read capacity for device %s\n",
            ntNameBuffer));

        return(STATUS_SUCCESS);

    } else {

        //
        // Make sure the volume verification bit is off so that
        // IoReadPartitionTable will work.
        //

        deviceObject->Flags &= ~DO_VERIFY_VOLUME;
    }

    //
    // Set up sector size fields.
    //
    // Stack variables will be used to update
    // the partition device extensions.
    //
    // The device extension field SectorShift is
    // used to calculate sectors in I/O transfers.
    //
    // The DiskGeometry structure is used to service
    // IOCTls used by the format utility.
    //

    bytesPerSector = diskGeometry->BytesPerSector;

    //
    // Make sure sector size is not zero.
    //

    if (bytesPerSector == 0) {

        //
        // Default sector size for disk is 512.
        //

        bytesPerSector = diskGeometry->BytesPerSector = 512;
    }

    sectorShift = deviceExtension->SectorShift;

    //
    // Set pointer to disk data area that follows device extension.
    //

    diskData = (PDISK_DATA)(deviceExtension + 1);

    //
    // Determine is DM Driver is loaded on an IDE drive that is
    // under control of Atapi - this could be either a crashdump or
    // an Atapi device is sharing the controller with an IDE disk.
    //

    HalExamineMBR(deviceExtension->DeviceObject,
                  deviceExtension->DiskGeometry->BytesPerSector,
                  (ULONG)0x54,
                  (PVOID)&dmSkew);

    if (dmSkew) {

        //
        // Update the device extension, so that the call to IoReadPartitionTable
        // will get the correct information. Any I/O to this disk will have
        // to be skewed by *dmSkew sectors aka DMByteSkew.
        //

        deviceExtension->DMSkew = *dmSkew;
        deviceExtension->DMActive = TRUE;
        deviceExtension->DMByteSkew = deviceExtension->DMSkew * bytesPerSector;

        //
        // Save away the infomation that we need, since this deviceExtension will soon be
        // blown away.
        //

        dmActive = TRUE;
        dmByteSkew = deviceExtension->DMByteSkew;

    }

    //
    // Create objects for all the partitions on the device.
    //

    status = IoReadPartitionTable(deviceObject,
                                  deviceExtension->DiskGeometry->BytesPerSector,
                                  TRUE,
                                  (PVOID)&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) &&
        deviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {

        if (!NT_SUCCESS(status)) {

            //
            // Remember this disk is not ready.
            //

            diskData->DriveNotReady = TRUE;

        } else {

            //
            // Free the partition list allocated by IoReadPartitionTable.
            //

            ExFreePool(partitionList);
        }

        //
        // Allocate and zero a partition list.
        //

        partitionList = ExAllocatePool(NonPagedPool, sizeof(*partitionList ));


        if (partitionList != NULL) {

            RtlZeroMemory( partitionList, sizeof( *partitionList ));

            //
            // 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->PartitionCount = 1;

            status = STATUS_SUCCESS;
        }
    }

    if (NT_SUCCESS(status)) {

        //
        // Record disk signature.
        //

        diskData->Signature = partitionList->Signature;

        //
        // If disk signature is zero, then calculate the MBR checksum.
        //

        if (!diskData->Signature) {

            if (!CalculateMbrCheckSum(deviceExtension,
                                      &diskData->MbrCheckSum)) {

                DebugPrint((1,
                            "SCSIDISK: Can't calculate MBR checksum for disk %x\n",
                            deviceExtension->DeviceNumber));
            } else {

                DebugPrint((2,
                           "SCSIDISK: MBR checksum for disk %x is %x\n",
                           deviceExtension->DeviceNumber,
                           diskData->MbrCheckSum));
            }
        }


        //
        // Check the registry and determine if the BIOS knew about this drive.  If
        // it did then update the geometry with the BIOS information.
        //

        UpdateGeometry(deviceExtension);

        //
        // Create device objects for the device partitions (if any).
        // PartitionCount includes physical device partition 0,
        // so only one partition means no objects to create.
        //

        DebugPrint((2,
                    "CreateDiskDeviceObjects: Number of partitions is %d\n",
                    partitionList->PartitionCount));

        for (partitionNumber = 0; partitionNumber <
            partitionList->PartitionCount; partitionNumber++) {

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

            sprintf(ntNameBuffer,
                    "\\Device\\Harddisk%lu\\Partition%lu",
                    *DeviceCount,
                    partitionNumber + 1);

            DebugPrint((2,
                        "CreateDiskDeviceObjects: Create device object %s\n",
                        ntNameBuffer));

            status = ScsiClassCreateDeviceObject(DriverObject,
                                                 ntNameBuffer,
                                                 physicalDevice,
                                                 &deviceObject,
                                                 InitData);

            if (!NT_SUCCESS(status)) {

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

                break;
            }

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

            deviceObject->Flags |= DO_DIRECT_IO;

            //
            // Check if this is during initialization. If not indicate that
            // system initialization already took place and this disk is ready
            // to be accessed.
            //

            if (!RegistryPath) {
                deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
            }

            deviceObject->StackSize = (CCHAR)PortDeviceObject->StackSize + 1;

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

            deviceExtension = deviceObject->DeviceExtension;

            if (dmActive) {

                //
                // Restore any saved DM values.
                //

                deviceExtension->DMByteSkew = dmByteSkew;
                deviceExtension->DMSkew     = *dmSkew;
                deviceExtension->DMActive   = TRUE;

            }

            //
            // Link new device extension to previous disk data
            // to support dynamic partitioning.
            //

            diskData->NextPartition = deviceExtension;

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

            diskData = (PDISK_DATA)(deviceExtension + 1);

            //
            // Set next partition pointer to NULL in case this is the
            // last partition.
            //

            diskData->NextPartition = NULL;

            //
            // Allocate spinlock for zoning for split-request completion.
            //

            KeInitializeSpinLock(&deviceExtension->SplitRequestSpinLock);

            //
            // Copy port device object pointer to device extension.
            //

            deviceExtension->PortDeviceObject = PortDeviceObject;
            deviceExtension->PortNumber = (UCHAR)PortNumber;

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

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


            if (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.
            //

            ScsiClassInitializeSrbLookasideList(deviceExtension,
                                                numberListElements);

            deviceExtension->SrbFlags = srbFlags;

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

            deviceExtension->SenseData        = senseData;
            deviceExtension->PortCapabilities = PortCapabilities;
            deviceExtension->DiskGeometry     = diskGeometry;
            diskData->PartitionOrdinal        = diskData->PartitionNumber = partitionNumber + 1;
            diskData->PartitionType           = partitionList->PartitionEntry[partitionNumber].PartitionType;
            diskData->BootIndicator           = partitionList->PartitionEntry[partitionNumber].BootIndicator;

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

            deviceExtension->StartingOffset  = partitionList->PartitionEntry[partitionNumber].StartingOffset;
            deviceExtension->PartitionLength = partitionList->PartitionEntry[partitionNumber].PartitionLength;
            diskData->HiddenSectors          = partitionList->PartitionEntry[partitionNumber].HiddenSectors;
            deviceExtension->PortNumber      = (UCHAR)PortNumber;
            deviceExtension->PathId          = pathId;
            deviceExtension->TargetId        = targetId;
            deviceExtension->Lun             = lun;

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

            if (((PINQUIRYDATA)LunInfo->InquiryData)->RemovableMedia) {
                deviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
            }

            //
            // Set timeout value in seconds.
            //

            deviceExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
            deviceExtension->DiskGeometry->BytesPerSector = bytesPerSector;
            deviceExtension->SectorShift  = sectorShift;
            deviceExtension->DeviceObject = deviceObject;
            deviceExtension->DeviceFlags |= physicalDeviceExtension->DeviceFlags;

        } // end for (partitionNumber) ...

        //
        // Free the buffer allocated by reading the
        // partition table.
        //

        ExFreePool(partitionList);

    } else {

        DebugPrint((1,
                    "CreateDiskDeviceObjects: IoReadPartitionTable failed\n"));

    } // end if...else

    return(STATUS_SUCCESS);

CreateDiskDeviceObjectsExit:

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

    ScsiClassClaimDevice(PortDeviceObject,
                         LunInfo,
                         TRUE,
                         NULL);

    if (diskGeometry != NULL) {
        ExFreePool(diskGeometry);
    }

⌨️ 快捷键说明

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