ReactOS  0.4.14-dev-828-g8dc90a4
disk.c File Reference
#include <ntddk.h>
#include <ntdddisk.h>
#include <scsi.h>
#include <ntddscsi.h>
#include <mountdev.h>
#include <mountmgr.h>
#include <ntiologc.h>
#include <include/class2.h>
#include <stdio.h>
#include <debug.h>
Include dependency graph for disk.c:

Go to the source code of this file.

Classes

struct  _DISK_DATA
 
struct  _BAD_CONTROLLER_INFORMATION
 

Macros

#define NDEBUG
 
#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
 

Typedefs

typedef struct _DISK_DATA DISK_DATA
 
typedef struct _DISK_DATAPDISK_DATA
 
typedef struct _BAD_CONTROLLER_INFORMATION BAD_CONTROLLER_INFORMATION
 
typedef struct _BAD_CONTROLLER_INFORMATIONPBAD_CONTROLLER_INFORMATION
 

Enumerations

enum  PARTITION_LIST_STATE { NotInitialized, Initializing, Initialized }
 

Functions

NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 
BOOLEAN NTAPI ScsiDiskDeviceVerification (IN PINQUIRYDATA InquiryData)
 
BOOLEAN NTAPI FindScsiDisks (IN PDRIVER_OBJECT DriveObject, IN PUNICODE_STRING RegistryPath, IN PCLASS_INIT_DATA InitializationData, IN PDEVICE_OBJECT PortDeviceObject, IN ULONG PortNumber)
 
