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

📄 cdrom.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/cdrom/cdrom.c
 * PURPOSE:         CDROM driver
 * PROGRAMMERS:     Based on a source code sample from Microsoft NT4 DDK
 */

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

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

#define CDB12GENERIC_LENGTH 12

typedef struct _XA_CONTEXT {

    //
    // Pointer to the device object.
    //

    PDEVICE_OBJECT DeviceObject;

    //
    // Pointer to the original request when
    // a mode select must be sent.
    //

    PIRP OriginalRequest;

    //
    // Pointer to the mode select srb.
    //

    PSCSI_REQUEST_BLOCK Srb;
} XA_CONTEXT, *PXA_CONTEXT;

typedef struct _ERROR_RECOVERY_DATA {
    MODE_PARAMETER_HEADER   Header;
    MODE_PARAMETER_BLOCK BlockDescriptor;
    MODE_READ_RECOVERY_PAGE ReadRecoveryPage;
} ERROR_RECOVERY_DATA, *PERROR_RECOVERY_DATA;

typedef struct _ERROR_RECOVERY_DATA10 {
    MODE_PARAMETER_HEADER10 Header10;
    MODE_PARAMETER_BLOCK BlockDescriptor10;
    MODE_READ_RECOVERY_PAGE ReadRecoveryPage10;
} ERROR_RECOVERY_DATA10, *PERROR_RECOVERY_DATA10;

//
// CdRom specific addition to device extension.
//

typedef struct _CDROM_DATA {

    //
    // Indicates whether an audio play operation
    // is currently being performed.
    //

    BOOLEAN PlayActive;

    //
    // Indicates whether the blocksize used for user data
    // is 2048 or 2352.
    //

    BOOLEAN RawAccess;

    //
    // Indicates whether 6 or 10 byte mode sense/select
    // should be used.
    //

    USHORT XAFlags;

    //
    // Storage for the error recovery page. This is used
    // as an easy method to switch block sizes.
    //

    union {
        ERROR_RECOVERY_DATA u1;
        ERROR_RECOVERY_DATA10 u2;
    };


    //
    // Pointer to the original irp for the raw read.
    //

    PIRP SavedReadIrp;

    //
    // Used to protect accesses to the RawAccess flag.
    //

    KSPIN_LOCK FormSpinLock;

    //
    // Even if media change support is requested, there are some devices
    // that are not supported.  This flag will indicate that such a device
    // is present when it is FALSE.
    //

    BOOLEAN MediaChangeSupported;

    //
    // The media change event is being supported.  The media change timer
    // should be running whenever this is true.
    //

    BOOLEAN MediaChange;

    //
    // The timer value to support media change events.  This is a countdown
    // value used to determine when to poll the device for a media change.
    // The max value for the timer is 255 seconds.
    //

    UCHAR MediaChangeCountDown;

#ifdef DBG
    //
    // Second timer to keep track of how long the media change IRP has been
    // in use.  If this value exceeds the timeout (#defined) then we should
    // print out a message to the user and set the MediaChangeIrpLost flag
    //

    SHORT MediaChangeIrpTimeInUse;

    //
    // Set by CdRomTickHandler when we determine that the media change irp has
    // been lost
    //

    BOOLEAN MediaChangeIrpLost;
#endif

    UCHAR PadReserve; // use this for new flags.

    //
    // An IRP is allocated and kept for the duration that media change
    // detection is in effect.  If this is NULL and MediaChange is TRUE,
    // the detection is in progress.  This should always be NULL when
    // MediaChange is FALSE.
    //

    PIRP MediaChangeIrp;

    //
    // The timer work list is a collection of IRPS that are prepared for
    // submission, but need to allow some time to pass before they are
    // run.
    //

    LIST_ENTRY TimerIrpList;
    KSPIN_LOCK TimerIrpSpinLock;

} CDROM_DATA, *PCDROM_DATA;

#define DEVICE_EXTENSION_SIZE sizeof(DEVICE_EXTENSION) + sizeof(CDROM_DATA)
#define SCSI_CDROM_TIMEOUT          10
#define SCSI_CHANGER_BONUS_TIMEOUT  10
#define HITACHI_MODE_DATA_SIZE      12
#define MODE_DATA_SIZE              64
#define RAW_SECTOR_SIZE           2352
#define COOKED_SECTOR_SIZE        2048
#define MEDIA_CHANGE_DEFAULT_TIME    4
#define CDROM_SRB_LIST_SIZE          4


