Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293/*++
Copyright (C) Microsoft Corporation, 1991 - 2010
Module Name:
disk.c
Abstract:
SCSI disk class driver
Environment:
kernel mode only
Notes:
Revision History:
--*/
#include "ntddk.h"#include "scsi.h"#include <wmidata.h>#include "classpnp.h"
#include <wmistr.h>#include "ntstrsafe.h"
//// Set component ID for DbgPrintEx calls//#ifndef DEBUG_COMP_ID#define DEBUG_COMP_ID DPFLTR_DISK_ID#endif
//// Include header file and setup GUID for tracing//#include <storswtr.h>#define WPP_GUID_DISK (945186BF, 3DD6, 4f3f, 9C8E, 9EDD3FC9D558)#ifndef WPP_CONTROL_GUIDS#define WPP_CONTROL_GUIDS WPP_CONTROL_GUIDS_NORMAL_FLAGS(WPP_GUID_DISK)#endif
#ifdef ExAllocatePool#undef ExAllocatePool#define ExAllocatePool #NT_ASSERT(FALSE)#endif
#define DISK_TAG_GENERAL ' DcS' // "ScD " - generic tag#define DISK_TAG_SMART 'aDcS' // "ScDa" - SMART allocations#define DISK_TAG_INFO_EXCEPTION 'ADcS' // "ScDA" - Info Exceptions#define DISK_TAG_DISABLE_CACHE 'CDcS' // "ScDC" - disable cache paths#define DISK_TAG_CCONTEXT 'cDcS' // "ScDc" - disk allocated completion context#define DISK_TAG_DISK_GEOM 'GDcS' // "ScDG" - disk geometry buffer#define DISK_TAG_UPDATE_GEOM 'gDcS' // "ScDg" - update disk geometry paths#define DISK_TAG_SENSE_INFO 'IDcS' // "ScDI" - sense info buffers#define DISK_TAG_PNP_ID 'iDcS' // "ScDp" - pnp ids#define DISK_TAG_MODE_DATA 'MDcS' // "ScDM" - mode data buffer#define DISK_CACHE_MBR_CHECK 'mDcS' // "ScDM" - mbr checksum code#define DISK_TAG_NAME 'NDcS' // "ScDN" - disk name code#define DISK_TAG_READ_CAP 'PDcS' // "ScDP" - read capacity buffer#define DISK_TAG_PART_LIST 'pDcS' // "ScDp" - disk partition lists#define DISK_TAG_SRB 'SDcS' // "ScDS" - srb allocation#define DISK_TAG_START 'sDcS' // "ScDs" - start device paths#define DISK_TAG_UPDATE_CAP 'UDcS' // "ScDU" - update capacity path#define DISK_TAG_WI_CONTEXT 'WDcS' // "ScDW" - work-item context
#ifdef __REACTOS__#undef MdlMappingNoExecute#define MdlMappingNoExecute 0#define NonPagedPoolNx NonPagedPool#define NonPagedPoolNxCacheAligned NonPagedPoolCacheAligned#undef POOL_NX_ALLOCATION#define POOL_NX_ALLOCATION 0#endif
#if defined(_X86_) || defined(_AMD64_)
//// Disk device data//
typedef enum _DISK_GEOMETRY_SOURCE { DiskGeometryUnknown, DiskGeometryFromBios, DiskGeometryFromPort, DiskGeometryFromNec98, DiskGeometryGuessedFromBios, DiskGeometryFromDefault, DiskGeometryFromNT4} DISK_GEOMETRY_SOURCE, *PDISK_GEOMETRY_SOURCE;#endif
//// Context for requests that can be combined and sent down//
typedef struct _DISK_GROUP_CONTEXT{ // // Queue of requests whose representative is currently outstanding at the port driver // LIST_ENTRY CurrList;
// // The representative for the above queue // PIRP CurrIrp;
// // Queue of requests whose representative is waiting to go down // LIST_ENTRY NextList;
// // The representative for the above queue // PIRP NextIrp;
// // The srb associated with this group //#if (NTDDI_VERSION >= NTDDI_WIN8)
union { SCSI_REQUEST_BLOCK Srb; STORAGE_REQUEST_BLOCK SrbEx; UCHAR SrbExBuffer[CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE]; } Srb;
#else SCSI_REQUEST_BLOCK Srb;#endif
// // The spinlock that will synchronize access to this context // KSPIN_LOCK Spinlock;
// // This event will allow for the requests to be sent down synchronously // KEVENT Event;
#if DBG
// // This counter maintains the number of requests currently tagged // to the request that is waiting to go down // ULONG DbgTagCount;
// // This counter maintains the number of requests that were avoided // ULONG DbgSavCount;
// // This counter maintains the total number of times that we combined // requests and the respective number of requests that were tagged // ULONG DbgRefCount[64];
#endif
} DISK_GROUP_CONTEXT, *PDISK_GROUP_CONTEXT;
//// Write cache setting as defined by the user//typedef enum _DISK_USER_WRITE_CACHE_SETTING{ DiskWriteCacheDisable = 0, DiskWriteCacheEnable = 1, DiskWriteCacheDefault = -1
} DISK_USER_WRITE_CACHE_SETTING, *PDISK_USER_WRITE_CACHE_SETTING;
typedef struct _DISK_DATA {
// // This field is the ordinal of a partition as it appears on a disk. //
ULONG PartitionOrdinal;
// // How has this disk been partitioned? Either EFI or MBR. //
PARTITION_STYLE PartitionStyle;
union {
struct {
// // Disk signature (from MBR) //
ULONG Signature;
// // MBR checksum //
ULONG MbrCheckSum;
// // Number of hidden sectors for BPB. //
ULONG HiddenSectors;
// // 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;
} Mbr;
struct {
// // The DiskGUID field from the EFI partition header. //
GUID DiskId;
// // Partition type of this device object. //
GUID PartitionType;
// // Unique partition identifier for this partition. //
GUID PartitionId;
// // EFI partition attributes for this partition. //
ULONG64 Attributes;
// // EFI partition name of this partition. //
WCHAR PartitionName[36];
} Efi;
#ifdef _MSC_VER#pragma warning(suppress: 4201) //this is intended to be an unnamed union#endif };
struct { // // This flag is set when the well known name is created (through // DiskCreateSymbolicLinks) and cleared when destroying it // (by calling DiskDeleteSymbolicLinks). //
unsigned int WellKnownNameCreated : 1;
// // This flag is set when the PhysicalDriveN link is created (through // DiskCreateSymbolicLinks) and is cleared when destroying it (through // DiskDeleteSymbolicLinks) //
unsigned int PhysicalDriveLinkCreated : 1;
} LinkStatus;
// // ReadyStatus - STATUS_SUCCESS indicates that the drive is ready for // use. Any error status is to be returned as an explaination for why // a request is failed. // // This was done solely for the zero-length partition case of having no // media in a removable disk drive. When that occurs, and a read is sent // to the zero-length non-partition-zero PDO that was created, we had to // be able to fail the request with a reasonable value. This may not have // been the best way to do this, but it works. //
NTSTATUS ReadyStatus;
// // SCSI address used for SMART operations. //
SCSI_ADDRESS ScsiAddress;
// // What type of failure prediction mechanism is available //
FAILURE_PREDICTION_METHOD FailurePredictionCapability; BOOLEAN AllowFPPerfHit;
// // Indicates that the SCSI Informational Exceptions mode page is supported. // Note that this only indicates *support* and does not necessarily // indicate that Informational Exception reporting via sense code is // actually enabled. // BOOLEAN ScsiInfoExceptionsSupported;
// // Indicates if failure prediction is actually enabled (via whatever) // method is applicable as indicated by FailurePredictionCapability. // BOOLEAN FailurePredictionEnabled;
#if defined(_X86_) || defined(_AMD64_) // // This flag indiciates that a non-default geometry for this drive has // already been determined by the disk driver. This field is ignored // for removable media drives. //
DISK_GEOMETRY_SOURCE GeometrySource;
// // If GeometryDetermined is TRUE this will contain the geometry which was // reported by the firmware or by the BIOS. For removable media drives // this will contain the last geometry used when media was present. //
DISK_GEOMETRY RealGeometry;#endif
// // This mutex prevents more than one IOCTL_DISK_VERIFY from being // sent down to the disk. This greatly reduces the possibility of // a Denial-of-Service attack //
KMUTEX VerifyMutex;
// // This allows for parallel flush requests to be combined into one so as to // reduce the number of outstanding requests that are sent down to the disk //
DISK_GROUP_CONTEXT FlushContext;
// // The user-specified disk write cache setting //
DISK_USER_WRITE_CACHE_SETTING WriteCacheOverride;
} DISK_DATA, *PDISK_DATA;
//// Define a general structure of identfing disk controllers with bad// hardware.//
#define HackDisableTaggedQueuing (0x01)#define HackDisableSynchronousTransfers (0x02)#define HackDisableSpinDown (0x04)#define HackDisableWriteCache (0x08)#define HackCauseNotReportableHack (0x10)#define HackRequiresStartUnitCommand (0x20)
#define DiskDeviceParameterSubkey L"Disk"#define DiskDeviceUserWriteCacheSetting L"UserWriteCacheSetting"#define DiskDeviceCacheIsPowerProtected L"CacheIsPowerProtected"
#define FUNCTIONAL_EXTENSION_SIZE sizeof(FUNCTIONAL_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
#define MAX_MEDIA_TYPES 4typedef struct _DISK_MEDIA_TYPES_LIST { PCCHAR VendorId; PCCHAR ProductId; PCCHAR Revision; const ULONG NumberOfTypes; const ULONG NumberOfSides; const STORAGE_MEDIA_TYPE MediaTypes[MAX_MEDIA_TYPES];} DISK_MEDIA_TYPES_LIST, *PDISK_MEDIA_TYPES_LIST;
//// WMI reregistration structures used for reregister work item//typedef struct{ SINGLE_LIST_ENTRY Next; PDEVICE_OBJECT DeviceObject; PIRP Irp;} DISKREREGREQUEST, *PDISKREREGREQUEST;
#define MAX_SECTORS_PER_VERIFY 0x100
//// This is based off 100ns units//#define ONE_MILLI_SECOND ((ULONGLONG)10 * 1000)
//// Context for the work-item//typedef struct _DISK_VERIFY_WORKITEM_CONTEXT{ PIRP Irp; PSCSI_REQUEST_BLOCK Srb; PIO_WORKITEM WorkItem;
} DISK_VERIFY_WORKITEM_CONTEXT, *PDISK_VERIFY_WORKITEM_CONTEXT;
//// Poll for Failure Prediction every hour//#define DISK_DEFAULT_FAILURE_POLLING_PERIOD 1 * 60 * 60
#define CHECK_IRQL() \ if (KeGetCurrentIrql() >= DISPATCH_LEVEL) { \ NT_ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); \ return STATUS_INVALID_LEVEL; \ }
//// Static global lookup tables.//
extern CLASSPNP_SCAN_FOR_SPECIAL_INFO DiskBadControllers[];extern const DISK_MEDIA_TYPES_LIST DiskMediaTypes[];extern const DISK_MEDIA_TYPES_LIST DiskMediaTypesExclude[];
#if defined(__REACTOS__) && defined(_MSC_VER)# pragma section("PAGECONS", read)# pragma section("PAGEDATA", read,write)#endif//// Macros//
//// Routine prototypes.//
DRIVER_INITIALIZE DriverEntry;
VOIDNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskUnload( IN PDRIVER_OBJECT DriverObject );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT Pdo );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskInitFdo( IN PDEVICE_OBJECT Fdo );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskStartFdo( IN PDEVICE_OBJECT Fdo );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskStopDevice( IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskRemoveDevice( IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskReadWriteVerification( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
VOIDNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskFdoProcessError( PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskShutdownFlush( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskGetCacheInformation( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskSetCacheInformation( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo );
VOIDDiskLogCacheInformation( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo, IN NTSTATUS Status );
NTSTATUSDiskIoctlGetCacheSetting( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
NTSTATUSDiskIoctlSetCacheSetting( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
IO_WORKITEM_ROUTINE DisableWriteCache;
IO_WORKITEM_ROUTINE DiskIoctlVerifyThread;
VOIDDiskFlushDispatch( IN PDEVICE_OBJECT Fdo, IN PDISK_GROUP_CONTEXT FlushContext );
IO_COMPLETION_ROUTINE DiskFlushComplete;
NTSTATUSDiskModeSelect( IN PDEVICE_OBJECT DeviceObject, _In_reads_bytes_(Length) PCHAR ModeSelectBuffer, IN ULONG Length, IN BOOLEAN SavePage );
//// We need to validate that the self test subcommand is valid and// appropriate. Right now we allow subcommands 0, 1 and 2 which are non// captive mode tests. Once we figure out a way to know if it is safe to// run a captive test then we can allow captive mode tests. Also if the// atapi 5 spec is ever updated to denote that bit 7 is the captive// mode bit, we can allow any request that does not have bit 7 set. Until// that is done we want to be sure//#define DiskIsValidSmartSelfTest(Subcommand) \ ( ((Subcommand) == SMART_OFFLINE_ROUTINE_OFFLINE) || \ ((Subcommand) == SMART_SHORT_SELFTEST_OFFLINE) || \ ((Subcommand) == SMART_EXTENDED_SELFTEST_OFFLINE) )
NTSTATUSDiskPerformSmartCommand( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN ULONG SrbControlCode, IN UCHAR Command, IN UCHAR Feature, IN UCHAR SectorCount, IN UCHAR SectorNumber, IN OUT PSRB_IO_CONTROL SrbControl, OUT PULONG BufferSize );
NTSTATUSDiskGetInfoExceptionInformation( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, OUT PMODE_INFO_EXCEPTIONS ReturnPageData );
NTSTATUSDiskSetInfoExceptionInformation( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMODE_INFO_EXCEPTIONS PageData );
#if (NTDDI_VERSION >= NTDDI_WINBLUE)NTSTATUSDiskGetModePage( _In_ PDEVICE_OBJECT Fdo, _In_ UCHAR PageMode, _In_ UCHAR PageControl, _In_ PMODE_PARAMETER_HEADER ModeData, _Inout_ PULONG ModeDataSize, _Out_ PVOID* PageData );
NTSTATUSDiskEnableInfoExceptions( _In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ BOOLEAN Enable );#endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
NTSTATUSDiskDetectFailurePrediction( PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PFAILURE_PREDICTION_METHOD FailurePredictCapability, BOOLEAN ScsiAddressAvailable );
NTSTATUSDiskCreateFdo( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT LowerDeviceObject, IN PULONG DeviceCount, IN BOOLEAN DasdAccessOnly );
VOIDNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskSetSpecialHacks( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN ULONG_PTR Data );
VOIDResetBus( IN PDEVICE_OBJECT DeviceObject );
NTSTATUSDiskGenerateDeviceName( IN ULONG DeviceNumber, OUT PCCHAR *RawName );
VOIDDiskCreateSymbolicLinks( IN PDEVICE_OBJECT DeviceObject );
VOIDDiskDeleteSymbolicLinks( IN PDEVICE_OBJECT DeviceObject );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskFdoQueryWmiRegInfo( IN PDEVICE_OBJECT DeviceObject, OUT ULONG *RegFlags, OUT PUNICODE_STRING InstanceName );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskFdoQueryWmiRegInfoEx( IN PDEVICE_OBJECT DeviceObject, OUT ULONG *RegFlags, OUT PUNICODE_STRING InstanceName, OUT PUNICODE_STRING MofName );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskFdoQueryWmiDataBlock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG BufferAvail, OUT PUCHAR Buffer );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskFdoSetWmiDataBlock( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG BufferSize, IN PUCHAR Buffer );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskFdoSetWmiDataItem( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG DataItemId, IN ULONG BufferSize, IN PUCHAR Buffer );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskFdoExecuteWmiMethod( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG MethodId, IN ULONG InBufferSize, IN ULONG OutBufferSize, IN PUCHAR Buffer );
NTSTATUSNTAPI /* ReactOS Change: GCC Does not support STDCALL by default */DiskWmiFunctionControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN CLASSENABLEDISABLEFUNCTION Function, IN BOOLEAN Enable );
NTSTATUSDiskReadFailurePredictStatus( PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus );
NTSTATUSDiskReadFailurePredictData( PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData );
NTSTATUSDiskEnableDisableFailurePrediction( PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable );
NTSTATUSDiskEnableDisableFailurePredictPolling( PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable, ULONG PollTimeInSeconds );
NTSTATUS DiskInitializeReregistration( VOID );
extern GUIDREGINFO DiskWmiFdoGuidList[];
#if defined(_X86_) || defined(_AMD64_)NTSTATUSDiskReadDriveCapacity( IN PDEVICE_OBJECT Fdo );#else#define DiskReadDriveCapacity(Fdo) ClassReadDriveCapacity(Fdo)#endif
#if defined(_X86_) || defined(_AMD64_)
NTSTATUSDiskSaveDetectInfo( PDRIVER_OBJECT DriverObject );
VOIDDiskCleanupDetectInfo( IN PDRIVER_OBJECT DriverObject );
VOIDDiskDriverReinitialization ( IN PDRIVER_OBJECT DriverObject, IN PVOID Nothing, IN ULONG Count );
#endif
#if defined(_X86_) || defined(_AMD64_)NTSTATUSDiskGetDetectInfo( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, OUT PDISK_DETECTION_INFO DetectInfo );
NTSTATUSDiskReadSignature( IN PDEVICE_OBJECT Fdo );
BOOLEANDiskIsNT4Geometry( IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension );
#else#define DiskGetDetectInfo(FdoExtension, DetectInfo) (STATUS_UNSUCCESSFUL)#endif
#define DiskHashGuid(Guid) (((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0] ^ ((PULONG) &Guid)[0])
NTSTATUSDiskDetermineMediaTypes( IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN UCHAR MediumType, IN UCHAR DensityCode, IN BOOLEAN MediaPresent, IN BOOLEAN IsWritable );
NTSTATUSDiskIoctlGetLengthInfo( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
NTSTATUSDiskIoctlGetDriveGeometry( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlGetDriveGeometryEx( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
NTSTATUSDiskIoctlGetCacheInformation( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlSetCacheInformation( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlGetMediaTypesEx( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlPredictFailure( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlEnableFailurePrediction( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlVerify( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlReassignBlocks( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlReassignBlocksEx( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlIsWritable( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlSetVerify( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlClearVerify( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlUpdateDriveSize( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlGetVolumeDiskExtents( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlSmartGetVersion( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlSmartReceiveDriveData( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
NTSTATUSDiskIoctlSmartSendDriveCommand( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp );
FORCEINLINE // __REACTOS__PCDBGetSrbScsiData( _In_ PSTORAGE_REQUEST_BLOCK SrbEx, _In_opt_ PUCHAR CdbLength8, _In_opt_ PULONG CdbLength32, _In_opt_ PUCHAR ScsiStatus, _In_opt_ PVOID *SenseInfoBuffer, _In_opt_ PUCHAR SenseInfoBufferLength )/*++
Routine Description:
Helper function to retrieve SCSI related fields from an extended SRB. If SRB is not a SRB_FUNCTION_EXECUTE_SCSI or not an extended SRB, default values will be returned.
Arguments:
SrbEx - Pointer to extended SRB.
CdbLength8 - Pointer to buffer to hold CdbLength field value for SRBEX_DATA_SCSI_CDB16 or SRBEX_DATA_SCSI_CDB32
CdbLength32 - Pointer to buffer to hold CdbLength field value for SRBEX_DATA_SCSI_CDB_VAR
ScsiStatus - Pointer to buffer to hold ScsiStatus field value.
SenseInfoBuffer - Pointer to buffer to hold SenseInfoBuffer value.
SenseInfoBufferLength - Pointer to buffer to hold SenseInfoBufferLength value.
Return Value:
Pointer to Cdb field or NULL if SRB is not a SRB_FUNCTION_EXECUTE_SCSI.
--*/{ PCDB Cdb = NULL; ULONG i; PSRBEX_DATA SrbExData = NULL; BOOLEAN FoundEntry = FALSE;
if ((SrbEx->Function == SRB_FUNCTION_STORAGE_REQUEST_BLOCK) && (SrbEx->SrbFunction == SRB_FUNCTION_EXECUTE_SCSI)) { NT_ASSERT(SrbEx->NumSrbExData > 0);
for (i = 0; i < SrbEx->NumSrbExData; i++) {
// Skip any invalid offsets if ((SrbEx->SrbExDataOffset[i] < sizeof(STORAGE_REQUEST_BLOCK)) || (SrbEx->SrbExDataOffset[i] > SrbEx->SrbLength)){ // Catch any invalid offsets NT_ASSERT(FALSE); continue; }
SrbExData = (PSRBEX_DATA)((PUCHAR)SrbEx + SrbEx->SrbExDataOffset[i]);
switch (SrbExData->Type) {
case SrbExDataTypeScsiCdb16: if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB16) <= SrbEx->SrbLength) { FoundEntry = TRUE; if (CdbLength8) { *CdbLength8 = ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->CdbLength; }
if (((PSRBEX_DATA_SCSI_CDB16) SrbExData)->CdbLength > 0) { Cdb = (PCDB)((PSRBEX_DATA_SCSI_CDB16) SrbExData)->Cdb; }
if (ScsiStatus) { *ScsiStatus = ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->ScsiStatus; }
if (SenseInfoBuffer) { *SenseInfoBuffer = ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->SenseInfoBuffer; }
if (SenseInfoBufferLength) { *SenseInfoBufferLength = ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->SenseInfoBufferLength; }
} else { // Catch invalid offset NT_ASSERT(FALSE); } break;
case SrbExDataTypeScsiCdb32: if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB32) <= SrbEx->SrbLength) { FoundEntry = TRUE; if (CdbLength8) { *CdbLength8 = ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->CdbLength; }
if (((PSRBEX_DATA_SCSI_CDB32) SrbExData)->CdbLength > 0) { Cdb = (PCDB)((PSRBEX_DATA_SCSI_CDB32) SrbExData)->Cdb; }
if (ScsiStatus) { *ScsiStatus = ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->ScsiStatus; }
if (SenseInfoBuffer) { *SenseInfoBuffer = ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->SenseInfoBuffer; }
if (SenseInfoBufferLength) { *SenseInfoBufferLength = ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->SenseInfoBufferLength; }
} else { // Catch invalid offset NT_ASSERT(FALSE); } break;
case SrbExDataTypeScsiCdbVar: if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB_VAR) <= SrbEx->SrbLength) { FoundEntry = TRUE; if (CdbLength32) { *CdbLength32 = ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->CdbLength; }
if (((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->CdbLength > 0) { Cdb = (PCDB)((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->Cdb; }
if (ScsiStatus) { *ScsiStatus = ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->ScsiStatus; }
if (SenseInfoBuffer) { *SenseInfoBuffer = ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->SenseInfoBuffer; }
if (SenseInfoBufferLength) { *SenseInfoBufferLength = ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->SenseInfoBufferLength; }
} else { // Catch invalid offset NT_ASSERT(FALSE); } break; }
if (FoundEntry) { break; } }
} else {
if (CdbLength8) { *CdbLength8 = 0; }
if (CdbLength32) { *CdbLength32 = 0; }
if (ScsiStatus) { *ScsiStatus = 0; }
if (SenseInfoBuffer) { *SenseInfoBuffer = NULL; }
if (SenseInfoBufferLength) { *SenseInfoBufferLength = 0; } }
return Cdb;}
FORCEINLINE // __REACTOS__VOIDSetSrbScsiData( _In_ PSTORAGE_REQUEST_BLOCK SrbEx, _In_ UCHAR CdbLength8, _In_ ULONG CdbLength32, _In_ UCHAR ScsiStatus, _In_opt_ PVOID SenseInfoBuffer, _In_ UCHAR SenseInfoBufferLength )/*++
Routine Description:
Helper function to set SCSI related fields from an extended SRB. If SRB is not a SRB_FUNCTION_EXECUTE_SCSI or not an extended SRB, no modifications will be made
Arguments:
SrbEx - Pointer to extended SRB.
CdbLength8 - CdbLength field value for SRBEX_DATA_SCSI_CDB16 or SRBEX_DATA_SCSI_CDB32
CdbLength32 - CdbLength field value for SRBEX_DATA_SCSI_CDB_VAR
ScsiStatus - ScsiStatus field value.
SenseInfoBuffer - SenseInfoBuffer value.
SenseInfoBufferLength - SenseInfoBufferLength value.
Return Value:
None
--*/{ ULONG i; PSRBEX_DATA SrbExData = NULL; BOOLEAN FoundEntry = FALSE;
if ((SrbEx->Function == SRB_FUNCTION_STORAGE_REQUEST_BLOCK) && (SrbEx->SrbFunction == SRB_FUNCTION_EXECUTE_SCSI)) { NT_ASSERT(SrbEx->NumSrbExData > 0);
for (i = 0; i < SrbEx->NumSrbExData; i++) {
// Skip any invalid offsets if ((SrbEx->SrbExDataOffset[i] < sizeof(STORAGE_REQUEST_BLOCK)) || (SrbEx->SrbExDataOffset[i] > SrbEx->SrbLength)){ // Catch any invalid offsets NT_ASSERT(FALSE); continue; }
SrbExData = (PSRBEX_DATA)((PUCHAR)SrbEx + SrbEx->SrbExDataOffset[i]);
switch (SrbExData->Type) {
case SrbExDataTypeScsiCdb16: if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB16) <= SrbEx->SrbLength) { FoundEntry = TRUE; ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->CdbLength = CdbLength8; ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->ScsiStatus = ScsiStatus; ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->SenseInfoBuffer = SenseInfoBuffer; ((PSRBEX_DATA_SCSI_CDB16) SrbExData)->SenseInfoBufferLength = SenseInfoBufferLength; } else { // Catch invalid offset NT_ASSERT(FALSE); } break;
case SrbExDataTypeScsiCdb32: if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB32) <= SrbEx->SrbLength) { FoundEntry = TRUE; ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->CdbLength = CdbLength8; ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->ScsiStatus = ScsiStatus; ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->SenseInfoBuffer = SenseInfoBuffer; ((PSRBEX_DATA_SCSI_CDB32) SrbExData)->SenseInfoBufferLength = SenseInfoBufferLength; } else { // Catch invalid offset NT_ASSERT(FALSE); } break;
case SrbExDataTypeScsiCdbVar: if (SrbEx->SrbExDataOffset[i] + sizeof(SRBEX_DATA_SCSI_CDB_VAR) <= SrbEx->SrbLength) { FoundEntry = TRUE; ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->CdbLength = CdbLength32; ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->ScsiStatus = ScsiStatus; ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->SenseInfoBuffer = SenseInfoBuffer; ((PSRBEX_DATA_SCSI_CDB_VAR) SrbExData)->SenseInfoBufferLength = SenseInfoBufferLength; } else { // Catch invalid offset NT_ASSERT(FALSE); } break; }
if (FoundEntry) { break; } }
}
return;}