NTSTATUS NTAPI ScsiDiskCreateClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ScsiDiskReadWriteVerification (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI ScsiDiskDeviceControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI ScsiDiskProcessError (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
 
NTSTATUS NTAPI ScsiDiskShutdownFlush (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI DisableWriteCache (IN PDEVICE_OBJECT DeviceObject, IN PSCSI_INQUIRY_DATA LunInfo)
 
BOOLEAN NTAPI ScsiDiskModeSelect (IN PDEVICE_OBJECT DeviceObject, IN PCHAR ModeSelectBuffer, IN ULONG Length, IN BOOLEAN SavePage)
 
BOOLEAN NTAPI IsFloppyDevice (IN PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI CalculateMbrCheckSum (IN PDEVICE_EXTENSION DeviceExtension, OUT PULONG Checksum)
 
BOOLEAN NTAPI EnumerateBusKey (IN PDEVICE_EXTENSION DeviceExtension, HANDLE BusKey, PULONG DiskNumber)
 
VOID NTAPI UpdateGeometry (IN PDEVICE_EXTENSION DeviceExtension)
 
NTSTATUS NTAPI UpdateRemovableGeometry (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI 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)
 
NTSTATUS NTAPI CreatePartitionDeviceObjects (IN PDEVICE_OBJECT PhysicalDeviceObject, IN PUNICODE_STRING RegistryPath)
 
VOID NTAPI UpdateDeviceObjects (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI ScanForSpecial (PDEVICE_OBJECT DeviceObject, PSCSI_INQUIRY_DATA LunInfo, PIO_SCSI_CAPABILITIES PortCapabilities)
 
VOID NTAPI ResetScsiBus (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI ScsiDiskFileSystemControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
VOID NTAPI ReportToMountMgr (IN PDEVICE_OBJECT DiskDeviceObject)
 
NTSTATUS NTAPI ScsiDiskDeviceControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
BOOLEAN NTAPI IsFloppyDevice (PDEVICE_OBJECT DeviceObject)
 

Variables

BAD_CONTROLLER_INFORMATION const ScsiDiskBadControllers []
 

Macro Definition Documentation

◆ DEVICE_EXTENSION_SIZE

#define DEVICE_EXTENSION_SIZE   sizeof(DEVICE_EXTENSION) + sizeof(DISK_DATA)

Definition at line 162 of file disk.c.

◆ MODE_DATA_SIZE

#define MODE_DATA_SIZE   192

Definition at line 164 of file disk.c.

◆ NDEBUG

#define NDEBUG

Definition at line 19 of file disk.c.

◆ NUMBER_OF_BAD_CONTROLLERS

#define NUMBER_OF_BAD_CONTROLLERS   (sizeof(ScsiDiskBadControllers) / sizeof(BAD_CONTROLLER_INFORMATION))

Definition at line 161 of file disk.c.

◆ PARTITION0_LIST_SIZE

#define PARTITION0_LIST_SIZE   4

Definition at line 167 of file disk.c.

◆ SCSI_DISK_TIMEOUT

#define SCSI_DISK_TIMEOUT   10

Definition at line 166 of file disk.c.

◆ VALUE_BUFFER_SIZE

#define VALUE_BUFFER_SIZE   2048

Definition at line 165 of file disk.c.

Typedef Documentation

◆ BAD_CONTROLLER_INFORMATION

◆ DISK_DATA

◆ PBAD_CONTROLLER_INFORMATION

◆ PDISK_DATA

Enumeration Type Documentation

◆ PARTITION_LIST_STATE

Enumerator
NotInitialized 
Initializing 
Initialized 

Definition at line 30 of file disk.c.

30  {
PARTITION_LIST_STATE
Definition: disk.c:30

Function Documentation

◆ CalculateMbrCheckSum()

BOOLEAN NTAPI CalculateMbrCheckSum ( IN PDEVICE_EXTENSION  DeviceExtension,
OUT PULONG  Checksum 
)

Definition at line 3759 of file disk.c.

3780 {
3781  LARGE_INTEGER sectorZero;
3782  PIRP irp;
3783  IO_STATUS_BLOCK ioStatus;
3784  KEVENT event;
3785  NTSTATUS status;
3786  ULONG sectorSize;
3787  PULONG mbr;
3788  ULONG i;
3789 
3790  PAGED_CODE();
3791  sectorZero.QuadPart = (LONGLONG) 0;
3792 
3793  //
3794  // Create notification event object to be used to signal the inquiry
3795  // request completion.
3796  //
3797 
3799 
3800  //
3801  // Get sector size.
3802  //
3803 
3804  sectorSize = DeviceExtension->DiskGeometry->Geometry.BytesPerSector;
3805 
3806  //
3807  // Make sure sector size is at least 512 bytes.
3808  //
3809 
3810  if (sectorSize < 512) {
3811  sectorSize = 512;
3812  }
3813 
3814  //
3815  // Allocate buffer for sector read.
3816  //
3817 
3818  mbr = ExAllocatePool(NonPagedPoolCacheAligned, sectorSize);
3819 
3820  if (!mbr) {
3821  return FALSE;
3822  }
3823 
3824  //
3825  // Build IRP to read MBR.
3826  //
3827 
3829  DeviceExtension->DeviceObject,
3830  mbr,
3831  sectorSize,
3832  &sectorZero,
3833  &event,
3834  &ioStatus );
3835 
3836  if (!irp) {
3837  ExFreePool(mbr);
3838  return FALSE;
3839  }
3840 
3841  //
3842  // Pass request to port driver and wait for request to complete.
3843  //
3844 
3845  status = IoCallDriver(DeviceExtension->DeviceObject,
3846  irp);
3847 
3848  if (status == STATUS_PENDING) {
3850  Suspended,
3851  KernelMode,
3852  FALSE,
3853  NULL);
3854  status = ioStatus.Status;
3855  }
3856 
3857  if (!NT_SUCCESS(status)) {
3858  ExFreePool(mbr);
3859  return FALSE;
3860  }
3861 
3862  //
3863  // Calculate MBR checksum.
3864  //
3865 
3866  *Checksum = 0;
3867 
3868  for (i = 0; i < 128; i++) {
3869  *Checksum += mbr[i];
3870  }
3871 
3872  *Checksum = ~*Checksum + 1;
3873 
3874  ExFreePool(mbr);
3875  return TRUE;
3876 }
#define TRUE
Definition: types.h:120
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PAGED_CODE()
Definition: video.h:57
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
int64_t LONGLONG
Definition: typedefs.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
struct _cl_event * event
Definition: glext.h:7739
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MJ_READ
Definition: rdpdr.c:46
unsigned int ULONG
Definition: retypes.h:1
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
LONGLONG QuadPart
Definition: typedefs.h:112
Definition: ps.c:97

Referenced by CreatePartitionDeviceObjects().

◆ CreateDiskDeviceObject()

NTSTATUS NTAPI 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 
)

Definition at line 621 of file disk.c.

658 {
659  CCHAR ntNameBuffer[MAXIMUM_FILENAME_LENGTH];
660  STRING ntNameString;
661  UNICODE_STRING ntUnicodeString;
662  OBJECT_ATTRIBUTES objectAttributes;
663  HANDLE handle;
665  PDEVICE_OBJECT deviceObject = NULL;
666  //PDEVICE_OBJECT physicalDevice;
667  PDISK_GEOMETRY_EX diskGeometry = NULL;
668  PDEVICE_EXTENSION deviceExtension = NULL;
669  //PDEVICE_EXTENSION physicalDeviceExtension;
670  UCHAR pathId = LunInfo->PathId;
671  UCHAR targetId = LunInfo->TargetId;
672  UCHAR lun = LunInfo->Lun;
673  //BOOLEAN writeCache;
674  PVOID senseData = NULL;
675  //ULONG srbFlags;
676  ULONG timeOut = 0;
677  BOOLEAN srbListInitialized = FALSE;
678 
679 
680  PAGED_CODE();
681 
682  //
683  // Set up an object directory to contain the objects for this
684  // device and all its partitions.
685  //
686 
687  sprintf(ntNameBuffer,
688  "\\Device\\Harddisk%lu",
689  *DeviceCount);
690 
691  RtlInitString(&ntNameString,
692  ntNameBuffer);
693 
694  status = RtlAnsiStringToUnicodeString(&ntUnicodeString,
695  &ntNameString,
696  TRUE);
697 
698  if (!NT_SUCCESS(status)) {
699  return(status);
700  }
701 
702  InitializeObjectAttributes(&objectAttributes,
703  &ntUnicodeString,
705  NULL,
706  NULL);
707 
710  &objectAttributes);
711 
712  RtlFreeUnicodeString(&ntUnicodeString);
713 
714  if (!NT_SUCCESS(status)) {
715 
716  DebugPrint((1,
717  "CreateDiskDeviceObjects: Could not create directory %s\n",
718  ntNameBuffer));
719 
720  return(status);
721  }
722 
723  //
724  // Claim the device.
725  //
726 
727  status = ScsiClassClaimDevice(PortDeviceObject,
728  LunInfo,
729  FALSE,
730  &PortDeviceObject);
731 
732  if (!NT_SUCCESS(status)) {
734  ZwClose(handle);
735  return status;
736  }
737 
738  //
739  // Create a device object for this device. Each physical disk will
740  // have at least one device object. The required device object
741  // describes the entire device. Its directory path is
742  // \Device\HarddiskN\Partition0, where N = device number.
743  //
744 
745  sprintf(ntNameBuffer,
746  "\\Device\\Harddisk%lu\\Partition0",
747  *DeviceCount);
748 
749 
751  ntNameBuffer,
752  NULL,
753  &deviceObject,
754  InitData);
755 
756  if (!NT_SUCCESS(status)) {
757 
758  DebugPrint((1,
759  "CreateDiskDeviceObjects: Can not create device object %s\n",
760  ntNameBuffer));
761 
762  goto CreateDiskDeviceObjectsExit;
763  }
764 
765  //
766  // Indicate that IRPs should include MDLs for data transfers.
767  //
768 
769  deviceObject->Flags |= DO_DIRECT_IO;
770 
771  //
772  // Check if this is during initialization. If not indicate that
773  // system initialization already took place and this disk is ready
774  // to be accessed.
775  //
776 
777  if (!RegistryPath) {
778  deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
779  }
780 
781  //
782  // Check for removable media support.
783  //
784 
785  if (((PINQUIRYDATA)LunInfo->InquiryData)->RemovableMedia) {
786  deviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
787  }
788 
789  //
790  // Set up required stack size in device object.
791  //
792 
793  deviceObject->StackSize = (CCHAR)PortDeviceObject->StackSize + 1;
794 
795  deviceExtension = deviceObject->DeviceExtension;
796 
797  //
798  // Allocate spinlock for split request completion.
799  //
800 
801  KeInitializeSpinLock(&deviceExtension->SplitRequestSpinLock);
802 
803  //
804  // Initialize lock count to zero. The lock count is used to
805  // disable the ejection mechanism on devices that support
806  // removable media. Only the lock count in the physical
807  // device extension is used.
808  //
809 
810  deviceExtension->LockCount = 0;
811 
812  //
813  // Save system disk number.
814  //
815 
816  deviceExtension->DeviceNumber = *DeviceCount;
817 
818  //
819  // Copy port device object pointer to the device extension.
820  //
821 
822  deviceExtension->PortDeviceObject = PortDeviceObject;
823 
824  //
825  // Set the alignment requirements for the device based on the
826  // host adapter requirements
827  //
828 
829  if (PortDeviceObject->AlignmentRequirement > deviceObject->AlignmentRequirement) {
830  deviceObject->AlignmentRequirement = PortDeviceObject->AlignmentRequirement;
831  }
832 
833  //
834  // This is the physical device object.
835  //
836 
837  //physicalDevice = deviceObject;
838  //physicalDeviceExtension = deviceExtension;
839 
840  //
841  // Save address of port driver capabilities.
842  //
843 
844  deviceExtension->PortCapabilities = PortCapabilities;
845 
846  //
847  // Build the lookaside list for srb's for the physical disk. Should only
848  // need a couple.
849  //
850 
851  ScsiClassInitializeSrbLookasideList(deviceExtension,
853 
854  srbListInitialized = TRUE;
855 
856  //
857  // Initialize the srb flags.
858  //
859 
860  if (((PINQUIRYDATA)LunInfo->InquiryData)->CommandQueue &&
861  PortCapabilities->TaggedQueuing) {
862 
863  deviceExtension->SrbFlags = SRB_FLAGS_QUEUE_ACTION_ENABLE;
864 
865  } else {
866 
867  deviceExtension->SrbFlags = 0;
868 
869  }
870 
871  //
872  // Allow queued requests if this is not removable media.
873  //
874 
875  if (!(deviceObject->Characteristics & FILE_REMOVABLE_MEDIA)) {
876 
877  deviceExtension->SrbFlags |= SRB_FLAGS_NO_QUEUE_FREEZE;
878 
879  }
880 
881  //
882  // Look for controller that require special flags.
883  //
884 
885  ScanForSpecial(deviceObject,
886  LunInfo,
887  PortCapabilities);
888 
889  //srbFlags = deviceExtension->SrbFlags;
890 
891  //
892  // Allocate buffer for drive geometry.
893  //
894 
895  diskGeometry = ExAllocatePool(NonPagedPool, sizeof(DISK_GEOMETRY_EX));
896 
897  if (diskGeometry == NULL) {
898 
899  DebugPrint((1,
900  "CreateDiskDeviceObjects: Can not allocate disk geometry buffer\n"));
902  goto CreateDiskDeviceObjectsExit;
903  }
904 
905  deviceExtension->DiskGeometry = diskGeometry;
906 
907  //
908  // Allocate request sense buffer.
909  //
910 
912 
913  if (senseData == NULL) {
914 
915  //
916  // The buffer can not be allocated.
917  //
918 
919  DebugPrint((1,
920  "CreateDiskDeviceObjects: Can not allocate request sense buffer\n"));
921 
923  goto CreateDiskDeviceObjectsExit;
924  }
925 
926  //
927  // Set the sense data pointer in the device extension.
928  //
929 
930  deviceExtension->SenseData = senseData;
931 
932  //
933  // Physical device object will describe the entire
934  // device, starting at byte offset 0.
935  //
936 
937  deviceExtension->StartingOffset.QuadPart = (LONGLONG)(0);
938 
939  //
940  // TargetId/LUN describes a device location on the SCSI bus.
941  // This information comes from the inquiry buffer.
942  //
943 
944  deviceExtension->PortNumber = (UCHAR)PortNumber;
945  deviceExtension->PathId = pathId;
946  deviceExtension->TargetId = targetId;
947  deviceExtension->Lun = lun;
948 
949  //
950  // Set timeout value in seconds.
951  //
952 
954  if (timeOut) {
955  deviceExtension->TimeOutValue = timeOut;
956  } else {
957  deviceExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
958  }
959 
960  //
961  // Back pointer to device object.
962  //
963 
964  deviceExtension->DeviceObject = deviceObject;
965 
966  //
967  // If this is a removable device, then make sure it is not a floppy.
968  // Perform a mode sense command to determine the media type. Note
969  // IsFloppyDevice also checks for write cache enabled.
970  //
971 
972 #if 0
973  if (IsFloppyDevice(deviceObject) && deviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
974  (((PINQUIRYDATA)LunInfo->InquiryData)->DeviceType == DIRECT_ACCESS_DEVICE)) {
975 
977  goto CreateDiskDeviceObjectsExit;
978  }
979 #endif
980 
981  DisableWriteCache(deviceObject,LunInfo);
982 
983  //writeCache = deviceExtension->DeviceFlags & DEV_WRITE_CACHE;
984 
985  //
986  // NOTE: At this point one device object has been successfully created.
987  // from here on out return success.
988  //
989 
990  //
991  // Do READ CAPACITY. This SCSI command
992  // returns the number of bytes on a device.
993  // Device extension is updated with device size.
994  //
995 
996  status = ScsiClassReadDriveCapacity(deviceObject);
997 
998  //
999  // If the read capacity failed then just return, unless this is a
1000  // removable disk where a device object partition needs to be created.
1001  //
1002 
1003  if (!NT_SUCCESS(status) &&
1004  !(deviceObject->Characteristics & FILE_REMOVABLE_MEDIA)) {
1005 
1006  DebugPrint((1,
1007  "CreateDiskDeviceObjects: Can't read capacity for device %s\n",
1008  ntNameBuffer));
1009 
1010  return(STATUS_SUCCESS);
1011 
1012  } else {
1013 
1014  //
1015  // Make sure the volume verification bit is off so that
1016  // IoReadPartitionTable will work.
1017  //
1018 
1019  deviceObject->Flags &= ~DO_VERIFY_VOLUME;
1020  }
1021 
1023 
1024  if (NT_SUCCESS(status))
1025  return STATUS_SUCCESS;
1026 
1027 
1028 CreateDiskDeviceObjectsExit:
1029 
1030  //
1031  // Release the device since an error occurred.
1032  //
1033 
1034  ScsiClassClaimDevice(PortDeviceObject,
1035  LunInfo,
1036  TRUE,
1037  NULL);
1038 
1039  if (diskGeometry != NULL) {
1040  ExFreePool(diskGeometry);
1041  }
1042 
1043  if (senseData != NULL) {
1044  ExFreePool(senseData);
1045  }
1046 
1047  if (deviceObject != NULL) {
1048 
1049  if (srbListInitialized) {
1050  ExDeleteNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
1051  }
1052 
1053  IoDeleteDevice(deviceObject);
1054  }
1055 
1056  //
1057  // Delete directory and return.
1058  //
1059 
1060  if (!NT_SUCCESS(status)) {
1062  }
1063 
1064  ZwClose(handle);
1065 
1066  return(status);
1067 
1068 } // end CreateDiskDeviceObjects()
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
NTSTATUS NTAPI CreatePartitionDeviceObjects(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PUNICODE_STRING RegistryPath)
Definition: disk.c:1196
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
VOID NTAPI ScsiClassInitializeSrbLookasideList(IN PDEVICE_EXTENSION DeviceExtension, IN ULONG NumberElements)
Definition: class2.c:4778
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI IsFloppyDevice(IN PDEVICE_OBJECT DeviceObject)
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define OBJ_PERMANENT
Definition: winternl.h:226
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
#define PAGED_CODE()
Definition: video.h:57
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define sprintf(buf, format,...)
Definition: sprintf.c:55
VOID NTAPI ScanForSpecial(PDEVICE_OBJECT DeviceObject, PSCSI_INQUIRY_DATA LunInfo, PIO_SCSI_CAPABILITIES PortCapabilities)
Definition: disk.c:4770
ULONG DeviceCount
Definition: mpu401.c:26
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSTATUS ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:714
ULONG PortNumber
Definition: storport.c:18
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define SCSI_DISK_TIMEOUT
Definition: disk.c:166
NTSTATUS NTAPI ScsiClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, IN PCCHAR ObjectNameBuffer, IN OPTIONAL PDEVICE_OBJECT PhysicalDeviceObject, IN OUT PDEVICE_OBJECT *DeviceObject, IN PCLASS_INIT_DATA InitializationData)
Definition: class2.c:4364
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
int64_t LONGLONG
Definition: typedefs.h:66
VOID NTAPI DisableWriteCache(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_INQUIRY_DATA LunInfo)
Definition: disk.c:3552
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
char CCHAR
Definition: typedefs.h:50
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
std::wstring STRING
Definition: fontsub.cpp:33
unsigned char UCHAR
Definition: xmlstorage.h:181
#define PARTITION0_LIST_SIZE
Definition: disk.c:167
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS ScsiClassClaimDevice(IN PDEVICE_OBJECT PortDeviceObject, IN PSCSI_INQUIRY_DATA LunInfo, IN BOOLEAN Release, OUT PDEVICE_OBJECT *NewPortDeviceObject OPTIONAL)
Definition: class2.c:4488
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
return STATUS_SUCCESS
Definition: btrfs.c:2938
VOID NTAPI ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside)
Definition: lookas.c:174
static SERVICE_STATUS status
Definition: service.c:31
NTSYSAPI NTSTATUS NTAPI ZwMakeTemporaryObject(_In_ HANDLE Handle)
ULONG NTAPI ScsiClassQueryTimeOutRegistryValue(IN PUNICODE_STRING RegistryPath)
Definition: class2.c:4816
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:387
Definition: ps.c:97

Referenced by FindScsiDisks().

◆ CreatePartitionDeviceObjects()

NTSTATUS NTAPI CreatePartitionDeviceObjects ( IN PDEVICE_OBJECT  PhysicalDeviceObject,
IN PUNICODE_STRING  RegistryPath 
)

Definition at line 1196 of file disk.c.

1200 {
1201  CCHAR ntNameBuffer[MAXIMUM_FILENAME_LENGTH];
1202  ULONG partitionNumber = 0;
1203  NTSTATUS status;
1204  PDEVICE_OBJECT deviceObject = NULL;
1205  PDISK_GEOMETRY_EX diskGeometry = NULL;
1206  PDRIVE_LAYOUT_INFORMATION partitionList = NULL;
1207  PDEVICE_EXTENSION deviceExtension;
1208  PDEVICE_EXTENSION physicalDeviceExtension;
1209  PCLASS_INIT_DATA initData = NULL;
1210  PDISK_DATA diskData;
1211  PDISK_DATA physicalDiskData;
1212  ULONG bytesPerSector;
1213  UCHAR sectorShift;
1214  ULONG srbFlags;
1215  ULONG dmByteSkew = 0;
1216  PULONG dmSkew;
1217  BOOLEAN dmActive = FALSE;
1218  ULONG numberListElements = 0;
1219 
1220 
1221  //
1222  // Get physical device geometry information for partition table reads.
1223  //
1224 
1225  physicalDeviceExtension = PhysicalDeviceObject->DeviceExtension;
1226  diskGeometry = physicalDeviceExtension->DiskGeometry;
1227  bytesPerSector = diskGeometry->Geometry.BytesPerSector;
1228 
1229  //
1230  // Make sure sector size is not zero.
1231  //
1232 
1233  if (bytesPerSector == 0) {
1234 
1235  //
1236  // Default sector size for disk is 512.
1237  //
1238 
1239  bytesPerSector = diskGeometry->Geometry.BytesPerSector = 512;
1240  }
1241 
1242  sectorShift = physicalDeviceExtension->SectorShift;
1243 
1244  //
1245  // Set pointer to disk data area that follows device extension.
1246  //
1247 
1248  diskData = (PDISK_DATA)(physicalDeviceExtension + 1);
1249  diskData->PartitionListState = Initializing;
1250 
1251  //
1252  // Determine is DM Driver is loaded on an IDE drive that is
1253  // under control of Atapi - this could be either a crashdump or
1254  // an Atapi device is sharing the controller with an IDE disk.
1255  //
1256 
1258  physicalDeviceExtension->DiskGeometry->Geometry.BytesPerSector,
1259  (ULONG)0x54,
1260  (PVOID)&dmSkew);
1261 
1262  if (dmSkew) {
1263 
1264  //
1265  // Update the device extension, so that the call to IoReadPartitionTable
1266  // will get the correct information. Any I/O to this disk will have
1267  // to be skewed by *dmSkew sectors aka DMByteSkew.
1268  //
1269 
1270  physicalDeviceExtension->DMSkew = *dmSkew;
1271  physicalDeviceExtension->DMActive = TRUE;
1272  physicalDeviceExtension->DMByteSkew = physicalDeviceExtension->DMSkew * bytesPerSector;
1273 
1274  //
1275  // Save away the information that we need, since this deviceExtension will soon be
1276  // blown away.
1277  //
1278 
1279  dmActive = TRUE;
1280  dmByteSkew = physicalDeviceExtension->DMByteSkew;
1281 
1282  }
1283 
1284 #ifdef __REACTOS__
1285  //
1286  // HACK so that we can use NT5+ NTOS functions with this NT4 driver
1287  // for removable devices and avoid an infinite recursive loop between
1288  // disk!UpdateRemovableGeometry() and ntos!IoReadPartitionTable().
1289  //
1290  diskData->UpdateRemovableGeometryCount = 0;
1291 #endif
1292 
1293  //
1294  // Create objects for all the partitions on the device.
1295  //
1296 
1298  physicalDeviceExtension->DiskGeometry->Geometry.BytesPerSector,
1299  TRUE,
1300  (PVOID)&partitionList);
1301 
1302  //
1303  // If the I/O read partition table failed and this is a removable device,
1304  // then fix up the partition list to make it look like there is one
1305  // zero length partition.
1306  //
1307  DPRINT("IoReadPartitionTable() status: 0x%08X\n", status);
1308  if ((!NT_SUCCESS(status) || partitionList->PartitionCount == 0) &&
1309  PhysicalDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1310 
1311  if (!NT_SUCCESS(status)) {
1312 
1313  //
1314  // Remember this disk is not ready.
1315  //
1316 
1317  diskData->DriveNotReady = TRUE;
1318 
1319  } else {
1320 
1321  //
1322  // Free the partition list allocated by IoReadPartitionTable.
1323  //
1324 
1325  ExFreePool(partitionList);
1326  }
1327 
1328  //
1329  // Allocate and zero a partition list.
1330  //
1331 
1332  partitionList = ExAllocatePool(NonPagedPool, sizeof(*partitionList));
1333 
1334 
1335  if (partitionList != NULL) {
1336 
1337  RtlZeroMemory( partitionList, sizeof( *partitionList ));
1338 
1339  //
1340  // Set the partition count to one and the status to success
1341  // so one device object will be created. Set the partition type
1342  // to a bogus value.
1343  //
1344 
1345  partitionList->PartitionCount = 1;
1346 
1348  }
1349  }
1350 
1351  if (NT_SUCCESS(status)) {
1352 
1353  //
1354  // Record disk signature.
1355  //
1356 
1357  diskData->Signature = partitionList->Signature;
1358 
1359  //
1360  // If disk signature is zero, then calculate the MBR checksum.
1361  //
1362 
1363  if (!diskData->Signature) {
1364 
1365  if (!CalculateMbrCheckSum(physicalDeviceExtension,
1366  &diskData->MbrCheckSum)) {
1367 
1368  DebugPrint((1,
1369  "SCSIDISK: Can't calculate MBR checksum for disk %x\n",
1370  physicalDeviceExtension->DeviceNumber));
1371  } else {
1372 
1373  DebugPrint((2,
1374  "SCSIDISK: MBR checksum for disk %x is %x\n",
1375  physicalDeviceExtension->DeviceNumber,
1376  diskData->MbrCheckSum));
1377  }
1378  }
1379 
1380  //
1381  // Check the registry and determine if the BIOS knew about this drive. If
1382  // it did then update the geometry with the BIOS information.
1383  //
1384 
1385  UpdateGeometry(physicalDeviceExtension);
1386 
1387  srbFlags = physicalDeviceExtension->SrbFlags;
1388 
1389  initData = ExAllocatePool(NonPagedPool, sizeof(CLASS_INIT_DATA));
1390  if (!initData)
1391  {
1392  DebugPrint((1,
1393  "Disk.CreatePartitionDeviceObjects - Allocation of initData failed\n"));
1394 
1396  goto CreatePartitionDeviceObjectsExit;
1397  }
1398 
1399  RtlZeroMemory(initData, sizeof(CLASS_INIT_DATA));
1400 
1401  initData->InitializationDataSize = sizeof(CLASS_INIT_DATA);
1403  initData->DeviceType = FILE_DEVICE_DISK;
1404  initData->DeviceCharacteristics = PhysicalDeviceObject->Characteristics;
1405  initData->ClassError = physicalDeviceExtension->ClassError;
1406  initData->ClassReadWriteVerification = physicalDeviceExtension->ClassReadWriteVerification;
1407  initData->ClassFindDevices = physicalDeviceExtension->ClassFindDevices;
1408  initData->ClassDeviceControl = physicalDeviceExtension->ClassDeviceControl;
1409  initData->ClassShutdownFlush = physicalDeviceExtension->ClassShutdownFlush;
1410  initData->ClassCreateClose = physicalDeviceExtension->ClassCreateClose;
1411  initData->ClassStartIo = physicalDeviceExtension->ClassStartIo;
1412 
1413  //
1414  // Create device objects for the device partitions (if any).
1415  // PartitionCount includes physical device partition 0,
1416  // so only one partition means no objects to create.
1417  //
1418 
1419  DebugPrint((2,
1420  "CreateDiskDeviceObjects: Number of partitions is %d\n",
1421  partitionList->PartitionCount));
1422 
1423  for (partitionNumber = 0; partitionNumber <
1424  partitionList->PartitionCount; partitionNumber++) {
1425 
1426  //
1427  // Create partition object and set up partition parameters.
1428  //
1429 
1430  sprintf(ntNameBuffer,
1431  "\\Device\\Harddisk%lu\\Partition%lu",
1432  physicalDeviceExtension->DeviceNumber,
1433  partitionNumber + 1);
1434 
1435  DebugPrint((2,
1436  "CreateDiskDeviceObjects: Create device object %s\n",
1437  ntNameBuffer));
1438 
1440  ntNameBuffer,
1442  &deviceObject,
1443  initData);
1444 
1445  if (!NT_SUCCESS(status)) {
1446 
1447  DebugPrint((1, "CreateDiskDeviceObjects: Can't create device object for %s\n", ntNameBuffer));
1448 
1449  break;
1450  }
1451 
1452  //
1453  // Set up device object fields.
1454  //
1455 
1456  deviceObject->Flags |= DO_DIRECT_IO;
1457 
1458  //
1459  // Check if this is during initialization. If not indicate that
1460  // system initialization already took place and this disk is ready
1461  // to be accessed.
1462  //
1463 
1464  if (!RegistryPath) {
1465  deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1466  }
1467 
1468  deviceObject->StackSize = (CCHAR)physicalDeviceExtension->PortDeviceObject->StackSize + 1;
1469 
1470  //
1471  // Set up device extension fields.
1472  //
1473 
1474  deviceExtension = deviceObject->DeviceExtension;
1475 
1476  if (dmActive) {
1477 
1478  //
1479  // Restore any saved DM values.
1480  //
1481 
1482  deviceExtension->DMByteSkew = dmByteSkew;
1483  deviceExtension->DMSkew = *dmSkew;
1484  deviceExtension->DMActive = TRUE;
1485 
1486  }
1487 
1488  //
1489  // Link new device extension to previous disk data
1490  // to support dynamic partitioning.
1491  //
1492 
1493  diskData->NextPartition = deviceExtension;
1494 
1495  //
1496  // Get pointer to new disk data.
1497  //
1498 
1499  diskData = (PDISK_DATA)(deviceExtension + 1);
1500 
1501  //
1502  // Set next partition pointer to NULL in case this is the
1503  // last partition.
1504  //
1505 
1506  diskData->NextPartition = NULL;
1507 
1508  //
1509  // Allocate spinlock for zoning for split-request completion.
1510  //
1511 
1512  KeInitializeSpinLock(&deviceExtension->SplitRequestSpinLock);
1513 
1514  //
1515  // Copy port device object pointer to device extension.
1516  //
1517 
1518  deviceExtension->PortDeviceObject = physicalDeviceExtension->PortDeviceObject;
1519 
1520  //
1521  // Set the alignment requirements for the device based on the
1522  // host adapter requirements
1523  //
1524 
1525  if (physicalDeviceExtension->PortDeviceObject->AlignmentRequirement > deviceObject->AlignmentRequirement) {
1526  deviceObject->AlignmentRequirement = physicalDeviceExtension->PortDeviceObject->AlignmentRequirement;
1527  }
1528 
1529 
1530  if (srbFlags & SRB_FLAGS_QUEUE_ACTION_ENABLE) {
1531  numberListElements = 30;
1532  } else {
1533  numberListElements = 8;
1534  }
1535 
1536  //
1537  // Build the lookaside list for srb's for this partition based on
1538  // whether the adapter and disk can do tagged queueing.
1539  //
1540 
1541  ScsiClassInitializeSrbLookasideList(deviceExtension,
1542  numberListElements);
1543 
1544  deviceExtension->SrbFlags = srbFlags;
1545 
1546  //
1547  // Set the sense-data pointer in the device extension.
1548  //
1549 
1550  deviceExtension->SenseData = physicalDeviceExtension->SenseData;
1551  deviceExtension->PortCapabilities = physicalDeviceExtension->PortCapabilities;
1552  deviceExtension->DiskGeometry = diskGeometry;
1553  diskData->PartitionOrdinal = diskData->PartitionNumber = partitionNumber + 1;
1554  diskData->PartitionType = partitionList->PartitionEntry[partitionNumber].PartitionType;
1555  diskData->BootIndicator = partitionList->PartitionEntry[partitionNumber].BootIndicator;
1556 
1557  DebugPrint((2, "CreateDiskDeviceObjects: Partition type is %x\n",
1558  diskData->PartitionType));
1559 
1560  deviceExtension->StartingOffset = partitionList->PartitionEntry[partitionNumber].StartingOffset;
1561  deviceExtension->PartitionLength = partitionList->PartitionEntry[partitionNumber].PartitionLength;
1562  diskData->HiddenSectors = partitionList->PartitionEntry[partitionNumber].HiddenSectors;
1563  deviceExtension->PortNumber = physicalDeviceExtension->PortNumber;
1564  deviceExtension->PathId = physicalDeviceExtension->PathId;
1565  deviceExtension->TargetId = physicalDeviceExtension->TargetId;
1566  deviceExtension->Lun = physicalDeviceExtension->Lun;
1567 
1568  //
1569  // Check for removable media support.
1570  //
1571 
1572  if (PhysicalDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1573  deviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
1574  }
1575 
1576  //
1577  // Set timeout value in seconds.
1578  //
1579 
1580  deviceExtension->TimeOutValue = physicalDeviceExtension->TimeOutValue;
1581  deviceExtension->DiskGeometry->Geometry.BytesPerSector = bytesPerSector;
1582  deviceExtension->SectorShift = sectorShift;
1583  deviceExtension->DeviceObject = deviceObject;
1584  deviceExtension->DeviceFlags |= physicalDeviceExtension->DeviceFlags;
1585 
1586  //
1587  // Now we're done, report to the MountMgr.
1588  // This is a HACK required to have the driver
1589  // handle the associated DosDevices.
1590  //
1591 
1592  ReportToMountMgr(deviceObject);
1593 
1594  } // end for (partitionNumber) ...
1595 
1596  //
1597  // Free the buffer allocated by reading the
1598  // partition table.
1599  //
1600 
1601  ExFreePool(partitionList);
1602 
1603  if (dmSkew) {
1604  ExFreePool(dmSkew);
1605  }
1606 
1607  } else {
1608 
1609 CreatePartitionDeviceObjectsExit:
1610 
1611  if (partitionList) {
1612  ExFreePool(partitionList);
1613  }
1614  if (initData) {
1615  ExFreePool(initData);
1616  }
1617 
1618  if (dmSkew) {
1619  ExFreePool(dmSkew);
1620  }
1621 
1622  return status;
1623 
1624  } // end if...else
1625 
1626 
1627  physicalDiskData = (PDISK_DATA)(physicalDeviceExtension + 1);
1628  physicalDiskData->PartitionListState = Initialized;
1629 
1630  return(STATUS_SUCCESS);
1631 
1632 
1633 } // end CreatePartitionDeviceObjects()
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
struct _DISK_DATA * PDISK_DATA
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
VOID NTAPI ReportToMountMgr(IN PDEVICE_OBJECT DiskDeviceObject)
Definition: disk.c:1073
DEVICE_TYPE DeviceType
Definition: class2.h:84
#define TRUE
Definition: types.h:120
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:399
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PDRIVER_STARTIO ClassStartIo
Definition: class2.h:93
BOOLEAN BootIndicator
Definition: disk.c:104
PCLASS_FIND_DEVICES ClassFindDevices
Definition: class2.h:89
VOID NTAPI ScsiClassInitializeSrbLookasideList(IN PDEVICE_EXTENSION DeviceExtension, IN ULONG NumberElements)
Definition: class2.c:4778
LONG NTSTATUS
Definition: precomp.h:26
ULONG HiddenSectors
Definition: disk.c:64
ULONG BytesPerSector
Definition: ntdddisk.h:381
VOID NTAPI UpdateGeometry(IN PDEVICE_EXTENSION DeviceExtension)
Definition: disk.c:4209
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
PCLASS_READ_WRITE ClassReadWriteVerification
Definition: class2.h:87
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define DEVICE_EXTENSION_SIZE
Definition: disk.c:162
ULONG PartitionOrdinal
Definition: disk.c:79
PDEVICE_EXTENSION NextPartition
Definition: disk.c:46
#define sprintf(buf, format,...)
Definition: sprintf.c:55
ULONG PartitionNumber
Definition: disk.c:73
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
DISK_GEOMETRY Geometry
Definition: ntdddisk.h:385
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:476
ULONG DeviceExtensionSize
Definition: class2.h:83
UCHAR PartitionType
Definition: disk.c:94
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS NTAPI ScsiClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, IN PCCHAR ObjectNameBuffer, IN OPTIONAL PDEVICE_OBJECT PhysicalDeviceObject, IN OUT PDEVICE_OBJECT *DeviceObject, IN PCLASS_INIT_DATA InitializationData)
Definition: class2.c:4364
BOOLEAN DriveNotReady
Definition: disk.c:111
ULONG Signature
Definition: disk.c:52
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:398
char CCHAR
Definition: typedefs.h:50
PCLASS_CREATE_CLOSE ClassCreateClose
Definition: class2.h:92
unsigned char UCHAR
Definition: xmlstorage.h:181
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
ULONG DeviceCharacteristics
Definition: class2.h:85
ULONG InitializationDataSize
Definition: class2.h:82
BOOLEAN NTAPI CalculateMbrCheckSum(IN PDEVICE_EXTENSION DeviceExtension, OUT PULONG Checksum)
Definition: disk.c:3759
PCLASS_DEVICE_CONTROL ClassDeviceControl
Definition: class2.h:90
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
NTSTATUS FASTCALL IoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN BOOLEAN ReturnRecognizedPartitions, OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
Definition: partition.c:495
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
PARTITION_LIST_STATE PartitionListState
Definition: disk.c:117
unsigned int * PULONG
Definition: retypes.h:1
struct _CLASS_INIT_DATA CLASS_INIT_DATA
PCLASS_SHUTDOWN_FLUSH ClassShutdownFlush
Definition: class2.h:91
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
VOID FASTCALL HalExamineMBR(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG MbrTypeIdentifier, OUT PVOID *MbrBuffer)
Definition: disksup.c:2726
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
ULONG MbrCheckSum
Definition: disk.c:58
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
PCLASS_ERROR ClassError
Definition: class2.h:86
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:387
Definition: ps.c:97

