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

📄 disk.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * PROJECT:         ReactOS Storage Stack
 * LICENSE:         DDK - see license.txt in the root dir
 * FILE:            drivers/storage/disk/disk.c
 * PURPOSE:         Disk class driver
 * PROGRAMMERS:     Based on a source code sample from Microsoft NT4 DDK
 */

#include <ntddk.h>
#include <ntdddisk.h>
#include <scsi.h>
#include <ntddscsi.h>
#include <mountdev.h>
#include <mountmgr.h>
#include <include/class2.h>
#include <stdio.h>

//#define NDEBUG
#include <debug.h>

#define IO_WRITE_CACHE_ENABLED  ((NTSTATUS)0x80040020L)
#define IO_WRITE_CACHE_DISABLED ((NTSTATUS)0x80040022L)

#ifdef POOL_TAGGING
#ifdef ExAllocatePool
#undef ExAllocatePool
#endif
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'DscS')
#endif

//
// Disk device data
//

typedef struct _DISK_DATA {

    //
    // Partition chain
    //

    PDEVICE_EXTENSION NextPartition;

    //
    // Disk signature (from MBR)
    //

    ULONG Signature;

    //
    // MBR checksum
    //

    ULONG MbrCheckSum;

    //
    // Number of hidden sectors for BPB.
    //

    ULONG HiddenSectors;

    //
    // Partition number of this device object
    //
    // This field is set during driver initialization or when the partition
    // is created to identify a parition to the system.
    //

    ULONG PartitionNumber;

    //
    // This field is the ordinal of a partition as it appears on a disk.
    //

    ULONG PartitionOrdinal;

    //
    // Partition type of this device object
    //
    // This field is set by:
    //
    //     1)  Initially set according to the partition list entry partition
    //         type returned by IoReadPartitionTable.
    //
    //     2)  Subsequently set by the IOCTL_DISK_SET_PARTITION_INFORMATION
    //         I/O control function when IoSetPartitionInformation function
    //         successfully updates the partition type on the disk.
    //

    UCHAR PartitionType;

    //
    // Boot indicator - indicates whether this partition is a bootable (active)
    // partition for this device
    //
    // This field is set according to the partition list entry boot indicator
    // returned by IoReadPartitionTable.
    //

    BOOLEAN BootIndicator;

    //
    // DriveNotReady - inidicates that the this device is currenly not ready
    // beacasue there is no media in the device.
    //

    BOOLEAN DriveNotReady;

} DISK_DATA, *PDISK_DATA;

//
// Define a general structure of identfing disk controllers with bad
// hardware.
//

typedef struct _BAD_CONTROLLER_INFORMATION {
    PCHAR InquiryString;
    BOOLEAN DisableTaggedQueuing;
    BOOLEAN DisableSynchronousTransfers;
    BOOLEAN DisableDisconnects;
    BOOLEAN DisableWriteCache;
}BAD_CONTROLLER_INFORMATION, *PBAD_CONTROLLER_INFORMATION;

BAD_CONTROLLER_INFORMATION const ScsiDiskBadControllers[] = {
    { "TOSHIBA MK538FB         60",   TRUE,  FALSE, FALSE, FALSE },
    { "CONNER  CP3500",               FALSE, TRUE,  FALSE, FALSE },
    { "OLIVETTICP3500",               FALSE, TRUE,  FALSE, FALSE },
    { "SyQuest SQ5110          CHC",  TRUE,  TRUE,  FALSE, FALSE },
    { "SEAGATE ST41601N        0102", FALSE, TRUE,  FALSE, FALSE },
    { "SEAGATE ST3655N",              FALSE, FALSE, FALSE, TRUE  },
    { "SEAGATE ST3390N",              FALSE, FALSE, FALSE, TRUE  },
    { "SEAGATE ST12550N",             FALSE, FALSE, FALSE, TRUE  },
    { "SEAGATE ST32430N",             FALSE, FALSE, FALSE, TRUE  },
    { "SEAGATE ST31230N",             FALSE, FALSE, FALSE, TRUE  },
    { "SEAGATE ST15230N",             FALSE, FALSE, FALSE, TRUE  },
    { "FUJITSU M2652S-512",           TRUE,  FALSE, FALSE, FALSE },
    { "MAXTOR  MXT-540SL       I1.2", TRUE,  FALSE, FALSE, FALSE },
    { "COMPAQ  PD-1",                 FALSE, TRUE,  FALSE, FALSE }
};