#ifdef DBG

//
// Used to detect the loss of the autorun irp.  The driver prints out a message
// (debug level 0) if this timeout ever occurs
//
#define MEDIA_CHANGE_TIMEOUT_TIME  300

#endif

#define PLAY_ACTIVE(DeviceExtension) (((PCDROM_DATA)(DeviceExtension + 1))->PlayActive)

#define MSF_TO_LBA(Minutes,Seconds,Frames) \
                (ULONG)((60 * 75 * (Minutes)) + (75 * (Seconds)) + ((Frames) - 150))

#define LBA_TO_MSF(Lba,Minutes,Seconds,Frames)               \
{                                                            \
    (Minutes) = (UCHAR)(Lba  / (60 * 75));                   \
    (Seconds) = (UCHAR)((Lba % (60 * 75)) / 75);             \
    (Frames)  = (UCHAR)((Lba % (60 * 75)) % 75);             \
}

#define DEC_TO_BCD(x) (((x / 10) << 4) + (x % 10))

//
// Define flags for XA, CDDA, and Mode Select/Sense
//

#define XA_USE_6_BYTE             0x01
#define XA_USE_10_BYTE            0x02
#define XA_USE_READ_CD            0x04
#define XA_NOT_SUPPORTED          0x08

#define PLEXTOR_CDDA              0x10
#define NEC_CDDA                  0x20

//
// Sector types for READ_CD
//

#define ANY_SECTOR                0
#define CD_DA_SECTOR              1
#define YELLOW_MODE1_SECTOR       2
#define YELLOW_MODE2_SECTOR       3
#define FORM2_MODE1_SECTOR        4
#define FORM2_MODE2_SECTOR        5


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

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

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

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

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

NTSTATUS
STDCALL
ScsiCdRomSwitchMode(
    IN PDEVICE_OBJECT DeviceObject,
    IN ULONG SectorSize,
    IN PIRP  OriginalRequest
    );

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

NTSTATUS
STDCALL
CdRomDeviceControlCompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    );

NTSTATUS
STDCALL
CdRomSetVolumeIntermediateCompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    );

NTSTATUS
STDCALL
CdRomSwitchModeCompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    );

NTSTATUS
STDCALL
CdRomXACompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    );

NTSTATUS
STDCALL
CdRomClassIoctlCompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    );

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

VOID
STDCALL
CdRomTickHandler(
    IN PDEVICE_OBJECT DeviceObject,
    IN PVOID Context
    );

BOOLEAN
STDCALL
CdRomCheckRegistryForMediaChangeValue(
    IN PUNICODE_STRING RegistryPath,
    IN ULONG DeviceNumber
    );

NTSTATUS
STDCALL
CdRomUpdateCapacity(
    IN PDEVICE_EXTENSION DeviceExtension,
    IN PIRP IrpToComplete,
    IN OPTIONAL PKEVENT IoctlEvent
    );

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

VOID
STDCALL
ScanForSpecial(
    PDEVICE_OBJECT DeviceObject,
    PINQUIRYDATA InquiryData,
    PIO_SCSI_CAPABILITIES PortCapabilities
    );

BOOLEAN
STDCALL
CdRomIsPlayActive(
    IN PDEVICE_OBJECT DeviceObject
    );

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

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

BOOLEAN
STDCALL
IsThisAnAtapiChanger(
    IN  PDEVICE_OBJECT DeviceObject,
    OUT PULONG         DiscsPresent
    );

BOOLEAN
STDCALL
IsThisASanyo(
    IN  PDEVICE_OBJECT DeviceObject,
    IN  UCHAR          PathId,
    IN  UCHAR          TargetId
    );

BOOLEAN
STDCALL
IsThisAMultiLunDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN PDEVICE_OBJECT PortDeviceObject
    );

VOID
STDCALL
CdRomCreateNamedEvent(
    IN PDEVICE_EXTENSION DeviceExtension,
    IN ULONG DeviceNumber
    );

⌨️ 快捷键说明

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