Referenced by CreateDiskDeviceObject(), and ScsiDiskDeviceControl().

◆ DisableWriteCache()

VOID NTAPI DisableWriteCache ( IN PDEVICE_OBJECT  DeviceObject,
IN PSCSI_INQUIRY_DATA  LunInfo 
)

Definition at line 3552 of file disk.c.

3557 {
3558  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3559  PINQUIRYDATA InquiryData = (PINQUIRYDATA)LunInfo->InquiryData;
3560  BAD_CONTROLLER_INFORMATION const *controller;
3561  ULONG j,length;
3562  PVOID modeData;
3563  PUCHAR pageData;
3564 
3565  for (j = 0; j < NUMBER_OF_BAD_CONTROLLERS; j++) {
3566 
3567  controller = &ScsiDiskBadControllers[j];
3568 
3569  if (!controller->DisableWriteCache || strncmp(controller->InquiryString, (PCCHAR)InquiryData->VendorId, strlen(controller->InquiryString))) {
3570  continue;
3571  }
3572 
3573  DebugPrint((1, "ScsiDisk.DisableWriteCache, Found bad controller! %s\n", controller->InquiryString));
3574 
3576 
3577  if (modeData == NULL) {
3578 
3579  DebugPrint((1,
3580  "ScsiDisk.DisableWriteCache: Check for write-cache enable failed\n"));
3581  return;
3582  }
3583 
3584  RtlZeroMemory(modeData, MODE_DATA_SIZE);
3585 
3587  modeData,
3590 
3591  if (length < sizeof(MODE_PARAMETER_HEADER)) {
3592 
3593  //
3594  // Retry the request in case of a check condition.
3595  //
3596 
3598  modeData,
3601 
3602  if (length < sizeof(MODE_PARAMETER_HEADER)) {
3603 
3604 
3605  DebugPrint((1,
3606  "ScsiDisk.DisableWriteCache: Mode Sense failed\n"));
3607 
3608  ExFreePool(modeData);
3609  return;
3610 
3611  }
3612  }
3613 
3614  //
3615  // If the length is greater than length indicated by the mode data reset
3616  // the data to the mode data.
3617  //
3618 
3619  if (length > (ULONG) ((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1) {
3620  length = ((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1;
3621  }
3622 
3623  //
3624  // Check to see if the write cache is enabled.
3625  //
3626 
3627  pageData = ScsiClassFindModePage( modeData, length, MODE_PAGE_CACHING, TRUE);
3628 
3629  //
3630  // Assume that write cache is disabled or not supported.
3631  //
3632 
3633  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
3634 
3635  //
3636  // Check if valid caching page exists.
3637  //
3638 
3639  if (pageData != NULL) {
3640 
3641  BOOLEAN savePage = FALSE;
3642 
3643  savePage = (BOOLEAN)(((PMODE_CACHING_PAGE)pageData)->PageSavable);
3644 
3645  //
3646  // Check if write cache is disabled.
3647  //
3648 
3649  if (((PMODE_CACHING_PAGE)pageData)->WriteCacheEnable) {
3650 
3651  PIO_ERROR_LOG_PACKET errorLogEntry;
3652  LONG errorCode;
3653 
3654 
3655  //
3656  // Disable write cache and ensure necessary fields are zeroed.
3657  //
3658 
3659  ((PMODE_CACHING_PAGE)pageData)->WriteCacheEnable = FALSE;
3660  ((PMODE_CACHING_PAGE)pageData)->Reserved = 0;
3661  ((PMODE_CACHING_PAGE)pageData)->PageSavable = 0;
3662  ((PMODE_CACHING_PAGE)pageData)->Reserved2 = 0;
3663 
3664  //
3665  // Extract length from caching page.
3666  //
3667 
3668  length = ((PMODE_CACHING_PAGE)pageData)->PageLength;
3669 
3670  //
3671  // Compensate for page code and page length.
3672  //
3673 
3674  length += 2;
3675 
3676  //
3677  // Issue mode select to set the parameter.
3678  //
3679 
3681  (PCHAR)pageData,
3682  length,
3683  savePage)) {
3684 
3685  DebugPrint((1,
3686  "SCSIDISK: Disk write cache disabled\n"));
3687 
3688  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
3689  errorCode = IO_WRITE_CACHE_DISABLED;
3690 
3691  } else {
3693  (PCHAR)pageData,
3694  length,
3695  savePage)) {
3696 
3697  DebugPrint((1,
3698  "SCSIDISK: Disk write cache disabled\n"));
3699 
3700 
3701  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
3702  errorCode = IO_WRITE_CACHE_DISABLED;
3703 
3704  } else {
3705 
3706  DebugPrint((1,
3707  "SCSIDISK: Mode select to disable write cache failed\n"));
3708 
3709  deviceExtension->DeviceFlags |= DEV_WRITE_CACHE;
3710  errorCode = IO_WRITE_CACHE_ENABLED;
3711  }
3712  }
3713 
3714  //
3715  // Log the appropriate informational or error entry.
3716  //
3717 
3719  DeviceObject,
3720  sizeof(IO_ERROR_LOG_PACKET) + 3
3721  * sizeof(ULONG));
3722 
3723  if (errorLogEntry != NULL) {
3724 
3725  errorLogEntry->FinalStatus = STATUS_SUCCESS;
3726  errorLogEntry->ErrorCode = errorCode;
3727  errorLogEntry->SequenceNumber = 0;
3728  errorLogEntry->MajorFunctionCode = IRP_MJ_SCSI;
3729  errorLogEntry->IoControlCode = 0;
3730  errorLogEntry->RetryCount = 0;
3731  errorLogEntry->UniqueErrorValue = 0x1;
3732  errorLogEntry->DumpDataSize = 3 * sizeof(ULONG);
3733  errorLogEntry->DumpData[0] = LunInfo->PathId;
3734  errorLogEntry->DumpData[1] = LunInfo->TargetId;
3735  errorLogEntry->DumpData[2] = LunInfo->Lun;
3736 
3737  //
3738  // Write the error log packet.
3739  //
3740 
3741  IoWriteErrorLogEntry(errorLogEntry);
3742  }
3743  }
3744  }
3745 
3746  //
3747  // Found device so exit the loop and return.
3748  //
3749 
3750  break;
3751  }
3752 
3753  return;
3754 }
signed char * PCHAR
Definition: retypes.h:7
#define IO_WRITE_CACHE_ENABLED
Definition: ntiologc.h:59
#define TRUE
Definition: types.h:120
#define IO_WRITE_CACHE_DISABLED
Definition: ntiologc.h:61
#define MODE_PAGE_CACHING
Definition: cdrw_hw.h:846
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
NTSTATUS FinalStatus
Definition: iotypes.h:1966
unsigned char * PUCHAR
Definition: retypes.h:3
#define MODE_SENSE_RETURN_ALL
Definition: cdrw_hw.h:857
struct _INQUIRYDATA * PINQUIRYDATA
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
BOOLEAN NTAPI ScsiDiskModeSelect(IN PDEVICE_OBJECT DeviceObject, IN PCHAR ModeSelectBuffer, IN ULONG Length, IN BOOLEAN SavePage)
Definition: disk.c:3416
VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:620
#define DEV_WRITE_CACHE
Definition: class2.h:21
#define IRP_MJ_SCSI
NTSTATUS ErrorCode
Definition: iotypes.h:1964
#define MODE_DATA_SIZE
Definition: disk.c:164
long LONG
Definition: pedump.c:60
PVOID NTAPI ScsiClassFindModePage(IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode, IN BOOLEAN Use6Byte)
Definition: class2.c:3295
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:520
ULONG NTAPI ScsiClassModeSense(IN PDEVICE_OBJECT DeviceObject, IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode)
Definition: class2.c:3198
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define for
Definition: utility.h:88
#define NUMBER_OF_BAD_CONTROLLERS
Definition: disk.c:161
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
struct _IO_ERROR_LOG_PACKET * PIO_ERROR_LOG_PACKET
#define BOOLEAN
Definition: pedump.c:73
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
struct _MODE_CACHING_PAGE * PMODE_CACHING_PAGE
BAD_CONTROLLER_INFORMATION const ScsiDiskBadControllers[]
Definition: disk.c:143

Referenced by CreateDiskDeviceObject(), and DiskFdoProcessError().

◆ DriverEntry()

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

Definition at line 342 of file disk.c.