#define NUMBER_OF_BAD_CONTROLLERS (sizeof(ScsiDiskBadControllers) / sizeof(BAD_CONTROLLER_INFORMATION))
#define DEVICE_EXTENSION_SIZE sizeof(DEVICE_EXTENSION) + sizeof(DISK_DATA)

#define MODE_DATA_SIZE      192
#define VALUE_BUFFER_SIZE  2048
#define SCSI_DISK_TIMEOUT    10
#define PARTITION0_LIST_SIZE  4


NTSTATUS
STDCALL
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    );

BOOLEAN
STDCALL
ScsiDiskDeviceVerification(
    IN PINQUIRYDATA InquiryData
    );

BOOLEAN
STDCALL
FindScsiDisks(
    IN PDRIVER_OBJECT DriveObject,
    IN PUNICODE_STRING RegistryPath,
    IN PCLASS_INIT_DATA InitializationData,
    IN PDEVICE_OBJECT PortDeviceObject,
    IN ULONG PortNumber
    );

NTSTATUS
STDCALL
ScsiDiskCreateClose (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

NTSTATUS
STDCALL
ScsiDiskReadWriteVerification(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

NTSTATUS
STDCALL
ScsiDiskDeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

VOID
STDCALL
ScsiDiskProcessError(
    PDEVICE_OBJECT DeviceObject,
    PSCSI_REQUEST_BLOCK Srb,
    NTSTATUS *Status,
    BOOLEAN *Retry
    );

NTSTATUS
STDCALL
ScsiDiskShutdownFlush(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

VOID
STDCALL
DisableWriteCache(
    IN PDEVICE_OBJECT DeviceObject,
    IN PSCSI_INQUIRY_DATA LunInfo
    );

BOOLEAN
STDCALL
ScsiDiskModeSelect(
    IN PDEVICE_OBJECT DeviceObject,
    IN PCHAR ModeSelectBuffer,
    IN ULONG Length,
    IN BOOLEAN SavePage
    );

BOOLEAN
STDCALL
IsFloppyDevice(
    IN PDEVICE_OBJECT DeviceObject
    );

BOOLEAN
STDCALL
CalculateMbrCheckSum(
    IN PDEVICE_EXTENSION DeviceExtension,
    OUT PULONG Checksum
    );

BOOLEAN
STDCALL
EnumerateBusKey(
    IN PDEVICE_EXTENSION DeviceExtension,
    HANDLE BusKey,
    PULONG DiskNumber
    );

VOID
STDCALL
UpdateGeometry(
    IN PDEVICE_EXTENSION DeviceExtension
    );

NTSTATUS
STDCALL
UpdateRemovableGeometry (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

NTSTATUS
STDCALL
CreateDiskDeviceObject(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath,
    IN PDEVICE_OBJECT PortDeviceObject,
    IN ULONG PortNumber,
    IN PULONG DeviceCount,
    IN PIO_SCSI_CAPABILITIES PortCapabilities,
    IN PSCSI_INQUIRY_DATA LunInfo,
    IN PCLASS_INIT_DATA InitData
    );

VOID
STDCALL
UpdateDeviceObjects(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

VOID
STDCALL
ScanForSpecial(
    PDEVICE_OBJECT DeviceObject,
    PSCSI_INQUIRY_DATA LunInfo,
    PIO_SCSI_CAPABILITIES PortCapabilities
    );

VOID
STDCALL
ResetScsiBus(
    IN PDEVICE_OBJECT DeviceObject
    );

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, DriverEntry)
#pragma alloc_text(PAGE, FindScsiDisks)
#pragma alloc_text(PAGE, CreateDiskDeviceObject)
#pragma alloc_text(PAGE, CalculateMbrCheckSum)
#pragma alloc_text(PAGE, EnumerateBusKey)
#pragma alloc_text(PAGE, UpdateGeometry)
#pragma alloc_text(PAGE, IsFloppyDevice)
#pragma alloc_text(PAGE, ScanForSpecial)
#pragma alloc_text(PAGE, ScsiDiskDeviceControl)
#pragma alloc_text(PAGE, ScsiDiskModeSelect)
#endif


NTSTATUS
STDCALL
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This routine initializes the SCSI hard disk class driver.

Arguments:

    DriverObject - Pointer to driver object created by system.

    RegistryPath - Pointer to the name of the services node for this driver.

Return Value:

    The function value is the final status from the initialization operation.

--*/

{
    CLASS_INIT_DATA InitializationData;

    //
    // Zero InitData
    //

    RtlZeroMemory (&InitializationData, sizeof(CLASS_INIT_DATA));

    //
    // Set sizes
    //

    InitializationData.InitializationDataSize = sizeof(CLASS_INIT_DATA);
    InitializationData.DeviceExtensionSize = DEVICE_EXTENSION_SIZE;

    InitializationData.DeviceType = FILE_DEVICE_DISK;
    InitializationData.DeviceCharacteristics = 0;

    //
    // Set entry points
    //

    InitializationData.ClassError = ScsiDiskProcessError;
    InitializationData.ClassReadWriteVerification = ScsiDiskReadWriteVerification;
    InitializationData.ClassFindDevices = FindScsiDisks;
    InitializationData.ClassFindDeviceCallBack = ScsiDiskDeviceVerification;
    InitializationData.ClassDeviceControl = ScsiDiskDeviceControl;
    InitializationData.ClassShutdownFlush = ScsiDiskShutdownFlush;
    InitializationData.ClassCreateClose = NULL;

    //
    // Call the class init routine
    //

    return ScsiClassInitialize( DriverObject, RegistryPath, &InitializationData);

} // end DriverEntry()



BOOLEAN
STDCALL
ScsiDiskDeviceVerification(
    IN PINQUIRYDATA InquiryData
    )

/*++

Routine Description:

    This routine checks InquiryData for the correct device type and qualifier.

Arguments:

    InquiryData - Pointer to the inquiry data for the device in question.

Return Value:

    True is returned if the correct device type is found.

--*/
{

    if (((InquiryData->DeviceType == DIRECT_ACCESS_DEVICE) ||
        (InquiryData->DeviceType == OPTICAL_DEVICE)) &&
        InquiryData->DeviceTypeQualifier == 0) {

        return TRUE;

    } else {
        return FALSE;
    }
}


BOOLEAN
STDCALL
FindScsiDisks(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath,
    IN PCLASS_INIT_DATA InitializationData,
    IN PDEVICE_OBJECT PortDeviceObject,
    IN ULONG PortNumber
    )

/*++

Routine Description:

    This routine gets a port drivers capabilities, obtains the
    inquiry data, searches the SCSI bus for the port driver and creates
    the device objects for the disks found.

Arguments:

    DriverObject - Pointer to driver object created by system.

    PortDeviceObject - Device object use to send requests to port driver.

    PortNumber - Number for port driver.  Used to pass on to
                 CreateDiskDeviceObjects() and create device objects.

Return Value:

    True is returned if one disk was found and successfully created.

--*/

{
    PIO_SCSI_CAPABILITIES portCapabilities;
    PULONG diskCount;
    PCONFIGURATION_INFORMATION configurationInformation;
    PCHAR buffer;
    PSCSI_INQUIRY_DATA lunInfo;
    PSCSI_ADAPTER_BUS_INFO  adapterInfo;
    PINQUIRYDATA inquiryData;
    ULONG scsiBus;
    ULONG adapterDisk;
    NTSTATUS status;
    BOOLEAN foundOne = FALSE;

    PAGED_CODE();

⌨️ 快捷键说明

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