365 {
367 
368  //
369  // Zero InitData
370  //
371 
373 
374  //
375  // Set sizes
376  //
377 
378  InitializationData.InitializationDataSize = sizeof(CLASS_INIT_DATA);
379  InitializationData.DeviceExtensionSize = DEVICE_EXTENSION_SIZE;
380 
382  InitializationData.DeviceCharacteristics = 0;
383 
384  //
385  // Set entry points
386  //
387 
389  InitializationData.ClassReadWriteVerification = ScsiDiskReadWriteVerification;
390  InitializationData.ClassFindDevices = FindScsiDisks;
391  InitializationData.ClassFindDeviceCallBack = ScsiDiskDeviceVerification;
392  InitializationData.ClassDeviceControl = ScsiDiskDeviceControl;
393  InitializationData.ClassShutdownFlush = ScsiDiskShutdownFlush;
394  InitializationData.ClassCreateClose = NULL;
395 
396  //
397  // Call the class init routine
398  //
399 
401 
402 } // end DriverEntry()
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
ULONG NTAPI ScsiClassInitialize(IN PVOID Argument1, IN PVOID Argument2, IN PCLASS_INIT_DATA InitializationData)
Definition: class2.c:160
VOID NTAPI ScsiDiskProcessError(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
Definition: disk.c:4706
NTSTATUS NTAPI ScsiDiskReadWriteVerification(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:1638
#define DEVICE_EXTENSION_SIZE
Definition: disk.c:162
NTSTATUS NTAPI ScsiDiskDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
BOOLEAN NTAPI ScsiDiskDeviceVerification(IN PINQUIRYDATA InquiryData)
Definition: disk.c:408
_In_ PVOID _In_ PCLASS_INIT_DATA InitializationData
Definition: classpnp.h:680
BOOLEAN NTAPI FindScsiDisks(IN PDRIVER_OBJECT DriveObject, IN PUNICODE_STRING RegistryPath, IN PCLASS_INIT_DATA InitializationData, IN PDEVICE_OBJECT PortDeviceObject, IN ULONG PortNumber)
Definition: disk.c:443
NTSTATUS NTAPI ScsiDiskShutdownFlush(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:3098
struct _CLASS_INIT_DATA CLASS_INIT_DATA
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27

Referenced by ScsiDiskDeviceControl().

◆ EnumerateBusKey()

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

Definition at line 3881 of file disk.c.

3907 {
3908  PDISK_DATA diskData = (PDISK_DATA)(DeviceExtension + 1);
3909  BOOLEAN diskFound = FALSE;
3910  OBJECT_ATTRIBUTES objectAttributes;
3911  UNICODE_STRING unicodeString;
3912  UNICODE_STRING identifier;
3913  ULONG busNumber;
3914  ULONG adapterNumber;
3915  ULONG diskNumber;
3916  HANDLE adapterKey;
3917  HANDLE spareKey;
3918  HANDLE diskKey;
3919  HANDLE targetKey;
3920  NTSTATUS status;
3921  STRING string;
3922  STRING anotherString;
3923  ULONG length;
3924  UCHAR buffer[20];
3926 
3927  PAGED_CODE();
3928 
3929  for (busNumber = 0; ; busNumber++) {
3930 
3931  //
3932  // Open controller name key.
3933  //
3934 
3935  sprintf((PCHAR)buffer,
3936  "%lu",
3937  busNumber);
3938 
3939  RtlInitString(&string,
3940  (PCSZ)buffer);
3941 
3942  status = RtlAnsiStringToUnicodeString(&unicodeString,
3943  &string,
3944  TRUE);
3945 
3946  if (!NT_SUCCESS(status)){
3947  break;
3948  }
3949 
3950  InitializeObjectAttributes(&objectAttributes,
3951  &unicodeString,
3953  BusKey,
3955 
3956  status = ZwOpenKey(&spareKey,
3957  KEY_READ,
3958  &objectAttributes);
3959 
3960  RtlFreeUnicodeString(&unicodeString);
3961 
3962  if (!NT_SUCCESS(status)) {
3963  break;
3964  }
3965 
3966  //
3967  // Open up controller ordinal key.
3968  //
3969 
3970  RtlInitUnicodeString(&unicodeString, L"DiskController");
3971  InitializeObjectAttributes(&objectAttributes,
3972  &unicodeString,
3974  spareKey,
3976 
3977  status = ZwOpenKey(&adapterKey,
3978  KEY_READ,
3979  &objectAttributes);
3980 
3981  //
3982  // This could fail even with additional adapters of this type
3983  // to search.
3984  //
3985 
3986  if (!NT_SUCCESS(status)) {
3987  continue;
3988  }
3989 
3990  for (adapterNumber = 0; ; adapterNumber++) {
3991 
3992  //
3993  // Open disk key.
3994  //
3995 
3996  sprintf((PCHAR)buffer,
3997  "%lu\\DiskPeripheral",
3998  adapterNumber);
3999 
4000  RtlInitString(&string,
4001  (PCSZ)buffer);
4002 
4003  status = RtlAnsiStringToUnicodeString(&unicodeString,
4004  &string,
4005  TRUE);
4006 
4007  if (!NT_SUCCESS(status)){
4008  break;
4009  }
4010 
4011  InitializeObjectAttributes(&objectAttributes,
4012  &unicodeString,
4014  adapterKey,
4016 
4017  status = ZwOpenKey(&diskKey,
4018  KEY_READ,
4019  &objectAttributes);
4020 
4021  RtlFreeUnicodeString(&unicodeString);
4022 
4023  if (!NT_SUCCESS(status)) {
4024  break;
4025  }
4026 
4027  for (diskNumber = 0; ; diskNumber++) {
4028 
4029  sprintf((PCHAR)buffer,
4030  "%lu",
4031  diskNumber);
4032 
4033  RtlInitString(&string,
4034  (PCSZ)buffer);
4035 
4036  status = RtlAnsiStringToUnicodeString(&unicodeString,
4037  &string,
4038  TRUE);
4039 
4040  if (!NT_SUCCESS(status)){
4041  break;
4042  }
4043 
4044  InitializeObjectAttributes(&objectAttributes,
4045  &unicodeString,
4047  diskKey,
4049 
4050  status = ZwOpenKey(&targetKey,
4051  KEY_READ,
4052  &objectAttributes);
4053 
4054  RtlFreeUnicodeString(&unicodeString);
4055 
4056  if (!NT_SUCCESS(status)) {
4057  break;
4058  }
4059 
4060  //
4061  // Allocate buffer for registry query.
4062  //
4063 
4065 
4066  if (keyData == NULL) {
4067  ZwClose(targetKey);
4068  continue;
4069  }
4070 
4071  //
4072  // Get disk peripheral identifier.
4073  //
4074 
4075  RtlInitUnicodeString(&unicodeString, L"Identifier");
4076  status = ZwQueryValueKey(targetKey,
4077  &unicodeString,
4079  keyData,
4081  &length);
4082 
4083  ZwClose(targetKey);
4084 
4085  if (!NT_SUCCESS(status)) {
4086  ExFreePool(keyData);
4087  continue;
4088  }
4089 
4090  if (keyData->DataLength < 9*sizeof(WCHAR)) {
4091  //
4092  // the data is too short to use (we subtract 9 chars in normal path)
4093  //
4094  DebugPrint((1, "EnumerateBusKey: Saved data was invalid, "
4095  "not enough data in registry!\n"));
4096  ExFreePool(keyData);
4097  continue;
4098  }
4099 
4100  //
4101  // Complete unicode string.
4102  //
4103 
4104  identifier.Buffer =
4105  (PWSTR)((PUCHAR)keyData + keyData->DataOffset);
4106  identifier.Length = (USHORT)keyData->DataLength;
4107  identifier.MaximumLength = (USHORT)keyData->DataLength;
4108 
4109  //
4110  // Convert unicode identifier to ansi string.
4111  //
4112 
4113  status =
4114  RtlUnicodeStringToAnsiString(&anotherString,
4115  &identifier,
4116  TRUE);
4117 
4118  if (!NT_SUCCESS(status)) {
4119  ExFreePool(keyData);
4120  continue;
4121  }
4122 
4123  //
4124  // If checksum is zero, then the MBR is valid and
4125  // the signature is meaningful.
4126  //
4127 
4128  if (diskData->MbrCheckSum) {
4129 
4130  //
4131  // Convert checksum to ansi string.
4132  //
4133 
4134  sprintf((PCHAR)buffer, "%08lx", diskData->MbrCheckSum);
4135 
4136  } else {
4137 
4138  //
4139  // Convert signature to ansi string.
4140  //
4141 
4142  sprintf((PCHAR)buffer, "%08lx", diskData->Signature);
4143 
4144  //
4145  // Make string point at signature. Can't use scan
4146  // functions because they are not exported for driver use.
4147  //
4148 
4149  anotherString.Buffer+=9;
4150  }
4151 
4152  //
4153  // Convert to ansi string.
4154  //
4155 
4156  RtlInitString(&string,
4157  (PCSZ)buffer);
4158 
4159 
4160  //
4161  // Make string lengths equal.
4162  //
4163 
4164  anotherString.Length = string.Length;
4165 
4166  //
4167  // Check if strings match.
4168  //
4169 
4170  if (RtlCompareString(&string,
4171  &anotherString,
4172  TRUE) == 0) {
4173 
4174  diskFound = TRUE;
4175  *DiskNumber = diskNumber;
4176  }
4177 
4178  ExFreePool(keyData);
4179 
4180  //
4181  // Readjust identifier string if necessary.
4182  //
4183 
4184  if (!diskData->MbrCheckSum) {
4185  anotherString.Buffer-=9;
4186  }
4187 
4188  RtlFreeAnsiString(&anotherString);
4189 
4190  if (diskFound) {
4191  break;
4192  }
4193  }
4194 
4195  ZwClose(diskKey);
4196  }
4197 
4198  ZwClose(adapterKey);
4199  }
4200 
4201  ZwClose(BusKey);
4202  return diskFound;
4203 
4204 } // end EnumerateBusKey()
signed char * PCHAR
Definition: retypes.h:7
CONST char * PCSZ
Definition: umtypes.h:125
struct _DISK_DATA * PDISK_DATA
#define TRUE
Definition: types.h:120
NTSYSAPI LONG NTAPI RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInSensitive)
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
GLuint buffer
Definition: glext.h:5915
#define PAGED_CODE()
Definition: video.h:57
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define VALUE_BUFFER_SIZE
Definition: disk.c:165
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
ULONG Signature
Definition: disk.c:52
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
std::wstring STRING
Definition: fontsub.cpp:33
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
char string[160]
Definition: util.h:11
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
ULONG MbrCheckSum
Definition: disk.c:58
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: ps.c:97

Referenced by UpdateGeometry().

◆ FindScsiDisks()

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

Definition at line 443 of file disk.c.

474 {
475  PIO_SCSI_CAPABILITIES portCapabilities;
476  PULONG diskCount;
477  PCONFIGURATION_INFORMATION configurationInformation;
478  PCHAR buffer;
479  PSCSI_INQUIRY_DATA lunInfo;
480  PSCSI_ADAPTER_BUS_INFO adapterInfo;
481  PINQUIRYDATA inquiryData;
482  ULONG scsiBus;
483  ULONG adapterDisk;
485  BOOLEAN foundOne = FALSE;
486 
487  PAGED_CODE();
488 
489  //
490  // Call port driver to get adapter capabilities.
491  //
492 
493  status = ScsiClassGetCapabilities(PortDeviceObject, &portCapabilities);
494 
495  if (!NT_SUCCESS(status)) {
496  DebugPrint((1,"FindScsiDevices: ScsiClassGetCapabilities failed\n"));
497  return(FALSE);
498  }
499 
500  //
501  // Call port driver to get inquiry information to find disks.
502  //
503 
505 
506  if (!NT_SUCCESS(status)) {
507  DebugPrint((1,"FindScsiDevices: ScsiClassGetInquiryData failed\n"));
508  return(FALSE);
509  }
510 
511  //
512  // Do a quick scan of the devices on this adapter to determine how many
513  // disks are on this adapter. This is used to determine the number of
514  // SRB zone elements to allocate.
515  //
516 
517  adapterInfo = (PVOID) buffer;
518 
519  adapterDisk = ScsiClassFindUnclaimedDevices(InitializationData, adapterInfo);
520 
521  //
522  // Allocate a zone of SRB for disks on this adapter.
523  //
524 
525  if (adapterDisk == 0) {
526 
527  //
528  // No free disks were found.
529  //
530 
531  return(FALSE);
532  }
533 
534  //
535  // Get the number of disks already initialized.
536  //
537 
538  configurationInformation = IoGetConfigurationInformation();
539  diskCount = &configurationInformation->DiskCount;
540 
541  //
542  // For each SCSI bus this adapter supports ...
543  //
544 
545  for (scsiBus=0; scsiBus < (ULONG)adapterInfo->NumberOfBuses; scsiBus++) {
546 
547  //
548  // Get the SCSI bus scan data for this bus.
549  //
550 
551  lunInfo = (PVOID) (buffer + adapterInfo->BusData[scsiBus].InquiryDataOffset);
552 
553  //
554  // Search list for unclaimed disk devices.
555  //
556 
557  while (adapterInfo->BusData[scsiBus].InquiryDataOffset) {
558 
559  inquiryData = (PVOID)lunInfo->InquiryData;
560 
561  if (((inquiryData->DeviceType == DIRECT_ACCESS_DEVICE) ||
562  (inquiryData->DeviceType == OPTICAL_DEVICE)) &&
563  inquiryData->DeviceTypeQualifier == 0 &&
564  (!lunInfo->DeviceClaimed)) {
565 
566  DebugPrint((1,
567  "FindScsiDevices: Vendor string is %.24s\n",
568  inquiryData->VendorId));
569 
570  //
571  // Create device objects for disk
572  //
573 
575  RegistryPath,
576  PortDeviceObject,
577  PortNumber,
578  diskCount,
579  portCapabilities,
580  lunInfo,
582 
583  if (NT_SUCCESS(status)) {
584 
585  //
586  // Increment system disk device count.
587  //
588 
589  (*diskCount)++;
590  foundOne = TRUE;
591 
592  }
593  }
594 
595  //
596  // Get next LunInfo.
597  //
598 
599  if (lunInfo->NextInquiryDataOffset == 0) {
600  break;
601  }
602 
603  lunInfo = (PVOID) (buffer + lunInfo->NextInquiryDataOffset);
604 
605  }
606  }
607 
608  //
609  // Buffer is allocated by ScsiClassGetInquiryData and must be free returning.
610  //
611 
613 
614  return(foundOne);
615 
616 } // end FindScsiDisks()
signed char * PCHAR
Definition: retypes.h:7
NTSTATUS NTAPI 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)
Definition: disk.c:621
#define TRUE
Definition: types.h:120
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
LONG NTSTATUS
Definition: precomp.h:26
GLuint buffer
Definition: glext.h:5915
ULONG NextInquiryDataOffset
Definition: scsi_port.h:118
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
NTSTATUS ScsiClassGetInquiryData(IN PDEVICE_OBJECT PortDeviceObject, IN PSCSI_ADAPTER_BUS_INFO *ConfigInfo)
#define PAGED_CODE()
Definition: video.h:57
SCSI_BUS_DATA BusData[1]
Definition: scsi_port.h:106
ULONG PortNumber
Definition: storport.c:18
unsigned char BOOLEAN
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
UCHAR DeviceTypeQualifier
Definition: cdrw_hw.h:1117
void * PVOID
Definition: retypes.h:9
ULONG InquiryDataOffset
Definition: scsi_port.h:98
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PVOID _In_ PCLASS_INIT_DATA InitializationData
Definition: classpnp.h:680
ULONG NTAPI ScsiClassFindUnclaimedDevices(IN PCLASS_INIT_DATA InitializationData, IN PSCSI_ADAPTER_BUS_INFO AdapterInformation)
Definition: class2.c:4316
UCHAR InquiryData[1]
Definition: scsi_port.h:119
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
UCHAR DeviceType
Definition: cdrw_hw.h:1116
unsigned int * PULONG
Definition: retypes.h:1
#define OPTICAL_DEVICE
Definition: cdrw_hw.h:1151
NTSTATUS ScsiClassGetCapabilities(IN PDEVICE_OBJECT PortDeviceObject, OUT PIO_SCSI_CAPABILITIES *PortCapabilities)
Definition: class2.c:531
BOOLEAN DeviceClaimed
Definition: scsi_port.h:116
unsigned int ULONG
Definition: retypes.h:1
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: ps.c:97

Referenced by DriverEntry().

◆ IsFloppyDevice() [1/2]

BOOLEAN NTAPI IsFloppyDevice ( IN PDEVICE_OBJECT  DeviceObject)

Referenced by CreateDiskDeviceObject().

◆ IsFloppyDevice() [2/2]

BOOLEAN NTAPI IsFloppyDevice ( PDEVICE_OBJECT  DeviceObject)

Definition at line 3276 of file disk.c.

3298 {
3299  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3300  PVOID modeData;
3301  PUCHAR pageData;
3302  ULONG length;
3303 
3304  PAGED_CODE();
3305 
3307 
3308  if (modeData == NULL) {
3309  return(FALSE);
3310  }
3311 
3312  RtlZeroMemory(modeData, MODE_DATA_SIZE);
3313 
3315  modeData,
3318 
3319  if (length < sizeof(MODE_PARAMETER_HEADER)) {
3320 
3321  //
3322  // Retry the request in case of a check condition.
3323  //
3324 
3326  modeData,
3329 
3330  if (length < sizeof(MODE_PARAMETER_HEADER)) {
3331 
3332  ExFreePool(modeData);
3333  return(FALSE);
3334 
3335  }
3336  }
3337 
3338  //
3339  // If the length is greater than length indicated by the mode data reset
3340  // the data to the mode data.
3341  //
3342 
3343  if (length > (ULONG) ((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1) {
3344  length = ((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1;
3345  }
3346 
3347  //
3348  // Look for the flexible disk mode page.
3349  //
3350 
3351  pageData = ScsiClassFindModePage( modeData, length, MODE_PAGE_FLEXIBILE, TRUE);
3352 
3353  if (pageData != NULL) {
3354 
3355  DebugPrint((1, "Scsidisk: Flexible disk page found, This is a floppy.\n"));
3356  ExFreePool(modeData);
3357  return(TRUE);
3358  }
3359 
3360  //
3361  // Check to see if the write cache is enabled.
3362  //
3363 
3364  pageData = ScsiClassFindModePage( modeData, length, MODE_PAGE_CACHING, TRUE);
3365 
3366  //
3367  // Assume that write cache is disabled or not supported.
3368  //
3369 
3370  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
3371 
3372  //
3373  // Check if valid caching page exists.
3374  //
3375 
3376  if (pageData != NULL) {
3377 
3378  //
3379  // Check if write cache is disabled.
3380  //
3381 
3382  if (((PMODE_CACHING_PAGE)pageData)->WriteCacheEnable) {
3383 
3384  DebugPrint((1,
3385  "SCSIDISK: Disk write cache enabled\n"));
3386 
3387  //
3388  // Check if forced unit access (FUA) is supported.
3389  //
3390 
3391  if (((PMODE_PARAMETER_HEADER)modeData)->DeviceSpecificParameter & MODE_DSP_FUA_SUPPORTED) {
3392 
3393  deviceExtension->DeviceFlags |= DEV_WRITE_CACHE;
3394 
3395  } else {
3396 
3397  DebugPrint((1,
3398  "SCSIDISK: Disk does not support FUA or DPO\n"));
3399 
3400  //
3401  // TODO: Log this.
3402  //
3403 
3404  }
3405  }
3406  }
3407 
3408  ExFreePool(modeData);
3409  return(FALSE);
3410 
3411 } // end IsFloppyDevice()
#define TRUE
Definition: types.h:120
#define MODE_PAGE_CACHING
Definition: cdrw_hw.h:846
unsigned char * PUCHAR
Definition: retypes.h:3
#define MODE_SENSE_RETURN_ALL
Definition: cdrw_hw.h:857
#define PAGED_CODE()
Definition: video.h:57
#define DEV_WRITE_CACHE
Definition: class2.h:21
#define MODE_DATA_SIZE
Definition: disk.c:164
PVOID NTAPI ScsiClassFindModePage(IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode, IN BOOLEAN Use6Byte)
Definition: class2.c:3295
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
ULONG NTAPI ScsiClassModeSense(IN PDEVICE_OBJECT DeviceObject, IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode)
Definition: class2.c:3198
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define MODE_DSP_FUA_SUPPORTED
Definition: cdrw_hw.h:2522
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define MODE_PAGE_FLEXIBILE
Definition: scsi.h:196

Referenced by ScsiFlopInitDevice().

◆ ReportToMountMgr()

VOID NTAPI ReportToMountMgr ( IN PDEVICE_OBJECT  DiskDeviceObject)

Definition at line 1073 of file disk.c.

1093 {
1094  NTSTATUS status;
1095  UNICODE_STRING mountMgrDevice;
1096  PDEVICE_OBJECT deviceObject;
1097  PFILE_OBJECT fileObject;
1098  PMOUNTMGR_TARGET_NAME mountTarget;
1099  ULONG diskLen;
1100  PDEVICE_EXTENSION deviceExtension;
1101  PIRP irp;
1102  KEVENT event;
1103  IO_STATUS_BLOCK ioStatus;
1104 
1105  //
1106  // First, get MountMgr DeviceObject.
1107  //
1108 
1109  RtlInitUnicodeString(&mountMgrDevice, MOUNTMGR_DEVICE_NAME);
1111  &fileObject, &deviceObject);
1112 
1113  if (!NT_SUCCESS(status)) {
1114 
1115  DebugPrint((1,
1116  "ReportToMountMgr: Can't get MountMgr pointers %lx\n",
1117  status));
1118 
1119  return;
1120  }
1121 
1122  deviceExtension = DiskDeviceObject->DeviceExtension;
1123  diskLen = deviceExtension->DeviceName.Length;
1124 
1125  //
1126  // Allocate input buffer to report our partition device.
1127  //
1128 
1129  mountTarget = ExAllocatePool(NonPagedPool,
1130  sizeof(MOUNTMGR_TARGET_NAME) + diskLen);
1131 
1132  if (!mountTarget) {
1133 
1134  DebugPrint((1,
1135  "ReportToMountMgr: Allocation of mountTarget failed\n"));
1136 
1137  ObDereferenceObject(fileObject);
1138  return;
1139  }
1140 
1141  mountTarget->DeviceNameLength = diskLen;
1142  RtlCopyMemory(mountTarget->DeviceName, deviceExtension->DeviceName.Buffer, diskLen);
1143 
1145 
1146  //
1147  // Build the IRP used to communicate with the MountMgr.
1148  //
1149 
1151  deviceObject,
1152  mountTarget,
1153  sizeof(MOUNTMGR_TARGET_NAME) + diskLen,
1154  NULL,
1155  0,
1156  FALSE,
1157  &event,
1158  &ioStatus);
1159 
1160  if (!irp) {
1161 
1162  DebugPrint((1,
1163  "ReportToMountMgr: Allocation of irp failed\n"));
1164 
1165  ExFreePool(mountTarget);
1166  ObDereferenceObject(fileObject);
1167  return;
1168  }
1169 
1170  //
1171  // Call the MountMgr.
1172  //
1173 
1174  status = IoCallDriver(deviceObject, irp);
1175 
1176  if (status == STATUS_PENDING) {
1178  status = ioStatus.Status;
1179  }
1180 
1181  //
1182  // We're done.
1183  //
1184 
1185  DPRINT1("Reported to the MountMgr: %lx\n", status);
1186 
1187  ExFreePool(mountTarget);
1188  ObDereferenceObject(fileObject);
1189 
1190  return;
1191 }
WCHAR DeviceName[1]
Definition: imports.h:155
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define MOUNTMGR_DEVICE_NAME
Definition: imports.h:76
#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION
Definition: imports.h:130
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
_Outptr_ PDEVICE_OBJECT * DiskDeviceObject
Definition: fltkernel.h:1673
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
* PFILE_OBJECT
Definition: iotypes.h:1955
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
struct _cl_event * event
Definition: glext.h:7739
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
USHORT DeviceNameLength
Definition: imports.h:154
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: ps.c:97

Referenced by CreatePartitionDeviceObjects().

◆ ResetScsiBus()

VOID NTAPI ResetScsiBus ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 4872 of file disk.c.

4892 {
4893  PIO_STACK_LOCATION irpStack;
4894  PIRP irp;
4895  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4896  PSCSI_REQUEST_BLOCK srb;
4898 
4899  DebugPrint((1, "ScsiDisk ResetScsiBus: Sending reset bus request to port driver.\n"));
4900 
4901  //
4902  // Allocate Srb from nonpaged pool.
4903  //
4904 
4906  sizeof(COMPLETION_CONTEXT));
4907 
4908  //
4909  // Save the device object in the context for use by the completion
4910  // routine.
4911  //
4912 
4913  context->DeviceObject = DeviceObject;
4914  srb = &context->Srb;
4915 
4916  //
4917  // Zero out srb.
4918  //
4919 
4921 
4922  //
4923  // Write length to SRB.
4924  //
4925 
4927 
4928  //
4929  // Set up SCSI bus address.
4930  //
4931 
4932  srb->PathId = deviceExtension->PathId;
4933  srb->TargetId = deviceExtension->TargetId;
4934  srb->Lun = deviceExtension->Lun;
4935 
4937 
4938  //
4939  // Build the asynchronous request to be sent to the port driver.
4940  // Since this routine is called from a DPC the IRP should always be
4941  // available.
4942  //
4943 
4945 
4948  context,
4949  TRUE,
4950  TRUE,
4951  TRUE);
4952 
4953  irpStack = IoGetNextIrpStackLocation(irp);
4954 
4955  irpStack->MajorFunction = IRP_MJ_SCSI;
4956 
4957  srb->OriginalRequest = irp;
4958 
4959  //
4960  // Store the SRB address in next stack for port driver.
4961  //
4962 
4963  irpStack->Parameters.Scsi.Srb = srb;
4964 
4965  //
4966  // Call the port driver with the IRP.
4967  //
4968 
4969  IoCallDriver(deviceExtension->PortDeviceObject, irp);
4970 
4971  return;
4972 
4973 } // end ResetScsiBus()
#define TRUE
Definition: types.h:120
PVOID OriginalRequest
Definition: srb.h:258
Definition: http.c:7094
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IRP_MJ_SCSI
PVOID DeviceExtension
Definition: env_spec_w32.h:418
UCHAR TargetId
Definition: srb.h:246
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define SRB_FUNCTION_RESET_BUS
Definition: srb.h:318
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
UCHAR PathId
Definition: srb.h:245
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
IO_COMPLETION_ROUTINE * PIO_COMPLETION_ROUTINE
Definition: iotypes.h:2480
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
IO_COMPLETION_ROUTINE ScsiClassAsynchronousCompletion
Definition: class2.h:148

Referenced by ScsiDiskProcessError().

◆ ScanForSpecial()

VOID NTAPI ScanForSpecial ( PDEVICE_OBJECT  DeviceObject,
PSCSI_INQUIRY_DATA  LunInfo,
PIO_SCSI_CAPABILITIES  PortCapabilities 
)

Definition at line 4770 of file disk.c.

4797 {
4798  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4799  PINQUIRYDATA InquiryData = (PINQUIRYDATA)LunInfo->InquiryData;
4800  BAD_CONTROLLER_INFORMATION const *controller;
4801  ULONG j;
4802 
4803  for (j = 0; j < NUMBER_OF_BAD_CONTROLLERS; j++) {
4804 
4805  controller = &ScsiDiskBadControllers[j];
4806 
4807  if (strncmp(controller->InquiryString, (PCCHAR)InquiryData->VendorId, strlen(controller->InquiryString))) {
4808  continue;
4809  }
4810 
4811  DebugPrint((1, "ScsiDisk ScanForSpecial, Found bad controller! %s\n", controller->InquiryString));
4812 
4813  //
4814  // Found a listed controller. Determine what must be done.
4815  //
4816 
4817  if (controller->DisableTaggedQueuing) {
4818 
4819  //
4820  // Disable tagged queuing.
4821  //
4822 
4823  deviceExtension->SrbFlags &= ~SRB_FLAGS_QUEUE_ACTION_ENABLE;
4824  }
4825 
4826  if (controller->DisableSynchronousTransfers) {
4827 
4828  //
4829  // Disable synchronous data transfers.
4830  //
4831 
4832  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
4833 
4834  }
4835 
4836  if (controller->DisableDisconnects) {
4837 
4838  //
4839  // Disable disconnects.
4840  //
4841 
4842  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT;
4843 
4844  }
4845 
4846  //
4847  // Found device so exit the loop and return.
4848  //
4849 
4850  break;
4851  }
4852 
4853  //
4854  // Set the StartUnit flag appropriately.
4855  //
4856 
4857  if (DeviceObject->DeviceType == FILE_DEVICE_DISK) {
4858  deviceExtension->DeviceFlags |= DEV_SAFE_START_UNIT;
4859 
4860  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
4861  if (_strnicmp((PCCHAR)InquiryData->VendorId, "iomega", strlen("iomega"))) {
4862  deviceExtension->DeviceFlags &= ~DEV_SAFE_START_UNIT;
4863  }
4864  }
4865  }
4866 
4867  return;
4868 }
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
struct _INQUIRYDATA * PINQUIRYDATA
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
_Check_return_ _CRTIMP int __cdecl _strnicmp(_In_reads_or_z_(_MaxCount) const char *_Str1, _In_reads_or_z_(_MaxCount) const char *_Str2, _In_ size_t _MaxCount)
PVOID DeviceExtension
Definition: env_spec_w32.h:418
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
#define for
Definition: utility.h:88
#define SRB_FLAGS_DISABLE_DISCONNECT
Definition: srb.h:388
#define NUMBER_OF_BAD_CONTROLLERS
Definition: disk.c:161
UCHAR InquiryData[1]
Definition: scsi_port.h:119
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define DEV_SAFE_START_UNIT
Definition: class2.h:35
unsigned int ULONG
Definition: retypes.h:1
BAD_CONTROLLER_INFORMATION const ScsiDiskBadControllers[]
Definition: disk.c:143
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:387

Referenced by CreateDiskDeviceObject().

◆ ScsiDiskCreateClose()

NTSTATUS NTAPI ScsiDiskCreateClose ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

◆ ScsiDiskDeviceControl() [1/2]

NTSTATUS NTAPI ScsiDiskDeviceControl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Referenced by DriverEntry().

◆ ScsiDiskDeviceControl() [2/2]

NTSTATUS NTAPI ScsiDiskDeviceControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 1733 of file disk.c.

1755 {
1757  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1758  PDISK_DATA diskData = (PDISK_DATA)(deviceExtension + 1);
1759  PSCSI_REQUEST_BLOCK srb;
1760  PCDB cdb;
1761  PMODE_PARAMETER_HEADER modeData;
1762  PIRP irp2;
1763  ULONG length;
1764  NTSTATUS status;
1765  KEVENT event;
1766  IO_STATUS_BLOCK ioStatus;
1767 
1768  PAGED_CODE();
1769 
1771 
1772  if (srb == NULL) {
1773 
1774  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1777  }
1778 
1779  //
1780  // Write zeros to Srb.
1781  //
1782 
1784 
1785  cdb = (PCDB)srb->Cdb;
1786 
1787  switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
1788 
1789  case SMART_GET_VERSION: {
1790 
1791  ULONG_PTR buffer;
1792  PSRB_IO_CONTROL srbControl;
1793  PGETVERSIONINPARAMS versionParams;
1794 
1795  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1796  sizeof(GETVERSIONINPARAMS)) {
1798  break;
1799  }
1800 
1801  //
1802  // Create notification event object to be used to signal the
1803  // request completion.
1804  //
1805 
1807 
1808  srbControl = ExAllocatePool(NonPagedPool,
1809  sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS));
1810 
1811  if (!srbControl) {
1813  break;
1814  }
1815 
1816  //
1817  // fill in srbControl fields
1818  //
1819 
1820  srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
1821  RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
1822  srbControl->Timeout = deviceExtension->TimeOutValue;
1823  srbControl->Length = sizeof(GETVERSIONINPARAMS);
1825 
1826  //
1827  // Point to the 'buffer' portion of the SRB_CONTROL
1828  //
1829 
1830  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
1831 
1832  //
1833  // Ensure correct target is set in the cmd parameters.
1834  //
1835 
1836  versionParams = (PGETVERSIONINPARAMS)buffer;
1837  versionParams->bIDEDeviceMap = deviceExtension->TargetId;
1838 
1839  //
1840  // Copy the IOCTL parameters to the srb control buffer area.
1841  //
1842 
1843  RtlMoveMemory((PVOID)buffer, Irp->AssociatedIrp.SystemBuffer, sizeof(GETVERSIONINPARAMS));
1844 
1845 
1847  deviceExtension->PortDeviceObject,
1848  srbControl,
1849  sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS),
1850  srbControl,
1851  sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS),
1852  FALSE,
1853  &event,
1854  &ioStatus);
1855 
1856  if (irp2 == NULL) {
1858  break;
1859  }
1860 
1861  //
1862  // Call the port driver with the request and wait for it to complete.
1863  //
1864 
1865  status = IoCallDriver(deviceExtension->PortDeviceObject, irp2);
1866 
1867  if (status == STATUS_PENDING) {
1869  status = ioStatus.Status;
1870  }
1871 
1872  //
1873  // If successful, copy the data received into the output buffer.
1874  // This should only fail in the event that the IDE driver is older than this driver.
1875  //
1876 
1877  if (NT_SUCCESS(status)) {
1878 
1879  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
1880 
1881  RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, (PVOID)buffer, sizeof(GETVERSIONINPARAMS));
1882  Irp->IoStatus.Information = sizeof(GETVERSIONINPARAMS);
1883  }
1884 
1885  ExFreePool(srbControl);
1886  break;
1887  }
1888 
1889  case SMART_RCV_DRIVE_DATA: {
1890 
1891  PSENDCMDINPARAMS cmdInParameters = ((PSENDCMDINPARAMS)Irp->AssociatedIrp.SystemBuffer);
1892  ULONG controlCode = 0;
1893  PSRB_IO_CONTROL srbControl;
1894  ULONG_PTR buffer;
1895 
1896  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
1897  (sizeof(SENDCMDINPARAMS) - 1)) {
1899  break;
1900 
1901  } else if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1902  (sizeof(SENDCMDOUTPARAMS) + 512 - 1)) {
1904  break;
1905  }
1906 
1907  //
1908  // Create notification event object to be used to signal the
1909  // request completion.
1910  //
1911 
1913 
1914  if (cmdInParameters->irDriveRegs.bCommandReg == ID_CMD) {
1915 
1917  controlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
1918 
1919  } else if (cmdInParameters->irDriveRegs.bCommandReg == SMART_CMD) {
1920  switch (cmdInParameters->irDriveRegs.bFeaturesReg) {
1921  case READ_ATTRIBUTES:
1924  break;
1925  case READ_THRESHOLDS:
1928  break;
1929  default:
1931  break;
1932  }
1933  } else {
1934 
1936  }
1937 
1938  if (controlCode == 0) {
1940  break;
1941  }
1942 
1943  srbControl = ExAllocatePool(NonPagedPool,
1944  sizeof(SRB_IO_CONTROL) + length);
1945 
1946  if (!srbControl) {
1948  break;
1949  }
1950 
1951  //
1952  // fill in srbControl fields
1953  //
1954 
1955  srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
1956  RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
1957  srbControl->Timeout = deviceExtension->TimeOutValue;
1958  srbControl->Length = length;
1959  srbControl->ControlCode = controlCode;
1960 
1961  //
1962  // Point to the 'buffer' portion of the SRB_CONTROL
1963  //
1964 
1965  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
1966 
1967  //
1968  // Ensure correct target is set in the cmd parameters.
1969  //
1970 
1971  cmdInParameters->bDriveNumber = deviceExtension->TargetId;
1972 
1973  //
1974  // Copy the IOCTL parameters to the srb control buffer area.
1975  //
1976 
1977  RtlMoveMemory((PVOID)buffer, Irp->AssociatedIrp.SystemBuffer, sizeof(SENDCMDINPARAMS) - 1);
1978 
1980  deviceExtension->PortDeviceObject,
1981  srbControl,
1982  sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1,
1983  srbControl,
1984  sizeof(SRB_IO_CONTROL) + length,
1985  FALSE,
1986  &event,
1987  &ioStatus);
1988 
1989  if (irp2 == NULL) {
1991  break;
1992  }
1993 
1994  //
1995  // Call the port driver with the request and wait for it to complete.
1996  //
1997 
1998  status = IoCallDriver(deviceExtension->PortDeviceObject, irp2);
1999 
2000  if (status == STATUS_PENDING) {
2002  status = ioStatus.Status;
2003  }
2004 
2005  //
2006  // If successful, copy the data received into the output buffer
2007  //
2008 
2009  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
2010 
2011  if (NT_SUCCESS(status)) {
2012 
2013  RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, (PVOID)buffer, length - 1);
2014  Irp->IoStatus.Information = length - 1;
2015 
2016  } else {
2017 
2018  RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, (PVOID)buffer, (sizeof(SENDCMDOUTPARAMS) - 1));
2019  Irp->IoStatus.Information = sizeof(SENDCMDOUTPARAMS) - 1;
2020 
2021  }
2022 
2023  ExFreePool(srbControl);
2024  break;
2025 
2026  }
2027 
2028  case SMART_SEND_DRIVE_COMMAND: {
2029 
2030  PSENDCMDINPARAMS cmdInParameters = ((PSENDCMDINPARAMS)Irp->AssociatedIrp.SystemBuffer);
2031  PSRB_IO_CONTROL srbControl;
2032  ULONG controlCode = 0;
2033  ULONG_PTR buffer;
2034 
2035  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2036  (sizeof(SENDCMDINPARAMS) - 1)) {
2038  break;
2039 
2040  } else if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
2041  (sizeof(SENDCMDOUTPARAMS) - 1)) {
2043  break;
2044  }
2045 
2046  //
2047  // Create notification event object to be used to signal the
2048  // request completion.
2049  //
2050 
2052 
2053  length = 0;
2054 
2055  if (cmdInParameters->irDriveRegs.bCommandReg == SMART_CMD) {
2056  switch (cmdInParameters->irDriveRegs.bFeaturesReg) {
2057 
2058  case ENABLE_SMART:
2059  controlCode = IOCTL_SCSI_MINIPORT_ENABLE_SMART;
2060  break;
2061 
2062  case DISABLE_SMART:
2063  controlCode = IOCTL_SCSI_MINIPORT_DISABLE_SMART;
2064  break;
2065 
2066  case RETURN_SMART_STATUS:
2067 
2068  //
2069  // Ensure bBuffer is at least 2 bytes (to hold the values of
2070  // cylinderLow and cylinderHigh).
2071  //
2072 
2073  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
2074  (sizeof(SENDCMDOUTPARAMS) - 1 + sizeof(IDEREGS))) {
2075 
2077  break;
2078  }
2079 
2080  controlCode = IOCTL_SCSI_MINIPORT_RETURN_STATUS;
2081  length = sizeof(IDEREGS);
2082  break;
2083 
2086  break;
2087 
2088  case SAVE_ATTRIBUTE_VALUES:
2090  break;
2091 
2092  case EXECUTE_OFFLINE_DIAGS:
2094  break;
2095 
2096  default:
2098  break;
2099  }
2100  } else {
2101 
2103  }
2104 
2105  if (controlCode == 0) {
2107  break;
2108  }
2109 
2110  length += (sizeof(SENDCMDOUTPARAMS) > sizeof(SENDCMDINPARAMS)) ? sizeof(SENDCMDOUTPARAMS) : sizeof(SENDCMDINPARAMS);
2111  srbControl = ExAllocatePool(NonPagedPool,
2112  sizeof(SRB_IO_CONTROL) + length);
2113 
2114  if (!srbControl) {
2116  break;
2117  }
2118 
2119  //
2120  // fill in srbControl fields
2121  //
2122 
2123  srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
2124  RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
2125  srbControl->Timeout = deviceExtension->TimeOutValue;
2126  srbControl->Length = length;
2127 
2128  //
2129  // Point to the 'buffer' portion of the SRB_CONTROL
2130  //
2131 
2132  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
2133 
2134  //
2135  // Ensure correct target is set in the cmd parameters.
2136  //
2137 
2138  cmdInParameters->bDriveNumber = deviceExtension->TargetId;
2139 
2140  //
2141  // Copy the IOCTL parameters to the srb control buffer area.
2142  //
2143 
2144  RtlMoveMemory((PVOID)buffer, Irp->AssociatedIrp.SystemBuffer, sizeof(SENDCMDINPARAMS) - 1);
2145 
2146  srbControl->ControlCode = controlCode;
2147 
2149  deviceExtension->PortDeviceObject,
2150  srbControl,
2151  sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1,
2152  srbControl,
2153  sizeof(SRB_IO_CONTROL) + length,
2154  FALSE,
2155  &event,
2156  &ioStatus);
2157 
2158  if (irp2 == NULL) {
2160  break;
2161  }
2162 
2163  //
2164  // Call the port driver with the request and wait for it to complete.
2165  //
2166 
2167  status = IoCallDriver(deviceExtension->PortDeviceObject, irp2);
2168 
2169  if (status == STATUS_PENDING) {
2171  status = ioStatus.Status;
2172  }
2173 
2174  //
2175  // Copy the data received into the output buffer. Since the status buffer
2176  // contains error information also, always perform this copy. IO will will
2177  // either pass this back to the app, or zero it, in case of error.
2178  //
2179 
2180  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
2181 
2182  //
2183  // Update the return buffer size based on the sub-command.
2184  //
2185 
2186  if (cmdInParameters->irDriveRegs.bFeaturesReg == RETURN_SMART_STATUS) {
2187  length = sizeof(SENDCMDOUTPARAMS) - 1 + sizeof(IDEREGS);
2188  } else {
2189  length = sizeof(SENDCMDOUTPARAMS) - 1;
2190  }
2191 
2192  RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, (PVOID)buffer, length);
2193  Irp->IoStatus.Information = length;
2194 
2195  ExFreePool(srbControl);
2196  break;
2197 
2198  }
2199 
2202  {
2203 
2204  PDEVICE_EXTENSION physicalDeviceExtension;
2205  PDISK_DATA physicalDiskData;
2206  BOOLEAN removable = FALSE;
2207  BOOLEAN listInitialized = FALSE;
2208  ULONG copyLength;
2209 
2210  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) {
2211  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY)) {
2213  break;
2214  }
2215 
2216  copyLength = sizeof(DISK_GEOMETRY);
2217  } else {
2218  ASSERT(irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX);
2219  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(DISK_GEOMETRY_EX, Data)) {
2221  break;
2222  }
2223 
2224  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(DISK_GEOMETRY_EX)) {
2225  copyLength = sizeof(DISK_GEOMETRY_EX);
2226  } else {
2227  copyLength = FIELD_OFFSET(DISK_GEOMETRY_EX, Data);
2228  }
2229  }
2230 
2232 
2233  physicalDeviceExtension = deviceExtension->PhysicalDevice->DeviceExtension;
2234  physicalDiskData = (PDISK_DATA)(physicalDeviceExtension + 1);
2235 
2236  removable = (BOOLEAN)DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA;
2237  listInitialized = (physicalDiskData->PartitionListState == Initialized);
2238 
2239  if (removable || (!listInitialized))
2240  {
2241  //
2242  // Issue ReadCapacity to update device extension
2243  // with information for current media.
2244  //
2245 
2246  status = ScsiClassReadDriveCapacity(deviceExtension->PhysicalDevice);
2247 
2248  }
2249 
2250  if (removable) {
2251 
2252  if (!NT_SUCCESS(status)) {
2253 
2254  //
2255  // Note the drive is not ready.
2256  //
2257 
2258  diskData->DriveNotReady = TRUE;
2259 
2260  break;
2261  }
2262 
2263  //
2264  // Note the drive is now ready.
2265  //
2266 
2267  diskData->DriveNotReady = FALSE;
2268 
2269  } else if (NT_SUCCESS(status)) {
2270 
2271  // ReadDriveCapacity was alright, create Partition Objects
2272 
2273  if (physicalDiskData->PartitionListState == NotInitialized) {
2274  status = CreatePartitionDeviceObjects(deviceExtension->PhysicalDevice, NULL);
2275  }
2276  }
2277 
2278  if (NT_SUCCESS(status)) {
2279 
2280  //
2281  // Copy drive geometry information from device extension.
2282  //
2283 
2284  RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
2285  deviceExtension->DiskGeometry,
2286  copyLength);
2287 
2289  Irp->IoStatus.Information = copyLength;
2290  }
2291 
2292  break;
2293 
2294  }
2295 
2296  case IOCTL_DISK_VERIFY:
2297 
2298  {
2299 
2300  PVERIFY_INFORMATION verifyInfo = Irp->AssociatedIrp.SystemBuffer;
2301  LARGE_INTEGER byteOffset;
2302  ULONG sectorOffset;
2304 
2305  //
2306  // Validate buffer length.
2307  //
2308 
2309  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2310  sizeof(VERIFY_INFORMATION)) {
2311 
2313  break;
2314  }
2315 
2316  //
2317  // Verify sectors
2318  //
2319 
2320  srb->CdbLength = 10;
2321 
2322  cdb->CDB10.OperationCode = SCSIOP_VERIFY;
2323 
2324  //
2325  // Add disk offset to starting sector.
2326  //
2327 
2328  byteOffset.QuadPart = deviceExtension->StartingOffset.QuadPart +
2329  verifyInfo->StartingOffset.QuadPart;
2330 
2331  //
2332  // Convert byte offset to sector offset.
2333  //
2334 
2335  sectorOffset = (ULONG)(byteOffset.QuadPart >> deviceExtension->SectorShift);
2336 
2337  //
2338  // Convert ULONG byte count to USHORT sector count.
2339  //
2340 
2341  sectorCount = (USHORT)(verifyInfo->Length >> deviceExtension->SectorShift);
2342 
2343  //
2344  // Move little endian values into CDB in big endian format.
2345  //
2346 
2347  cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&sectorOffset)->Byte3;
2348  cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&sectorOffset)->Byte2;
2349  cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&sectorOffset)->Byte1;
2350  cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&sectorOffset)->Byte0;
2351 
2352  cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&sectorCount)->Byte1;
2353  cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&sectorCount)->Byte0;
2354 
2355  //
2356  // The verify command is used by the NT FORMAT utility and
2357  // requests are sent down for 5% of the volume size. The
2358  // request timeout value is calculated based on the number of
2359  // sectors verified.
2360  //
2361 
2362  srb->TimeOutValue = ((sectorCount + 0x7F) >> 7) *
2363  deviceExtension->TimeOutValue;
2364 
2366  srb,
2367  Irp,
2368  NULL,
2369  0,
2370  FALSE);
2371 
2372  return(status);
2373 
2374  }
2375 
2377 
2378  //
2379  // Return the information about the partition specified by the device
2380  // object. Note that no information is ever returned about the size
2381  // or partition type of the physical disk, as this doesn't make any
2382  // sense.
2383  //
2384 
2385  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
2386  sizeof(PARTITION_INFORMATION)) {
2387 
2389  break;
2390  }
2391 
2392  //
2393  // Update the geometry in case it has changed.
2394  //
2395 
2397 
2398  if (!NT_SUCCESS(status)) {
2399 
2400  //
2401  // Note the drive is not ready.
2402  //
2403 
2404  diskData->DriveNotReady = TRUE;
2405  break;
2406  }
2407 
2408  //
2409  // Note the drive is now ready.
2410  //
2411 
2412  diskData->DriveNotReady = FALSE;
2413 
2414  //
2415  // Handle the case were we query the whole disk
2416  //
2417 
2418  if (diskData->PartitionNumber == 0) {
2419 
2420  PPARTITION_INFORMATION outputBuffer;
2421 
2422  outputBuffer =
2423  (PPARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2424 
2425  outputBuffer->PartitionType = PARTITION_ENTRY_UNUSED;
2426  outputBuffer->StartingOffset = deviceExtension->StartingOffset;
2427  outputBuffer->PartitionLength.QuadPart = deviceExtension->PartitionLength.QuadPart;
2428  outputBuffer->HiddenSectors = 0;
2429  outputBuffer->PartitionNumber = diskData->PartitionNumber;
2430  outputBuffer->BootIndicator = FALSE;
2431  outputBuffer->RewritePartition = FALSE;
2432  outputBuffer->RecognizedPartition = FALSE;
2433 
2435  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
2436 
2437  } else {
2438 
2439  PPARTITION_INFORMATION outputBuffer;
2440 
2441  //
2442  // We query a single partition here
2443  // FIXME: this can only work for MBR-based disks, check for this!
2444  //
2445 
2446  outputBuffer =
2447  (PPARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2448 
2449  outputBuffer->PartitionType = diskData->PartitionType;
2450  outputBuffer->StartingOffset = deviceExtension->StartingOffset;
2451  outputBuffer->PartitionLength.QuadPart = deviceExtension->PartitionLength.QuadPart;
2452  outputBuffer->HiddenSectors = diskData->HiddenSectors;
2453  outputBuffer->PartitionNumber = diskData->PartitionNumber;
2454  outputBuffer->BootIndicator = diskData->BootIndicator;
2455  outputBuffer->RewritePartition = FALSE;
2456  outputBuffer->RecognizedPartition =
2458 
2460  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
2461  }
2462 
2463  break;
2464 
2466 
2467  //
2468  // Return the information about the partition specified by the device
2469  // object. Note that no information is ever returned about the size
2470  // or partition type of the physical disk, as this doesn't make any
2471  // sense.
2472  //
2473 
2474  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
2475  sizeof(PARTITION_INFORMATION_EX)) {
2476 
2478 
2479  }
2480 #if 0 // HACK: ReactOS partition numbers must be wrong
2481  else if (diskData->PartitionNumber == 0) {
2482 
2483  //
2484  // Partition zero is not a partition so this is not a
2485  // reasonable request.
2486  //
2487 
2489 
2490  }
2491 #endif
2492  else {
2493 
2494  PPARTITION_INFORMATION_EX outputBuffer;
2495 
2496  if (diskData->PartitionNumber == 0) {
2497  DPRINT1("HACK: Handling partition 0 request!\n");
2498  //ASSERT(FALSE);
2499  }
2500 
2501  //
2502  // Update the geometry in case it has changed.
2503  //
2504 
2506 
2507  if (!NT_SUCCESS(status)) {
2508 
2509  //
2510  // Note the drive is not ready.
2511  //
2512 
2513  diskData->DriveNotReady = TRUE;
2514  break;
2515  }
2516 
2517  //
2518  // Note the drive is now ready.
2519  //
2520 
2521  diskData->DriveNotReady = FALSE;
2522 
2523  if (diskData->PartitionType == 0 && (diskData->PartitionNumber > 0)) {
2524 
2526  break;
2527  }
2528 
2529  outputBuffer =
2530  (PPARTITION_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer;
2531 
2532  //
2533  // FIXME: hack of the year, assume that partition is MBR
2534  // Thing that can obviously be wrong...
2535  //
2536 
2537  outputBuffer->PartitionStyle = PARTITION_STYLE_MBR;
2538  outputBuffer->Mbr.PartitionType = diskData->PartitionType;
2539  outputBuffer->StartingOffset = deviceExtension->StartingOffset;
2540  outputBuffer->PartitionLength.QuadPart = deviceExtension->PartitionLength.QuadPart;
2541  outputBuffer->Mbr.HiddenSectors = diskData->HiddenSectors;
2542  outputBuffer->PartitionNumber = diskData->PartitionNumber;
2543  outputBuffer->Mbr.BootIndicator = diskData->BootIndicator;
2544  outputBuffer->RewritePartition = FALSE;
2545  outputBuffer->Mbr.RecognizedPartition =
2547 
2549  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX);
2550  }
2551 
2552  break;
2553 
2555 
2556  if (diskData->PartitionNumber == 0) {
2557 
2559 
2560  } else {
2561 
2562  PSET_PARTITION_INFORMATION inputBuffer =
2563  (PSET_PARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2564 
2565  //
2566  // Validate buffer length.
2567  //
2568 
2569  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2570  sizeof(SET_PARTITION_INFORMATION)) {
2571 
2573  break;
2574  }
2575 
2576  //
2577  // The HAL routines IoGet- and IoSetPartitionInformation were
2578  // developed before support of dynamic partitioning and therefore
2579  // don't distinguish between partition ordinal (that is the order
2580  // of a partition on a disk) and the partition number. (The
2581  // partition number is assigned to a partition to identify it to
2582  // the system.) Use partition ordinals for these legacy calls.
2583  //
2584 
2586  deviceExtension->PhysicalDevice,
2587  deviceExtension->DiskGeometry->Geometry.BytesPerSector,
2588  diskData->PartitionOrdinal,
2589  inputBuffer->PartitionType);
2590 
2591  if (NT_SUCCESS(status)) {
2592 
2593  diskData->PartitionType = inputBuffer->PartitionType;
2594  }
2595  }
2596 
2597  break;
2598 
2600 
2601  //
2602  // Return the partition layout for the physical drive. Note that
2603  // the layout is returned for the actual physical drive, regardless
2604  // of which partition was specified for the request.
2605  //
2606 
2607  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
2608  sizeof(DRIVE_LAYOUT_INFORMATION)) {
2610 
2611  } else {
2612 
2613  PDRIVE_LAYOUT_INFORMATION partitionList;
2614  PDEVICE_EXTENSION physicalExtension = deviceExtension;
2615  PPARTITION_INFORMATION partitionEntry;
2616  PDISK_DATA diskData;
2617  ULONG tempSize;
2618  ULONG i;
2619 
2620  //
2621  // Read partition information.
2622  //
2623 
2624  status = IoReadPartitionTable(deviceExtension->PhysicalDevice,
2625  deviceExtension->DiskGeometry->Geometry.BytesPerSector,
2626  FALSE,
2627  &partitionList);
2628 
2629  if (!NT_SUCCESS(status)) {
2630  break;
2631  }
2632 
2633  //
2634  // The disk layout has been returned in the partitionList
2635  // buffer. Determine its size and, if the data will fit
2636  // into the intermediary buffer, return it.
2637  //
2638 
2639  tempSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION,PartitionEntry[0]);
2640  tempSize += partitionList->PartitionCount *
2641  sizeof(PARTITION_INFORMATION);
2642 
2643  if (tempSize >
2644  irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
2645 
2647  ExFreePool(partitionList);
2648  break;
2649  }
2650 
2651  //
2652  // Walk partition list to associate partition numbers with
2653  // partition entries.
2654  //
2655 
2656  for (i = 0; i < partitionList->PartitionCount; i++) {
2657 
2658  //
2659  // Walk partition chain anchored at physical disk extension.
2660  //
2661 
2662  deviceExtension = physicalExtension;
2663  diskData = (PDISK_DATA)(deviceExtension + 1);
2664 
2665  do {
2666 
2667  deviceExtension = diskData->NextPartition;
2668 
2669  //
2670  // Check if this is the last partition in the chain.
2671  //
2672 
2673  if (!deviceExtension) {
2674  break;
2675  }
2676 
2677  //
2678  // Get the partition device extension from disk data.
2679  //
2680 
2681  diskData = (PDISK_DATA)(deviceExtension + 1);
2682 
2683  //
2684  // Check if this partition is not currently being used.
2685  //
2686 
2687  if (!deviceExtension->PartitionLength.QuadPart) {
2688  continue;
2689  }
2690 
2691  partitionEntry = &partitionList->PartitionEntry[i];
2692 
2693  //
2694  // Check if empty, or describes extended partition or hasn't changed.
2695  //
2696 
2697  if (partitionEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
2698  IsContainerPartition(partitionEntry->PartitionType)) {
2699  continue;
2700  }
2701 
2702  //
2703  // Check if new partition starts where this partition starts.
2704  //
2705 
2706  if (partitionEntry->StartingOffset.QuadPart !=
2707  deviceExtension->StartingOffset.QuadPart) {
2708  continue;
2709  }
2710 
2711  //
2712  // Check if partition length is the same.
2713  //
2714 
2715  if (partitionEntry->PartitionLength.QuadPart ==
2716  deviceExtension->PartitionLength.QuadPart) {
2717 
2718  //
2719  // Partitions match. Update partition number.
2720  //
2721 
2722  partitionEntry->PartitionNumber =
2723  diskData->PartitionNumber;
2724  break;
2725  }
2726 
2727  } while (TRUE);
2728  }
2729 
2730  //
2731  // Copy partition information to system buffer.
2732  //
2733 
2734  RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
2735  partitionList,
2736  tempSize);
2738  Irp->IoStatus.Information = tempSize;
2739 
2740  //
2741  // Finally, free the buffer allocated by reading the
2742  // partition table.
2743  //
2744 
2745  ExFreePool(partitionList);
2746  }
2747 
2748  break;
2749 
2751 
2752  {
2753 
2754  //
2755  // Update the disk with new partition information.
2756  //
2757 
2758  PDRIVE_LAYOUT_INFORMATION partitionList = Irp->AssociatedIrp.SystemBuffer;
2759 
2760  //
2761  // Validate buffer length.
2762  //
2763 
2764  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2765  sizeof(DRIVE_LAYOUT_INFORMATION)) {
2766 
2768  break;
2769  }
2770 
2771  length = sizeof(DRIVE_LAYOUT_INFORMATION) +
2772  (partitionList->PartitionCount - 1) * sizeof(PARTITION_INFORMATION);
2773 
2774 
2775  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2776  length) {
2777 
2779  break;
2780  }
2781 
2782  //
2783  // Verify that device object is for physical disk.
2784  //
2785 
2786  if (deviceExtension->PhysicalDevice->DeviceExtension != deviceExtension) {
2788  break;
2789  }
2790 
2791  //
2792  // Walk through partition table comparing partitions to
2793  // existing partitions to create, delete and change
2794  // device objects as necessary.
2795  //
2796 
2798  Irp);
2799 
2800  //
2801  // Write changes to disk.
2802  //
2803 
2805  deviceExtension->DeviceObject,
2806  deviceExtension->DiskGeometry->Geometry.BytesPerSector,
2807  deviceExtension->DiskGeometry->Geometry.SectorsPerTrack,
2808  deviceExtension->DiskGeometry->Geometry.TracksPerCylinder,
2809  partitionList);
2810  }
2811 
2812  //
2813  // Update IRP with bytes returned.
2814  //
2815 
2816  if (NT_SUCCESS(status)) {
2817  Irp->IoStatus.Information = length;
2818  }
2819 
2820  break;
2821 
2823 
2824  //
2825  // Map defective blocks to new location on disk.
2826  //
2827 
2828  {
2829 
2830  PREASSIGN_BLOCKS badBlocks = Irp->AssociatedIrp.SystemBuffer;
2831  ULONG bufferSize;
2832  ULONG blockNumber;
2833  ULONG blockCount;
2834 
2835  //
2836  // Validate buffer length.
2837  //
2838 
2839  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2840  sizeof(REASSIGN_BLOCKS)) {
2841 
2843  break;
2844  }
2845 
2846  bufferSize = sizeof(REASSIGN_BLOCKS) +
2847  (badBlocks->Count - 1) * sizeof(ULONG);
2848 
2849  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2850  bufferSize) {
2851 
2853  break;
2854  }
2855 
2856  //
2857  // Build the data buffer to be transferred in the input buffer.
2858  // The format of the data to the device is:
2859  //
2860  // 2 bytes Reserved
2861  // 2 bytes Length
2862  // x * 4 btyes Block Address
2863  //
2864  // All values are big endian.
2865  //
2866 
2867  badBlocks->Reserved = 0;
2868  blockCount = badBlocks->Count;
2869 
2870  //
2871  // Convert # of entries to # of bytes.
2872  //
2873 
2874  blockCount *= 4;
2875  badBlocks->Count = (USHORT) ((blockCount >> 8) & 0XFF);
2876  badBlocks->Count |= (USHORT) ((blockCount << 8) & 0XFF00);
2877 
2878  //
2879  // Convert back to number of entries.
2880  //
2881 
2882  blockCount /= 4;
2883 
2884  for (; blockCount > 0; blockCount--) {
2885 
2886  blockNumber = badBlocks->BlockNumber[blockCount-1];
2887 
2888  REVERSE_BYTES((PFOUR_BYTE) &badBlocks->BlockNumber[blockCount-1],
2889  (PFOUR_BYTE) &blockNumber);
2890  }
2891 
2892  srb->CdbLength = 6;
2893 
2894  cdb->CDB6GENERIC.OperationCode = SCSIOP_REASSIGN_BLOCKS;
2895 
2896  //
2897  // Set timeout value.
2898  //
2899 
2900  srb->TimeOutValue = deviceExtension->TimeOutValue;
2901 
2903  srb,
2904  badBlocks,
2905  bufferSize,
2906  TRUE);
2907 
2908  Irp->IoStatus.Status = status;
2909  Irp->IoStatus.Information = 0;
2910  ExFreePool(srb);
2912  }
2913 
2914  return(status);
2915 
2917 
2918  //
2919  // Determine if the device is writable.
2920  //
2921 
2923 
2924  if (modeData == NULL) {
2926  break;
2927  }
2928 
2929  RtlZeroMemory(modeData, MODE_DATA_SIZE);
2930 
2932  (PCHAR) modeData,
2935 
2936  if (length < sizeof(MODE_PARAMETER_HEADER)) {
2937 
2938  //
2939  // Retry the request in case of a check condition.
2940  //
2941 
2943  (PCHAR) modeData,
2946 
2947  if (length < sizeof(MODE_PARAMETER_HEADER)) {
2949  ExFreePool(modeData);
2950  break;
2951  }
2952  }
2953 
2956  } else {
2958  }
2959 
2960  ExFreePool(modeData);
2961  break;
2962 
2964 
2965  //
2966  // If the caller is kernel mode, set the verify bit.
2967  //
2968 
2969  if (Irp->RequestorMode == KernelMode) {
2971  }
2973  break;
2974 
2976 
2977  //
2978  // If the caller is kernel mode, clear the verify bit.
2979  //
2980 
2981  if (Irp->RequestorMode == KernelMode) {
2983  }
2985  break;
2986 
2988 
2989  //
2990  // Search for devices that have been powered on since the last
2991  // device search or system initialization.
2992  //
2993 
2994  DebugPrint((3,"CdRomDeviceControl: Find devices\n"));
2995  status = DriverEntry(DeviceObject->DriverObject,
2996  NULL);
2997 
2998  Irp->IoStatus.Status = status;
2999  ExFreePool(srb);
3001  return status;
3002 
3004 
3005  //
3006  // If the disk is not removable then don't allow this command.
3007  //
3008 
3009  if (!(DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)) {
3011  break;
3012  }
3013 
3014  //
3015  // Fall through and let the class driver process the request.
3016  //
3017 
3019 
3020  //
3021  // Validate buffer length.
3022  //
3023 
3024  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
3025  sizeof(GET_LENGTH_INFORMATION)) {
3027 
3028  } else {
3029 
3030  PGET_LENGTH_INFORMATION lengthInformation = Irp->AssociatedIrp.SystemBuffer;
3031 
3032  //
3033  // Update the geometry in case it has changed.
3034  //
3035 
3037 
3038  if (!NT_SUCCESS(status)) {
3039 
3040  //
3041  // Note the drive is not ready.
3042  //
3043 
3044  diskData->DriveNotReady = TRUE;
3045  break;
3046  }
3047 
3048  //
3049  // Note the drive is now ready.
3050  //
3051 
3052  diskData->DriveNotReady = FALSE;
3053 
3054  //
3055  // Output data, and return
3056  //
3057 
3058  lengthInformation->Length.QuadPart = deviceExtension->PartitionLength.QuadPart;
3060  Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
3061  }
3062 
3063  break;
3064 
3065  default:
3066 
3067  //
3068  // Free the Srb, since it is not needed.
3069  //
3070 
3071  ExFreePool(srb);
3072 
3073  //
3074  // Pass the request to the common device control routine.
3075  //
3076 
3078 
3079  break;
3080 
3081  } // end switch( ...
3082 
3083  Irp->IoStatus.Status = status;
3084 
3086 
3088  }
3089 
3091  ExFreePool(srb);
3092  return(status);
3093 
3094 } // end ScsiDiskDeviceControl()
signed char * PCHAR
Definition: retypes.h:7
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
struct _FOUR_BYTE * PFOUR_BYTE
NTSTATUS NTAPI CreatePartitionDeviceObjects(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PUNICODE_STRING RegistryPath)
Definition: disk.c:1196
#define SCSIOP_REASSIGN_BLOCKS
Definition: cdrw_hw.h:873
struct _DISK_DATA * PDISK_DATA
#define TRUE
Definition: types.h:120
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:399
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS
Definition: cdrw_hw.h:1459
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
UCHAR Cdb[16]
Definition: srb.h:271
#define IOCTL_DISK_INTERNAL_SET_VERIFY
Definition: ntdddisk.h:109
#define IOCTL_SCSI_MINIPORT
Definition: scsi_port.h:48
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define MODE_DSP_WRITE_PROTECT
Definition: cdrw_hw.h:2523
BOOLEAN BootIndicator
Definition: disk.c:104
#define SMART_GET_VERSION
Definition: ntdddisk.h:194
#define ENABLE_DISABLE_AUTOSAVE
Definition: ntdddisk.h:635
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:2707
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define MODE_SENSE_RETURN_ALL
Definition: cdrw_hw.h:857
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
struct _SENDCMDOUTPARAMS SENDCMDOUTPARAMS
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
UCHAR CdbLength
Definition: srb.h:250
GLuint buffer
Definition: glext.h:5915
#define IDENTIFY_BUFFER_SIZE
Definition: ntdddisk.h:621
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:250
ULONG HiddenSectors
Definition: disk.c:64
ULONG ControlCode
Definition: scsi_port.h:128
#define DISABLE_SMART
Definition: ntdddisk.h:641
struct _CDB::_CDB10 CDB10
struct _PARTITION_INFORMATION PARTITION_INFORMATION
ULONG TimeOutValue
Definition: srb.h:254
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define ENABLE_SMART
Definition: ntdddisk.h:640
PARTITION_INFORMATION_MBR Mbr
Definition: imports.h:226
#define PAGED_CODE()
Definition: video.h:57
LARGE_INTEGER Length
Definition: imports.h:232
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
ULONG PartitionOrdinal
Definition: disk.c:79
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define IOCTL_DISK_FIND_NEW_DEVICES
Definition: cdrw_usr.h:181
PDEVICE_EXTENSION NextPartition
Definition: disk.c:46
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
struct _DISK_GEOMETRY_EX DISK_GEOMETRY_EX
ULONG PartitionNumber
Definition: disk.c:73
PARTITION_STYLE PartitionStyle
Definition: imports.h:220
struct _SENDCMDINPARAMS SENDCMDINPARAMS
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE
Definition: cdrw_hw.h:1464
#define MODE_DATA_SIZE
Definition: disk.c:164
#define IOCTL_DISK_VERIFY
Definition: cdrw_usr.h:170
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
struct _DRIVE_LAYOUT_INFORMATION DRIVE_LAYOUT_INFORMATION
struct _GET_LENGTH_INFORMATION GET_LENGTH_INFORMATION
NTSTATUS ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:714
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
VOID NTAPI UpdateDeviceObjects(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:4978
smooth NULL
Definition: ftsmooth.c:416
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:476
#define IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS
Definition: cdrw_hw.h:1460
struct _REASSIGN_BLOCKS REASSIGN_BLOCKS
UCHAR PartitionType
Definition: disk.c:94
union _CDB * PCDB
#define IoCompleteRequest
Definition: irp.c:1240
UCHAR DeviceSpecificParameter
Definition: cdrw_hw.h:2507
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define READ_THRESHOLD_BUFFER_SIZE
Definition: ntdddisk.h:622
switch(r->id)
Definition: btrfs.c:2904
#define RETURN_SMART_STATUS
Definition: ntdddisk.h:642
#define READ_ATTRIBUTE_BUFFER_SIZE
Definition: ntdddisk.h:620
#define IOCTL_DISK_SET_PARTITION_INFO
Definition: ntdddisk.h:176
#define SMART_RCV_DRIVE_DATA
Definition: ntdddisk.h:197
#define EXECUTE_OFFLINE_DIAGS
Definition: ntdddisk.h:637
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define ID_CMD
Definition: helper.h:20
#define READ_THRESHOLDS
Definition: ntdddisk.h:634
BOOLEAN DriveNotReady
Definition: disk.c:111
#define SAVE_ATTRIBUTE_VALUES
Definition: ntdddisk.h:636
ULONG NTAPI ScsiClassModeSense(IN PDEVICE_OBJECT DeviceObject, IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode)
Definition: class2.c:3198
IDEREGS irDriveRegs
Definition: helper.h:32
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:398
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define IOCTL_DISK_INTERNAL_CLEAR_VERIFY
Definition: ntdddisk.h:106
#define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS
Definition: cdrw_hw.h:1466
#define IOCTL_SCSI_MINIPORT_RETURN_STATUS
Definition: cdrw_hw.h:1463
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:276
UCHAR bCommandReg
Definition: helper.h:15
#define IOCTL_SCSI_MINIPORT_ENABLE_SMART
Definition: cdrw_hw.h:1461
LARGE_INTEGER PartitionLength
Definition: imports.h:222
#define READ_ATTRIBUTES
Definition: ntdddisk.h:633
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SCSIOP_VERIFY
Definition: cdrw_hw.h:912
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES
Definition: cdrw_hw.h:1465
BOOLEAN RewritePartition
Definition: ntdddisk.h:405
LARGE_INTEGER StartingOffset
Definition: imports.h:221
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:88
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: disk.c:342
struct _cl_event * event
Definition: glext.h:7739
NTSTATUS ScsiClassSendSrbSynchronous(IN PDEVICE_OBJECT TargetDeviceObject, IN PSCSI_REQUEST_BLOCK _srb, IN PKEVENT event)
struct _GETVERSIONINPARAMS GETVERSIONINPARAMS
NTSTATUS FASTCALL IoReadPartitionTable(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN BOOLEAN ReturnRecognizedPartitions, OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
Definition: partition.c:495
#define IOCTL_DISK_REASSIGN_BLOCKS
Definition: ntdddisk.h:127
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define SMART_CMD
Definition: helper.h:21
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:76
UCHAR bFeaturesReg
Definition: helper.h:9
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
struct _DISK_GEOMETRY DISK_GEOMETRY
struct _PARTITION_INFORMATION * PPARTITION_INFORMATION
PARTITION_LIST_STATE PartitionListState
Definition: disk.c:117
NTSTATUS NTAPI ScsiClassSendSrbAsynchronous(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PIRP Irp, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class2.c:3369
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
unsigned short USHORT
Definition: pedump.c:61
struct _SRB_IO_CONTROL SRB_IO_CONTROL
struct _CDB::_CDB6GENERIC CDB6GENERIC
#define IOCTL_SCSI_MINIPORT_IDENTIFY
Definition: cdrw_hw.h:1458
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IOCTL_SCSI_MINIPORT_SMART_VERSION
Definition: cdrw_hw.h:1457
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define DPRINT1
Definition: precomp.h:8
#define BOOLEAN
Definition: pedump.c:73
NTSTATUS FASTCALL IoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG PartitionNumber, IN ULONG PartitionType)
Definition: ntoskrnl.c:64
UCHAR Signature[8]
Definition: scsi_port.h:126
USHORT Reserved
Definition: ntdddisk.h:524
UINT sectorCount[1]
Definition: diskio.c:16
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
NTSTATUS NTAPI ScsiClassDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: class2.c:3602
#define IOCTL_DISK_SET_DRIVE_LAYOUT
Definition: ntdddisk.h:170
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
BOOLEAN RecognizedPartition
Definition: ntdddisk.h:404
struct _IDEREGS IDEREGS
NTSTATUS FASTCALL IoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG SectorsPerTrack, IN ULONG NumberOfHeads, IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
Definition: ntoskrnl.c:87
#define IOCTL_DISK_MEDIA_REMOVAL
Definition: cdrw_usr.h:176
#define IOCTL_SCSI_MINIPORT_DISABLE_SMART
Definition: cdrw_hw.h:1462
UCHAR bDriveNumber
Definition: helper.h:33
ULONG HeaderLength
Definition: scsi_port.h:125
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
ULONG BlockNumber[1]
Definition: ntdddisk.h:526
return STATUS_SUCCESS
Definition: btrfs.c:2938
Definition: helper.h:8
static SERVICE_STATUS status
Definition: service.c:31
#define SMART_SEND_DRIVE_COMMAND
Definition: ntdddisk.h:200
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
struct _PARTITION_INFORMATION_EX * PPARTITION_INFORMATION_EX
struct _SET_PARTITION_INFORMATION * PSET_PARTITION_INFORMATION
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
LONGLONG QuadPart
Definition: typedefs.h:112
NTSTATUS NTAPI UpdateRemovableGeometry(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:4549
struct _SENDCMDINPARAMS * PSENDCMDINPARAMS
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:545
Definition: ps.c:97

◆ ScsiDiskDeviceVerification()

BOOLEAN NTAPI ScsiDiskDeviceVerification ( IN PINQUIRYDATA  InquiryData)

Definition at line 408 of file disk.c.

427 {
428 
429  if (((InquiryData->DeviceType == DIRECT_ACCESS_DEVICE) ||
430  (InquiryData->DeviceType == OPTICAL_DEVICE)) &&
431  InquiryData->DeviceTypeQualifier == 0) {
432 
433  return TRUE;
434 
435  } else {
436  return FALSE;
437  }
438 }
#define TRUE
Definition: types.h:120
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
#define OPTICAL_DEVICE
Definition: cdrw_hw.h:1151

Referenced by DriverEntry().

◆ ScsiDiskFileSystemControl()

NTSTATUS NTAPI ScsiDiskFileSystemControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

◆ ScsiDiskModeSelect()

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

Definition at line 3416 of file disk.c.

3444 {
3445  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3446  PCDB cdb;
3447  SCSI_REQUEST_BLOCK srb;
3448  ULONG retries = 1;
3449  ULONG length2;
3450  NTSTATUS status;
3451  ULONG_PTR buffer;
3452  PMODE_PARAMETER_BLOCK blockDescriptor;
3453 
3454  PAGED_CODE();
3455 
3456  length2 = Length + sizeof(MODE_PARAMETER_HEADER) + sizeof(MODE_PARAMETER_BLOCK);
3457 
3458  //
3459  // Allocate buffer for mode select header, block descriptor, and mode page.
3460  //
3461 
3463 
3464  RtlZeroMemory((PVOID)buffer, length2);
3465 
3466  //
3467  // Set length in header to size of mode page.
3468  //
3469 
3470  ((PMODE_PARAMETER_HEADER)buffer)->BlockDescriptorLength = sizeof(MODE_PARAMETER_BLOCK);
3471 
3472  blockDescriptor = (PMODE_PARAMETER_BLOCK)(buffer + 1);
3473 
3474  //
3475  // Set size
3476  //
3477 
3478  blockDescriptor->BlockLength[1]=0x02;
3479 
3480  //
3481  // Copy mode page to buffer.
3482  //
3483 
3484  RtlCopyMemory((PVOID)(buffer + 3), ModeSelectBuffer, Length);
3485 
3486  //
3487  // Zero SRB.
3488  //
3489 
3490  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
3491 
3492  //
3493  // Build the MODE SELECT CDB.
3494  //
3495 
3496  srb.CdbLength = 6;
3497  cdb = (PCDB)srb.Cdb;
3498 
3499  //
3500  // Set timeout value from device extension.
3501  //
3502 
3503  srb.TimeOutValue = deviceExtension->TimeOutValue * 2;
3504 
3505  cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
3506  cdb->MODE_SELECT.SPBit = SavePage;
3507  cdb->MODE_SELECT.PFBit = 1;
3508  cdb->MODE_SELECT.ParameterListLength = (UCHAR)(length2);
3509 
3510 Retry:
3511 
3513  &srb,
3514  (PVOID)buffer,
3515  length2,
3516  TRUE);
3517 
3518 
3519  if (status == STATUS_VERIFY_REQUIRED) {
3520 
3521  //
3522  // Routine ScsiClassSendSrbSynchronous does not retry requests returned with
3523  // this status.
3524  //
3525 
3526  if (retries--) {
3527 
3528  //
3529  // Retry request.
3530  //
3531 
3532  goto Retry;
3533  }
3534 
3535  } else if (SRB_STATUS(srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) {
3537  }
3538 
3540 
3541  if (NT_SUCCESS(status)) {
3542  return(TRUE);
3543  } else {
3544  return(FALSE);
3545  }
3546 
3547 } // end SciDiskModeSelect()
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _MODE_PARAMETER_HEADER MODE_PARAMETER_HEADER
UCHAR Cdb[16]
Definition: srb.h:271
struct _MODE_PARAMETER_BLOCK MODE_PARAMETER_BLOCK
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
GLuint buffer
Definition: glext.h:5915
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
PVOID DeviceExtension
Definition: env_spec_w32.h:418
union _CDB * PCDB
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
struct _CDB::_MODE_SELECT MODE_SELECT
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
UCHAR BlockLength[3]
Definition: cdrw_hw.h:2531
unsigned char UCHAR
Definition: xmlstorage.h:181
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
NTSTATUS ScsiClassSendSrbSynchronous(IN PDEVICE_OBJECT TargetDeviceObject, IN PSCSI_REQUEST_BLOCK _srb, IN PKEVENT event)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
struct _MODE_PARAMETER_BLOCK * PMODE_PARAMETER_BLOCK
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define SCSIOP_MODE_SELECT
Definition: cdrw_hw.h:891
Definition: ps.c:97

Referenced by DisableWriteCache().

◆ ScsiDiskProcessError()

VOID NTAPI ScsiDiskProcessError ( PDEVICE_OBJECT  DeviceObject,
PSCSI_REQUEST_BLOCK  Srb,
NTSTATUS Status,
BOOLEAN Retry 
)

Definition at line 4706 of file disk.c.

4735 {
4736  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4737 
4738  if (*Status == STATUS_DATA_OVERRUN &&
4739  ( Srb->Cdb[0] == SCSIOP_WRITE || Srb->Cdb[0] == SCSIOP_READ)) {
4740 
4741  *Retry = TRUE;
4742 
4743  //
4744  // Update the error count for the device.
4745  //
4746 
4747  deviceExtension->ErrorCount++;
4748  }
4749 
4750  if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_ERROR &&
4751  Srb->ScsiStatus == SCSISTAT_BUSY) {
4752 
4753  //
4754  // The disk drive should never be busy this long. Reset the scsi bus
4755  // maybe this will clear the condition.
4756  //
4757 
4759 
4760  //
4761  // Update the error count for the device.
4762  //
4763 
4764  deviceExtension->ErrorCount++;
4765  }
4766 }
#define SCSISTAT_BUSY
Definition: cdrw_hw.h:1081
#define TRUE
Definition: types.h:120
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define SRB_STATUS(Status)
Definition: srb.h:381
#define SRB_STATUS_ERROR
Definition: srb.h:336
VOID NTAPI ResetScsiBus(IN PDEVICE_OBJECT DeviceObject)
Definition: disk.c:4872
#define SCSIOP_READ
Definition: cdrw_hw.h:905
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49

Referenced by DriverEntry().

◆ ScsiDiskReadWriteVerification()

NTSTATUS NTAPI ScsiDiskReadWriteVerification ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 1638 of file disk.c.

1660 {
1661  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1663  ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
1664  LARGE_INTEGER startingOffset;
1665 
1666  //
1667  // HACK: How can we end here with null sector size?!
1668  //
1669 
1670  if (deviceExtension->DiskGeometry->Geometry.BytesPerSector == 0) {
1671  DPRINT1("Hack! Received invalid sector size\n");
1672  deviceExtension->DiskGeometry->Geometry.BytesPerSector = 512;
1673  }
1674 
1675  //
1676  // Verify parameters of this request.
1677  // Check that ending sector is within partition and
1678  // that number of bytes to transfer is a multiple of
1679  // the sector size.
1680  //
1681 
1682  startingOffset.QuadPart = (currentIrpStack->Parameters.Read.ByteOffset.QuadPart +
1683  transferByteCount);
1684 
1685  if ((startingOffset.QuadPart > deviceExtension->PartitionLength.QuadPart) ||
1686  (transferByteCount & (deviceExtension->DiskGeometry->Geometry.BytesPerSector - 1))) {
1687 
1688  //
1689  // This error maybe caused by the fact that the drive is not ready.
1690  //
1691 
1692  if (((PDISK_DATA)(deviceExtension + 1))->DriveNotReady) {
1693 
1694  //
1695  // Flag this as a user error so that a popup is generated.
1696  //
1697 
1698  Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
1700 
1701  } else {
1702 
1703  //
1704  // Note fastfat depends on this parameter to determine when to
1705  // remount do to a sector size change.
1706  //
1707 
1708  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1709  }
1710 
1711  if (startingOffset.QuadPart > deviceExtension->PartitionLength.QuadPart) {
1712  DPRINT1("Reading beyond partition end! startingOffset: %I64d, PartitionLength: %I64d\n", startingOffset.QuadPart, deviceExtension->PartitionLength.QuadPart);
1713  }
1714 
1715  if (transferByteCount & (deviceExtension->DiskGeometry->Geometry.BytesPerSector - 1)) {
1716  DPRINT1("Not reading sectors! TransferByteCount: %lu, BytesPerSector: %lu\n", transferByteCount, deviceExtension->DiskGeometry->Geometry.BytesPerSector);
1717  }
1718 
1719  if (Irp->IoStatus.Status == STATUS_DEVICE_NOT_READY) {
1720  DPRINT1("Failing due to device not ready!\n");
1721  }
1722 
1723  return STATUS_INVALID_PARAMETER;
1724  }
1725 
1726  return STATUS_SUCCESS;
1727 
1728 } // end ScsiDiskReadWrite()
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PVOID DeviceExtension
Definition: env_spec_w32.h:418
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
LONGLONG QuadPart
Definition: typedefs.h:112
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70

Referenced by DriverEntry().

◆ ScsiDiskShutdownFlush()

NTSTATUS NTAPI ScsiDiskShutdownFlush ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 3098 of file disk.c.

3125 {
3126  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3127  PIO_STACK_LOCATION irpStack;
3128  PSCSI_REQUEST_BLOCK srb;
3129  NTSTATUS status;
3130  PCDB cdb;
3131 
3132  //
3133  // Allocate SCSI request block.
3134  //
3135 
3137 
3138  if (srb == NULL) {
3139 
3140  //
3141  // Set the status and complete the request.
3142  //
3143 
3144  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
3147  }
3148 
3150 
3151  //
3152  // Write length to SRB.
3153  //
3154 
3156 
3157  //
3158  // Set SCSI bus address.
3159  //
3160 
3161  srb->PathId = deviceExtension->PathId;
3162  srb->TargetId = deviceExtension->TargetId;
3163  srb->Lun = deviceExtension->Lun;
3164 
3165  //
3166  // Set timeout value and mark the request as not being a tagged request.
3167  //
3168 
3169  srb->TimeOutValue = deviceExtension->TimeOutValue * 4;
3170  srb->QueueTag = SP_UNTAGGED;
3172  srb->SrbFlags = deviceExtension->SrbFlags;
3173 
3174  //
3175  // If the write cache is enabled then send a synchronize cache request.
3176  //
3177 
3178  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
3179 
3181  srb->CdbLength = 10;
3182 
3183  srb->Cdb[0] = SCSIOP_SYNCHRONIZE_CACHE;
3184 
3186  srb,
3187  NULL,
3188  0,
3189  TRUE);
3190 
3191  DebugPrint((1, "ScsiDiskShutdownFlush: Synchronize cache sent. Status = %lx\n", status ));
3192  }
3193 
3194  //
3195  // Unlock the device if it is removable and this is a shutdown.
3196  //
3197 
3198  irpStack = IoGetCurrentIrpStackLocation(Irp);
3199 
3200  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
3201  irpStack->MajorFunction == IRP_MJ_SHUTDOWN) {
3202 
3203  srb->CdbLength = 6;
3204  cdb = (PVOID) srb->Cdb;
3205  cdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
3206  cdb->MEDIA_REMOVAL.Prevent = FALSE;
3207 
3208  //
3209  // Set timeout value.
3210  //
3211 
3212  srb->TimeOutValue = deviceExtension->TimeOutValue;
3214  srb,
3215  NULL,
3216  0,
3217  TRUE);
3218 
3219  DebugPrint((1, "ScsiDiskShutdownFlush: Unlock device request sent. Status = %lx\n", status ));
3220  }
3221 
3222  srb->CdbLength = 0;
3223 
3224  //
3225  // Save a few parameters in the current stack location.
3226  //
3227 
3228  srb->Function = irpStack->MajorFunction == IRP_MJ_SHUTDOWN ?
3230 
3231  //
3232  // Set the retry count to zero.
3233  //
3234 
3235  irpStack->Parameters.Others.Argument4 = (PVOID) 0;
3236 
3237  //
3238  // Set up IoCompletion routine address.
3239  //
3240